aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorV1K1NGbg <victor@ilchev.com>2024-08-02 20:24:01 +0300
committerV1K1NGbg <victor@ilchev.com>2024-08-05 20:51:31 +0300
commite82c2fd083813c18a893bb19cbc013b6df44cafb (patch)
treed584dfd06a4a57d15fedc8973c63d0858c5c6db8
parent5b189eea169bd69faa6705f6df68b8b132d2b0dc (diff)
downloadluarocks-e82c2fd083813c18a893bb19cbc013b6df44cafb.tar.gz
luarocks-e82c2fd083813c18a893bb19cbc013b6df44cafb.tar.bz2
luarocks-e82c2fd083813c18a893bb19cbc013b6df44cafb.zip
move .d.tl to types folder
-rw-r--r--src/luarocks/tools/patch.tl718
-rw-r--r--tlconfig.lua2
-rw-r--r--types/ltn12.d.tl (renamed from src/ltn12.d.tl)0
-rw-r--r--types/mimetypes.d.tl (renamed from src/mimetypes.d.tl)0
-rw-r--r--types/socket.d.tl (renamed from src/socket.d.tl)0
-rw-r--r--types/socket/http.d.tl (renamed from src/socket/http.d.tl)0
-rw-r--r--types/ssl.d.tl (renamed from src/ssl.d.tl)0
-rw-r--r--types/ssl/https.d.tl (renamed from src/ssl/https.d.tl)0
8 files changed, 719 insertions, 1 deletions
diff --git a/src/luarocks/tools/patch.tl b/src/luarocks/tools/patch.tl
new file mode 100644
index 00000000..a3dbe0df
--- /dev/null
+++ b/src/luarocks/tools/patch.tl
@@ -0,0 +1,718 @@
1--- Patch utility to apply unified diffs.
2--
3-- http://lua-users.org/wiki/LuaPatch
4--
5-- (c) 2008 David Manura, Licensed under the same terms as Lua (MIT license).
6-- Code is heavily based on the Python-based patch.py version 8.06-1
7-- Copyright (c) 2008 rainforce.org, MIT License
8-- Project home: http://code.google.com/p/python-patch/ .
9-- Version 0.1
10
11local record patch
12
13end
14
15local fs = require("luarocks.fs")
16local fun = require("luarocks.fun")
17
18local io = io
19local os = os
20local string = string
21local table = table
22local format = string.format
23
24-- logging
25local debugmode = false
26local function debug(_) end --!
27local function info(_) end
28local function warning(s: string) io.stderr:write(s .. '\n') end
29
30-- Returns boolean whether string s2 starts with string s.
31local function startswith(s: string, s2: string): boolean
32 return s:sub(1, #s2) == s2
33end
34
35-- Returns boolean whether string s2 ends with string s.
36local function endswith(s: string, s2: string): boolean
37 return #s >= #s2 and s:sub(#s-#s2+1) == s2
38end
39
40-- Returns string s after filtering out any new-line characters from end.
41local function endlstrip(s: string): string
42 return s:gsub('[\r\n]+$', '')
43end
44
45-- Returns shallow copy of table t.
46local function table_copy<K, V>(t: {K: V}): {K: V}
47 local t2 = {}
48 for k,v in pairs(t) do t2[k] = v end
49 return t2
50end
51
52local function exists(filename: string): boolean
53 local fh = io.open(filename)
54 local result = fh ~= nil
55 if fh then fh:close() end
56 return result
57end
58local function isfile(): boolean return true end --FIX? --!
59
60local function string_as_file(s: string) --!
61 return {
62 at = 0,
63 str = s,
64 len = #s,
65 eof = false,
66 read = function(self, n)
67 if self.eof then return nil end
68 local chunk = self.str:sub(self.at, self.at + n - 1)
69 self.at = self.at + n
70 if self.at > self.len then
71 self.eof = true
72 end
73 return chunk
74 end,
75 close = function(self)
76 self.eof = true
77 end,
78 }
79end
80
81--
82-- file_lines(f) is similar to f:lines() for file f.
83-- The main difference is that read_lines includes
84-- new-line character sequences ("\n", "\r\n", "\r"),
85-- if any, at the end of each line. Embedded "\0" are also handled.
86-- Caution: The newline behavior can depend on whether f is opened
87-- in binary or ASCII mode.
88-- (file_lines - version 20080913)
89--
90local function file_lines(f: FILE): function(): string
91 local CHUNK_SIZE = 1024
92 local buffer = ""
93 local pos_beg = 1
94 return function(): string
95 local pos, chars: number, number --? char represented as a number
96 while 1 do
97 pos, chars = buffer:match('()([\r\n].)', pos_beg)
98 if pos or not f then
99 break
100 elseif f then
101 local chunk = f:read(CHUNK_SIZE)
102 if chunk then
103 buffer = buffer:sub(pos_beg) .. chunk
104 pos_beg = 1
105 else
106 f = nil
107 end
108 end
109 end
110 if not pos then
111 pos = #buffer
112 elseif chars == '\r\n' then
113 pos = pos + 1
114 end
115 local line = buffer:sub(pos_beg, pos)
116 pos_beg = pos + 1
117 if #line > 0 then
118 return line
119 end
120 end
121end
122
123local function match_linerange(line: string)
124 local m1, m2, m3, m4 = line:match("^@@ %-(%d+),(%d+) %+(%d+),(%d+)")
125 if not m1 then m1, m3, m4 = line:match("^@@ %-(%d+) %+(%d+),(%d+)") end
126 if not m1 then m1, m2, m3 = line:match("^@@ %-(%d+),(%d+) %+(%d+)") end
127 if not m1 then m1, m3 = line:match("^@@ %-(%d+) %+(%d+)") end
128 return m1, m2, m3, m4
129end
130
131local function match_epoch(str)
132 return str:match("[^0-9]1969[^0-9]") or str:match("[^0-9]1970[^0-9]")
133end
134
135function patch.read_patch(filename, data)
136 -- define possible file regions that will direct the parser flow
137 local state = 'header'
138 -- 'header' - comments before the patch body
139 -- 'filenames' - lines starting with --- and +++
140 -- 'hunkhead' - @@ -R +R @@ sequence
141 -- 'hunkbody'
142 -- 'hunkskip' - skipping invalid hunk mode
143
144 local all_ok = true
145 local lineends = {lf=0, crlf=0, cr=0}
146 local files = {source={}, target={}, epoch={}, hunks={}, fileends={}, hunkends={}}
147 local nextfileno = 0
148 local nexthunkno = 0 --: even if index starts with 0 user messages
149 -- number hunks from 1
150
151 -- hunkinfo holds parsed values, hunkactual - calculated
152 local hunkinfo = {
153 startsrc=nil, linessrc=nil, starttgt=nil, linestgt=nil,
154 invalid=false, text={}
155 }
156 local hunkactual = {linessrc=nil, linestgt=nil}
157
158 info(format("reading patch %s", filename))
159
160 local fp
161 if data then
162 fp = string_as_file(data)
163 else
164 fp = filename == '-' and io.stdin or assert(io.open(filename, "rb"))
165 end
166 local lineno = 0
167
168 for line in file_lines(fp) do
169 lineno = lineno + 1
170 if state == 'header' then
171 if startswith(line, "--- ") then
172 state = 'filenames'
173 end
174 -- state is 'header' or 'filenames'
175 end
176 if state == 'hunkbody' then
177 -- skip hunkskip and hunkbody code until definition of hunkhead read
178
179 if line:match"^[\r\n]*$" then
180 -- prepend space to empty lines to interpret them as context properly
181 line = " " .. line
182 end
183
184 -- process line first
185 if line:match"^[- +\\]" then
186 -- gather stats about line endings
187 local he = files.hunkends[nextfileno]
188 if endswith(line, "\r\n") then
189 he.crlf = he.crlf + 1
190 elseif endswith(line, "\n") then
191 he.lf = he.lf + 1
192 elseif endswith(line, "\r") then
193 he.cr = he.cr + 1
194 end
195 if startswith(line, "-") then
196 hunkactual.linessrc = hunkactual.linessrc + 1
197 elseif startswith(line, "+") then
198 hunkactual.linestgt = hunkactual.linestgt + 1
199 elseif startswith(line, "\\") then
200 -- nothing
201 else
202 hunkactual.linessrc = hunkactual.linessrc + 1
203 hunkactual.linestgt = hunkactual.linestgt + 1
204 end
205 table.insert(hunkinfo.text, line)
206 -- todo: handle \ No newline cases
207 else
208 warning(format("invalid hunk no.%d at %d for target file %s",
209 nexthunkno, lineno, files.target[nextfileno]))
210 -- add hunk status node
211 table.insert(files.hunks[nextfileno], table_copy(hunkinfo))
212 files.hunks[nextfileno][nexthunkno].invalid = true
213 all_ok = false
214 state = 'hunkskip'
215 end
216
217 -- check exit conditions
218 if hunkactual.linessrc > hunkinfo.linessrc or
219 hunkactual.linestgt > hunkinfo.linestgt
220 then
221 warning(format("extra hunk no.%d lines at %d for target %s",
222 nexthunkno, lineno, files.target[nextfileno]))
223 -- add hunk status node
224 table.insert(files.hunks[nextfileno], table_copy(hunkinfo))
225 files.hunks[nextfileno][nexthunkno].invalid = true
226 state = 'hunkskip'
227 elseif hunkinfo.linessrc == hunkactual.linessrc and
228 hunkinfo.linestgt == hunkactual.linestgt
229 then
230 table.insert(files.hunks[nextfileno], table_copy(hunkinfo))
231 state = 'hunkskip'
232
233 -- detect mixed window/unix line ends
234 local ends = files.hunkends[nextfileno]
235 if (ends.cr~=0 and 1 or 0) + (ends.crlf~=0 and 1 or 0) +
236 (ends.lf~=0 and 1 or 0) > 1
237 then
238 warning(format("inconsistent line ends in patch hunks for %s",
239 files.source[nextfileno]))
240 end
241 end
242 -- state is 'hunkbody' or 'hunkskip'
243 end
244
245 if state == 'hunkskip' then
246 if match_linerange(line) then
247 state = 'hunkhead'
248 elseif startswith(line, "--- ") then
249 state = 'filenames'
250 if debugmode and #files.source > 0 then
251 debug(format("- %2d hunks for %s", #files.hunks[nextfileno],
252 files.source[nextfileno]))
253 end
254 end
255 -- state is 'hunkskip', 'hunkhead', or 'filenames'
256 end
257 local advance
258 if state == 'filenames' then
259 if startswith(line, "--- ") then
260 if fun.contains(files.source, nextfileno) then
261 all_ok = false
262 warning(format("skipping invalid patch for %s",
263 files.source[nextfileno+1]))
264 table.remove(files.source, nextfileno+1)
265 -- double source filename line is encountered
266 -- attempt to restart from this second line
267 end
268 -- Accept a space as a terminator, like GNU patch does.
269 -- Breaks patches containing filenames with spaces...
270 -- FIXME Figure out what does GNU patch do in those cases.
271 local match, rest = line:match("^%-%-%- ([^ \t\r\n]+)(.*)")
272 if not match then
273 all_ok = false
274 warning(format("skipping invalid filename at line %d", lineno+1))
275 state = 'header'
276 else
277 if match_epoch(rest) then
278 files.epoch[nextfileno + 1] = true
279 end
280 table.insert(files.source, match)
281 end
282 elseif not startswith(line, "+++ ") then
283 if fun.contains(files.source, nextfileno) then
284 all_ok = false
285 warning(format("skipping invalid patch with no target for %s",
286 files.source[nextfileno+1]))
287 table.remove(files.source, nextfileno+1)
288 else
289 -- this should be unreachable
290 warning("skipping invalid target patch")
291 end
292 state = 'header'
293 else
294 if fun.contains(files.target, nextfileno) then
295 all_ok = false
296 warning(format("skipping invalid patch - double target at line %d",
297 lineno+1))
298 table.remove(files.source, nextfileno+1)
299 table.remove(files.target, nextfileno+1)
300 nextfileno = nextfileno - 1
301 -- double target filename line is encountered
302 -- switch back to header state
303 state = 'header'
304 else
305 -- Accept a space as a terminator, like GNU patch does.
306 -- Breaks patches containing filenames with spaces...
307 -- FIXME Figure out what does GNU patch do in those cases.
308 local re_filename = "^%+%+%+ ([^ \t\r\n]+)(.*)$"
309 local match, rest = line:match(re_filename)
310 if not match then
311 all_ok = false
312 warning(format(
313 "skipping invalid patch - no target filename at line %d",
314 lineno+1))
315 state = 'header'
316 else
317 table.insert(files.target, match)
318 nextfileno = nextfileno + 1
319 if match_epoch(rest) then
320 files.epoch[nextfileno] = true
321 end
322 nexthunkno = 0
323 table.insert(files.hunks, {})
324 table.insert(files.hunkends, table_copy(lineends))
325 table.insert(files.fileends, table_copy(lineends))
326 state = 'hunkhead'
327 advance = true
328 end
329 end
330 end
331 -- state is 'filenames', 'header', or ('hunkhead' with advance)
332 end
333 if not advance and state == 'hunkhead' then
334 local m1, m2, m3, m4 = match_linerange(line)
335 if not m1 then
336 if not fun.contains(files.hunks, nextfileno-1) then
337 all_ok = false
338 warning(format("skipping invalid patch with no hunks for file %s",
339 files.target[nextfileno]))
340 end
341 state = 'header'
342 else
343 hunkinfo.startsrc = tonumber(m1)
344 hunkinfo.linessrc = tonumber(m2 or 1)
345 hunkinfo.starttgt = tonumber(m3)
346 hunkinfo.linestgt = tonumber(m4 or 1)
347 hunkinfo.invalid = false
348 hunkinfo.text = {}
349
350 hunkactual.linessrc = 0
351 hunkactual.linestgt = 0
352
353 state = 'hunkbody'
354 nexthunkno = nexthunkno + 1
355 end
356 -- state is 'header' or 'hunkbody'
357 end
358 end
359 if state ~= 'hunkskip' then
360 warning(format("patch file incomplete - %s", filename))
361 all_ok = false
362 -- os.exit(?)
363 else
364 -- duplicated message when an eof is reached
365 if debugmode and #files.source > 0 then
366 debug(format("- %2d hunks for %s", #files.hunks[nextfileno],
367 files.source[nextfileno]))
368 end
369 end
370
371 local sum = 0; for _,hset in ipairs(files.hunks) do sum = sum + #hset end
372 info(format("total files: %d total hunks: %d", #files.source, sum))
373 fp:close()
374 return files, all_ok
375end
376
377local function find_hunk(file, h, hno)
378 for fuzz=0,2 do
379 local lineno = h.startsrc
380 for i=0,#file do
381 local found = true
382 local location = lineno
383 for l, hline in ipairs(h.text) do
384 if l > fuzz then
385 -- todo: \ No newline at the end of file
386 if startswith(hline, " ") or startswith(hline, "-") then
387 local line = file[lineno]
388 lineno = lineno + 1
389 if not line or #line == 0 then
390 found = false
391 break
392 end
393 if endlstrip(line) ~= endlstrip(hline:sub(2)) then
394 found = false
395 break
396 end
397 end
398 end
399 end
400 if found then
401 local offset = location - h.startsrc - fuzz
402 if offset ~= 0 then
403 warning(format("Hunk %d found at offset %d%s...", hno, offset, fuzz == 0 and "" or format(" (fuzz %d)", fuzz)))
404 end
405 h.startsrc = location
406 h.starttgt = h.starttgt + offset
407 for _=1,fuzz do
408 table.remove(h.text, 1)
409 table.remove(h.text, #h.text)
410 end
411 return true
412 end
413 lineno = i
414 end
415 end
416 return false
417end
418
419local function load_file(filename)
420 local fp = assert(io.open(filename))
421 local file = {}
422 local readline = file_lines(fp)
423 while true do
424 local line = readline()
425 if not line then break end
426 table.insert(file, line)
427 end
428 fp:close()
429 return file
430end
431
432local function find_hunks(file, hunks)
433 for hno, h in ipairs(hunks) do
434 find_hunk(file, h, hno)
435 end
436end
437
438local function check_patched(file, hunks)
439 local lineno = 1
440 local ok, err = pcall(function()
441 if #file == 0 then
442 error('nomatch', 0)
443 end
444 for hno, h in ipairs(hunks) do
445 -- skip to line just before hunk starts
446 if #file < h.starttgt then
447 error('nomatch', 0)
448 end
449 lineno = h.starttgt
450 for _, hline in ipairs(h.text) do
451 -- todo: \ No newline at the end of file
452 if not startswith(hline, "-") and not startswith(hline, "\\") then
453 local line = file[lineno]
454 lineno = lineno + 1
455 if #line == 0 then
456 error('nomatch', 0)
457 end
458 if endlstrip(line) ~= endlstrip(hline:sub(2)) then
459 warning(format("file is not patched - failed hunk: %d", hno))
460 error('nomatch', 0)
461 end
462 end
463 end
464 end
465 end)
466 -- todo: display failed hunk, i.e. expected/found
467 return err ~= 'nomatch'
468end
469
470local function patch_hunks(srcname, tgtname, hunks)
471 local src = assert(io.open(srcname, "rb"))
472 local tgt = assert(io.open(tgtname, "wb"))
473
474 local src_readline = file_lines(src)
475
476 -- todo: detect linefeeds early - in apply_files routine
477 -- to handle cases when patch starts right from the first
478 -- line and no lines are processed. At the moment substituted
479 -- lineends may not be the same at the start and at the end
480 -- of patching. Also issue a warning about mixed lineends
481
482 local srclineno = 1
483 local lineends = {['\n']=0, ['\r\n']=0, ['\r']=0}
484 for hno, h in ipairs(hunks) do
485 debug(format("processing hunk %d for file %s", hno, tgtname))
486 -- skip to line just before hunk starts
487 while srclineno < h.startsrc do
488 local line = src_readline()
489 -- Python 'U' mode works only with text files
490 if endswith(line, "\r\n") then
491 lineends["\r\n"] = lineends["\r\n"] + 1
492 elseif endswith(line, "\n") then
493 lineends["\n"] = lineends["\n"] + 1
494 elseif endswith(line, "\r") then
495 lineends["\r"] = lineends["\r"] + 1
496 end
497 tgt:write(line)
498 srclineno = srclineno + 1
499 end
500
501 for _,hline in ipairs(h.text) do
502 -- todo: check \ No newline at the end of file
503 if startswith(hline, "-") or startswith(hline, "\\") then
504 src_readline()
505 srclineno = srclineno + 1
506 else
507 if not startswith(hline, "+") then
508 src_readline()
509 srclineno = srclineno + 1
510 end
511 local line2write = hline:sub(2)
512 -- detect if line ends are consistent in source file
513 local sum = 0
514 for _,v in pairs(lineends) do if v > 0 then sum=sum+1 end end
515 if sum == 1 then
516 local newline
517 for k,v in pairs(lineends) do if v ~= 0 then newline = k end end
518 tgt:write(endlstrip(line2write) .. newline)
519 else -- newlines are mixed or unknown
520 tgt:write(line2write)
521 end
522 end
523 end
524 end
525 for line in src_readline do
526 tgt:write(line)
527 end
528 tgt:close()
529 src:close()
530 return true
531end
532
533local function strip_dirs(filename, strip)
534 if strip == nil then return filename end
535 for _=1,strip do
536 filename=filename:gsub("^[^/]*/", "")
537 end
538 return filename
539end
540
541local function write_new_file(filename, hunk)
542 local fh = io.open(filename, "wb")
543 if not fh then return false end
544 for _, hline in ipairs(hunk.text) do
545 local c = hline:sub(1,1)
546 if c ~= "+" and c ~= "-" and c ~= " " then
547 return false, "malformed patch"
548 end
549 fh:write(hline:sub(2))
550 end
551 fh:close()
552 return true
553end
554
555local function patch_file(source, target, epoch, hunks, strip, create_delete)
556 local create_file = false
557 if create_delete then
558 local is_src_epoch = epoch and #hunks == 1 and hunks[1].startsrc == 0 and hunks[1].linessrc == 0
559 if is_src_epoch or source == "/dev/null" then
560 info(format("will create %s", target))
561 create_file = true
562 end
563 end
564 if create_file then
565 return write_new_file(fs.absolute_name(strip_dirs(target, strip)), hunks[1])
566 end
567 source = strip_dirs(source, strip)
568 local f2patch = source
569 if not exists(f2patch) then
570 f2patch = strip_dirs(target, strip)
571 f2patch = fs.absolute_name(f2patch)
572 if not exists(f2patch) then --FIX:if f2patch nil
573 warning(format("source/target file does not exist\n--- %s\n+++ %s",
574 source, f2patch))
575 return false
576 end
577 end
578 if not isfile(f2patch) then
579 warning(format("not a file - %s", f2patch))
580 return false
581 end
582
583 source = f2patch
584
585 -- validate before patching
586 local file = load_file(source)
587 local hunkno = 1
588 local hunk = hunks[hunkno]
589 local hunkfind = {}
590 local validhunks = 0
591 local canpatch = false
592 local hunklineno
593 if not file then
594 return nil, "failed reading file " .. source
595 end
596
597 if create_delete then
598 if epoch and #hunks == 1 and hunks[1].starttgt == 0 and hunks[1].linestgt == 0 then
599 local ok = os.remove(source)
600 if not ok then
601 return false
602 end
603 info(format("successfully removed %s", source))
604 return true
605 end
606 end
607
608 find_hunks(file, hunks)
609
610 local function process_line(line, lineno)
611 if not hunk or lineno < hunk.startsrc then
612 return false
613 end
614 if lineno == hunk.startsrc then
615 hunkfind = {}
616 for _,x in ipairs(hunk.text) do
617 if x:sub(1,1) == ' ' or x:sub(1,1) == '-' then
618 hunkfind[#hunkfind+1] = endlstrip(x:sub(2))
619 end
620 end
621 hunklineno = 1
622
623 -- todo \ No newline at end of file
624 end
625 -- check hunks in source file
626 if lineno < hunk.startsrc + #hunkfind - 1 then
627 if endlstrip(line) == hunkfind[hunklineno] then
628 hunklineno = hunklineno + 1
629 else
630 debug(format("hunk no.%d doesn't match source file %s",
631 hunkno, source))
632 -- file may be already patched, but check other hunks anyway
633 hunkno = hunkno + 1
634 if hunkno <= #hunks then
635 hunk = hunks[hunkno]
636 return false
637 else
638 return true
639 end
640 end
641 end
642 -- check if processed line is the last line
643 if lineno == hunk.startsrc + #hunkfind - 1 then
644 debug(format("file %s hunk no.%d -- is ready to be patched",
645 source, hunkno))
646 hunkno = hunkno + 1
647 validhunks = validhunks + 1
648 if hunkno <= #hunks then
649 hunk = hunks[hunkno]
650 else
651 if validhunks == #hunks then
652 -- patch file
653 canpatch = true
654 return true
655 end
656 end
657 end
658 return false
659 end
660
661 local done = false
662 for lineno, line in ipairs(file) do
663 done = process_line(line, lineno)
664 if done then
665 break
666 end
667 end
668 if not done then
669 if hunkno <= #hunks and not create_file then
670 warning(format("premature end of source file %s at hunk %d",
671 source, hunkno))
672 return false
673 end
674 end
675 if validhunks < #hunks then
676 if check_patched(file, hunks) then
677 warning(format("already patched %s", source))
678 elseif not create_file then
679 warning(format("source file is different - %s", source))
680 return false
681 end
682 end
683 if not canpatch then
684 return true
685 end
686 local backupname = source .. ".orig"
687 if exists(backupname) then
688 warning(format("can't backup original file to %s - aborting",
689 backupname))
690 return false
691 end
692 local ok = os.rename(source, backupname)
693 if not ok then
694 warning(format("failed backing up %s when patching", source))
695 return false
696 end
697 patch_hunks(backupname, source, hunks)
698 info(format("successfully patched %s", source))
699 os.remove(backupname)
700 return true
701end
702
703function patch.apply_patch(the_patch, strip, create_delete)
704 local all_ok = true
705 local total = #the_patch.source
706 for fileno, source in ipairs(the_patch.source) do
707 local target = the_patch.target[fileno]
708 local hunks = the_patch.hunks[fileno]
709 local epoch = the_patch.epoch[fileno]
710 info(format("processing %d/%d:\t %s", fileno, total, source))
711 local ok = patch_file(source, target, epoch, hunks, strip, create_delete)
712 all_ok = all_ok and ok
713 end
714 -- todo: check for premature eof
715 return all_ok
716end
717
718return patch
diff --git a/tlconfig.lua b/tlconfig.lua
index a6667cb1..aefcbef6 100644
--- a/tlconfig.lua
+++ b/tlconfig.lua
@@ -1,5 +1,5 @@
1return { 1return {
2 build_dir = "build", 2 build_dir = "build",
3 source_dir = "src", 3 source_dir = "src",
4 include_dir = { "src" }, 4 include_dir = { "src", "types" },
5 } \ No newline at end of file 5 } \ No newline at end of file
diff --git a/src/ltn12.d.tl b/types/ltn12.d.tl
index cd2375fc..cd2375fc 100644
--- a/src/ltn12.d.tl
+++ b/types/ltn12.d.tl
diff --git a/src/mimetypes.d.tl b/types/mimetypes.d.tl
index a735225d..a735225d 100644
--- a/src/mimetypes.d.tl
+++ b/types/mimetypes.d.tl
diff --git a/src/socket.d.tl b/types/socket.d.tl
index e62e907b..e62e907b 100644
--- a/src/socket.d.tl
+++ b/types/socket.d.tl
diff --git a/src/socket/http.d.tl b/types/socket/http.d.tl
index 2a64872e..2a64872e 100644
--- a/src/socket/http.d.tl
+++ b/types/socket/http.d.tl
diff --git a/src/ssl.d.tl b/types/ssl.d.tl
index 1bd40348..1bd40348 100644
--- a/src/ssl.d.tl
+++ b/types/ssl.d.tl
diff --git a/src/ssl/https.d.tl b/types/ssl/https.d.tl
index 94c38df6..94c38df6 100644
--- a/src/ssl/https.d.tl
+++ b/types/ssl/https.d.tl