cortav  Check-in [ee086767f3]

Overview
Comment:add remote fetch via curl, shim native bindings
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: ee086767f3c7d8e499c9a4a91ffe77f6bd1805ab58a5d73c4ee8d44f4f337167
User & Date: lexi on 2022-09-10 17:28:05
Other Links: manifest | tags
Context
2022-09-10
19:14
tweak docs check-in: 5a78370f0f user: lexi tags: trunk
17:28
add remote fetch via curl, shim native bindings check-in: ee086767f3 user: lexi tags: trunk
13:31
better footnotes, update syntax def, delete broken old span check-in: a8358d587d user: lexi tags: trunk
Changes

Modified cli.lua from [2aa6072a5d] to [6b3b695c7e].

1
2
3
4
5
6
7


8
9
10
11
12
13
14
...
223
224
225
226
227
228
229





230
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245
246
-- [สž] cli.lua
--  ~ lexi hale <lexi@hale.su>
--  ๐Ÿ„ฏ AGPLv3
--  ? simple command line driver for the cortav library
local ct = require 'cortav'
local ss = require 'sirsem'



local default_mode = {
	['render:format'] = 'html';
	['html:gen-styles'] = true;
	['groff:color'] = true;
}

local function
................................................................................
local ok, e = true, entry_cli()
if not ok then
	local str = 'translation failure'
	if ss.exn.is(e) then
		str = e.kind.desc
	end
	local color = false





	if log:seek() == nil then
		-- this is not a very reliable heuristic for detecting
		-- attachment to a tty but it's better than nothing
		if os.getenv('COLORTERM') then
			color = true
		else
			local term = os.getenv('TERM')
			if term:find 'color' then color = true end

		end
	end
	if color then
		str = string.format('\27[1;31m%s\27[m', str)
	end
	log:write(string.format('%s: %s\n', str, e))
	os.exit(1)
end
os.exit(e)







>
>







 







>
>
>
>
>
|
|
|
|
|
|
|
|
>









1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
...
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
-- [สž] cli.lua
--  ~ lexi hale <lexi@hale.su>
--  ๐Ÿ„ฏ AGPLv3
--  ? simple command line driver for the cortav library
local ct = require 'cortav'
local ss = require 'sirsem'

local native = _G.native

local default_mode = {
	['render:format'] = 'html';
	['html:gen-styles'] = true;
	['groff:color'] = true;
}

local function
................................................................................
local ok, e = true, entry_cli()
if not ok then
	local str = 'translation failure'
	if ss.exn.is(e) then
		str = e.kind.desc
	end
	local color = false
	if native then
		if native.posix.isatty(log) then
			color = true
		end
	else
		if log:seek() == nil then
			-- this is not a very reliable heuristic for detecting
			-- attachment to a tty but it's better than nothing
			if os.getenv('COLORTERM') then
				color = true
			else
				local term = os.getenv('TERM')
				if term:find 'color' then color = true end
			end
		end
	end
	if color then
		str = string.format('\27[1;31m%s\27[m', str)
	end
	log:write(string.format('%s: %s\n', str, e))
	os.exit(1)
end
os.exit(e)

Modified cortav.lua from [648cf1722d] to [940c3efd41].

794
795
796
797
798
799
800
801






802
803
804
805
806
807
808
			}
		end};
		{seq = '>', parse = insert_link};
		{seq = 'โ†’', parse = insert_link};
		{seq = '๐Ÿ”—', parse = insert_link};
		{seq = '##', parse = insert_var_ref(true)};
		{seq = '#', parse = insert_var_ref(false)};
		{seq = '%%', parse = function() --[[NOP]] end};






		{seq = '%!', parse = insert_span_directive(true,false)};
		{seq = '%:', parse = insert_span_directive(false,true)};
		{seq = '%', parse = insert_span_directive(false,false)};
	}
end

function ct.parse_span(str,ctx)







|
>
>
>
>
>
>







794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
			}
		end};
		{seq = '>', parse = insert_link};
		{seq = 'โ†’', parse = insert_link};
		{seq = '๐Ÿ”—', parse = insert_link};
		{seq = '##', parse = insert_var_ref(true)};
		{seq = '#', parse = insert_var_ref(false)};
		{seq = '%%', parse = function (s,c)
			local com = s:match '^%%%%%s*(.*)$'
			return {
				kind = 'comment';
				comment = com;
			}
		end};
		{seq = '%!', parse = insert_span_directive(true,false)};
		{seq = '%:', parse = insert_span_directive(false,true)};
		{seq = '%', parse = insert_span_directive(false,false)};
	}
end

function ct.parse_span(str,ctx)

Modified makefile from [fbd94cf6db] to [10a67640c2].

37
38
39
40
41
42
43


44
45
46
47
48
49
50
51
52
53




54
55
56
57
58
59
60
..
84
85
86
87
88
89
90
91
92
93




94
95
96
97
98
99
100
...
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
luac != which luac
sh != which sh

extens = $(wildcard ext/*.lua)
extens-names ?= $(basename $(notdir $(extens)))
rendrs = $(wildcard render/*.lua)
rendrs-names ?= $(basename $(notdir $(rendrs)))



build = build
executable = cortav
default-format-flags = -m html:width 40em

prefix = $(HOME)/.local
bin-prefix = $(prefix)/bin

lua-standalone = $(if $(lua-lib-prefix),$(lua-lib-prefix)/liblua.a,-llua)
lua-bindeps = -lm -ldl





dbg-flags-luac = $(if $(debug),,-s)
dbg-flags-cc = $(if $(debug),-g,-s)

# sterilize the operating theatre
export LUA_PATH=./?.lua;./?.lc
export LUA_PATH_5_3=./?.lc;./?.lua
................................................................................
# raw bytecode without shebang header, must be run as `lua cortav.lc`
$(build)/$(executable).lc: sirsem.lua $(encoding-files) cortav.lua $(rendrs) $(extens) cli.lua | $(build)/
	@echo ' ยป building with extensions $(extens-names)'
	@echo ' ยป building with renderers $(rendrs-names)'
	$(luac) $(dbg-flags-luac) -o $@ $^

# true standalone binary, wraps bytecode file and (optionally) lua
$(build)/$(executable).bin: $(build)/$(executable).lc tool/makeshim.lua
	$(lua) tool/makeshim.lua $< |\
		$(CC) -s -o$@ -xc - -xnone $(lua-standalone) $(lua-bindeps)





$(build)/cortav.html: cortav.ct $(build)/$(executable) | $(build)/
	$(build)/$(executable) $< -o $@ -m render:format html -y html:fossil-uv

.PHONY: syncdoc
syncdoc: $(build)/cortav.html
	fossil uv add $< --as cortav.html
................................................................................
# just in case it ever gets invoked in a bad way
.PHONY: clean
clean:
	rm -f $(build)/*.{html,lc,sh,txt,desktop} \
	      $(build)/$(executable){,.bin}
	rmdir $(build)

$(build)/%.sh: desk/%.sh
	echo >$@ "#!$(sh)"
	echo >>$@ 'cortav_exec="$(bin-prefix)/$(executable)"'
	echo >>$@ 'cortav_flags="$${ct_format_flags-$(default-format-flags)}"'
	cat $< >> $@
	chmod +x $@

$(build)/velartrill-cortav-view.desktop: desk/cortav-view.desktop







>
>










>
>
>
>







 







|
|
|
>
>
>
>







 







|







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
..
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
...
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
luac != which luac
sh != which sh

extens = $(wildcard ext/*.lua)
extens-names ?= $(basename $(notdir $(extens)))
rendrs = $(wildcard render/*.lua)
rendrs-names ?= $(basename $(notdir $(rendrs)))
binds = $(wildcard bind/*.c)
binds-names ?= $(basename $(notdir $(binds)))

build = build
executable = cortav
default-format-flags = -m html:width 40em

prefix = $(HOME)/.local
bin-prefix = $(prefix)/bin

lua-standalone = $(if $(lua-lib-prefix),$(lua-lib-prefix)/liblua.a,-llua)
lua-bindeps = -lm -ldl

ifneq ($(filter net,$(binds-names)),)
    lua-bindeps += -lcurl
endif

dbg-flags-luac = $(if $(debug),,-s)
dbg-flags-cc = $(if $(debug),-g,-s)

# sterilize the operating theatre
export LUA_PATH=./?.lua;./?.lc
export LUA_PATH_5_3=./?.lc;./?.lua
................................................................................
# raw bytecode without shebang header, must be run as `lua cortav.lc`
$(build)/$(executable).lc: sirsem.lua $(encoding-files) cortav.lua $(rendrs) $(extens) cli.lua | $(build)/
	@echo ' ยป building with extensions $(extens-names)'
	@echo ' ยป building with renderers $(rendrs-names)'
	$(luac) $(dbg-flags-luac) -o $@ $^

# true standalone binary, wraps bytecode file and (optionally) lua
$(build)/$(executable).bin: $(build)/$(executable).lc tool/makeshim.lua $(binds)
	$(lua) tool/makeshim.lua $< "" $(binds-names) |\
		$(CC) -s -o$@ -xc - -xnone $(binds) $(lua-standalone) $(lua-bindeps)

# loadable lua modules for binds, mainly useful for testing
$(build)/bind/%.so: bind/%.c bind/bind.h | $(build)/bind/
	$(CC) -fPIC -shared -g -o$@ $<

$(build)/cortav.html: cortav.ct $(build)/$(executable) | $(build)/
	$(build)/$(executable) $< -o $@ -m render:format html -y html:fossil-uv

.PHONY: syncdoc
syncdoc: $(build)/cortav.html
	fossil uv add $< --as cortav.html
................................................................................
# just in case it ever gets invoked in a bad way
.PHONY: clean
clean:
	rm -f $(build)/*.{html,lc,sh,txt,desktop} \
	      $(build)/$(executable){,.bin}
	rmdir $(build)

$(build)/%.sh: desk/%.sh | $(build)/
	echo >$@ "#!$(sh)"
	echo >>$@ 'cortav_exec="$(bin-prefix)/$(executable)"'
	echo >>$@ 'cortav_flags="$${ct_format_flags-$(default-format-flags)}"'
	cat $< >> $@
	chmod +x $@

$(build)/velartrill-cortav-view.desktop: desk/cortav-view.desktop

Modified render/html.lua from [e235e554e3] to [28584fb71a].

173
174
175
176
177
178
179

















180
181
182
183
184
185
186
...
505
506
507
508
509
510
511






512
513
514
515
516
517
518
...
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
...
997
998
999
1000
1001
1002
1003

1004

1005
1006
1007

1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020

1021

1022
1023

1024
1025
1026
1027
1028
1029
1030
....
1032
1033
1034
1035
1036
1037
1038

1039

1040
1041

1042
1043
1044
1045
1046
1047
1048
				overflow-y: auto;
				margin-top: 0;
			}
			aside.footnote > .text > :first-child {
				margin-top: 0;
			}
		]];

















		header = [[
			body { padding: 0 2.5em !important }
			h1,h2,h3,h4,h5,h6 { border-bottom: 1px solid @tone(0.7); }
			h1 { font-size: 200%; border-bottom-style: double !important; border-bottom-width: 3px !important; margin: 0em -1em; }
			h2 { font-size: 130%; margin: 0em -0.7em; }
			h3 { font-size: 110%; margin: 0em -0.5em; }
			h4 { font-size: 100%; font-weight: normal; margin: 0em -0.2em; }
................................................................................

	local renderJob = doc:job('render_html', nil, render_state_handle)
	doc.stage.job = renderJob;

	local runhook = function(h, ...)
		return renderJob:hook(h, render_state_handle, ...)
	end







	local function htmlURI(uri)
		local family = uri:canfetch()
		if family == 'file' then
			if uri.namespace == 'localhost' then
				-- emit an actual file url
				return 'file://' .. uri:construct('path','frag')
................................................................................
				tag('body', nil, body or ''))
		end

		local function htmlSpan(spans, block, sec)
			local text = {}
			for k,v in pairs(spans) do
				if type(v) == 'string' then
					v=v:gsub('[<>&"]', function(x)
							return string.format('&#%02u;', string.byte(x))
						end)
					for fn, ext in renderJob:each('hook','render_html_sanitize') do
						v = fn(renderJob:delegate(ext), v)
					end
					table.insert(text,v)
				else
					table.insert(text, (span_renderers[v.kind](v, block, sec)))
				end
................................................................................
					end
				end};
				{ss.mime'text/x.cortav', function(s,ctr)
					if s == nil then
						return {}
					elseif next(ctr) == nil then
						if (s.mode == 'embed' or s.mode == 'auto') and s.doc then

							ctr.tag = 'div'; -- kinda hacky, maybe fix

							ctr.nodes = renderSubdoc(s.doc)
						elseif s.mode == 'link' then
							-- yeah this is not gonna work my dude

							ctr.elt = 'embed';
							ctr.attrs = {
								type = 'text/x.cortav';
								src = htmlURI(s.uri);
							}
						end
					end
				end};
				{ss.mime'text/html',     function(s,ctr)
					if s == nil then
						return {}
					elseif next(ctr) == nil then
						if (s.mode == 'embed' or s.mode == 'auto') and s.raw then

							ctr.tag = 'div'

							ctr.nodes = s.raw
						elseif s.mode == 'link' then

							ctr.elt = 'embed';
							ctr.attrs = {
								type = 'text/html';
								src = htmlURI(s.uri);
							}
						end
					end
................................................................................
				{ss.mime'text/*',     function(s,ctr)
					if s == nil then
						return {}
					elseif next(ctr) == nil then
						local mime = s.mime:clone()
						mime.opts={}
						if (s.mode == 'embed' or s.mode == 'auto') and s.raw then

							ctr.tag = 'pre';

							ctr.nodes = s.raw
						elseif s.mode == 'link' then

							ctr.elt = 'embed';
							ctr.attrs = {
								type = tostring(mime);
								src = htmlURI(s.uri);
							}
						end
					end







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>







 







|
<
<







 







>

>



>













>

>


>







 







>

>
|

>







173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
...
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
...
652
653
654
655
656
657
658
659


660
661
662
663
664
665
666
....
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
....
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
				overflow-y: auto;
				margin-top: 0;
			}
			aside.footnote > .text > :first-child {
				margin-top: 0;
			}
		]];
		docmeta = [[
			.render-warn {
				border: 1px solid @tone(0.1 20);
				background: @tone(0.4 20);
				padding: 1em;
				margin: 5em 1em;
			}
		]];
		embed = [[
			embed, .embed {
				width: 100%;
				height: fit-content;
				max-height: 80vh;
				overflow: scroll;
			}
			embed {height: 20em;}
		]];
		header = [[
			body { padding: 0 2.5em !important }
			h1,h2,h3,h4,h5,h6 { border-bottom: 1px solid @tone(0.7); }
			h1 { font-size: 200%; border-bottom-style: double !important; border-bottom-width: 3px !important; margin: 0em -1em; }
			h2 { font-size: 130%; margin: 0em -0.7em; }
			h3 { font-size: 110%; margin: 0em -0.5em; }
			h4 { font-size: 100%; font-weight: normal; margin: 0em -0.2em; }
................................................................................

	local renderJob = doc:job('render_html', nil, render_state_handle)
	doc.stage.job = renderJob;

	local runhook = function(h, ...)
		return renderJob:hook(h, render_state_handle, ...)
	end

	local function htmlentities(v)
		return v:gsub('[<>&"]', function(x)
			return string.format('&#%02u;', string.byte(x))
		end)
	end

	local function htmlURI(uri)
		local family = uri:canfetch()
		if family == 'file' then
			if uri.namespace == 'localhost' then
				-- emit an actual file url
				return 'file://' .. uri:construct('path','frag')
................................................................................
				tag('body', nil, body or ''))
		end

		local function htmlSpan(spans, block, sec)
			local text = {}
			for k,v in pairs(spans) do
				if type(v) == 'string' then
					v=htmlentities(v)


					for fn, ext in renderJob:each('hook','render_html_sanitize') do
						v = fn(renderJob:delegate(ext), v)
					end
					table.insert(text,v)
				else
					table.insert(text, (span_renderers[v.kind](v, block, sec)))
				end
................................................................................
					end
				end};
				{ss.mime'text/x.cortav', function(s,ctr)
					if s == nil then
						return {}
					elseif next(ctr) == nil then
						if (s.mode == 'embed' or s.mode == 'auto') and s.doc then
							addStyle 'embed'
							ctr.tag = 'div'; -- kinda hacky, maybe fix
							ctr.attrs = {class='embed'}
							ctr.nodes = renderSubdoc(s.doc)
						elseif s.mode == 'link' then
							-- yeah this is not gonna work my dude
							addStyle 'embed'
							ctr.elt = 'embed';
							ctr.attrs = {
								type = 'text/x.cortav';
								src = htmlURI(s.uri);
							}
						end
					end
				end};
				{ss.mime'text/html',     function(s,ctr)
					if s == nil then
						return {}
					elseif next(ctr) == nil then
						if (s.mode == 'embed' or s.mode == 'auto') and s.raw then
							addStyle 'embed'
							ctr.tag = 'div'
							ctr.attrs = {class='embed'}
							ctr.nodes = s.raw
						elseif s.mode == 'link' then
							addStyle 'embed'
							ctr.elt = 'embed';
							ctr.attrs = {
								type = 'text/html';
								src = htmlURI(s.uri);
							}
						end
					end
................................................................................
				{ss.mime'text/*',     function(s,ctr)
					if s == nil then
						return {}
					elseif next(ctr) == nil then
						local mime = s.mime:clone()
						mime.opts={}
						if (s.mode == 'embed' or s.mode == 'auto') and s.raw then
							addStyle 'embed'
							ctr.tag = 'pre';
							ctr.attrs = {class='embed'}
							ctr.nodes = htmlentities(s.raw);
						elseif s.mode == 'link' then
							addStyle 'embed'
							ctr.elt = 'embed';
							ctr.attrs = {
								type = tostring(mime);
								src = htmlURI(s.uri);
							}
						end
					end

Modified sirsem.lua from [9b28e1fde4] to [2b64c7033a].

17
18
19
20
21
22
23


24
25
26
27
28
29
30
...
112
113
114
115
116
117
118

119




120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
....
1170
1171
1172
1173
1174
1175
1176

















1177
1178
1179
1180
1181
1182
1183
1184
....
1336
1337
1338
1339
1340
1341
1342



1343
1344
1345
1346
1347
1348
1349
		end
		return pkg
	end
	ss = namespace 'sirsem'
	ss.namespace = namespace
end



function ss.map(fn, lst)
	local new = {}
	for k,v in pairs(lst) do
		table.insert(new, fn(v,k))
	end
	return new
end
................................................................................
                              -- tbl (lightweight alternative to shallow copies)
	tpl = tpl or {}
	return setmetatable({}, {__index=tbl})
end

ss.str = {}


function ss.str.begins(str, pfx)




	-- appallingly, this is actually ~2/5ths faster than either
	-- of the below. i hate scripting languages so much
	return string.find(str, pfx, 1, true) == 1
	-- to my shock, disgust, and horror, even writing my own
	-- string scanning library for lua IN C only sped this up by
	-- a tiny fraction. i am just speechless.
-- 	return string.sub(str, 1, #pfx) == pfx

-- 	local pl = string.len(pfx)
-- 	local sl = string.len(str)
-- 	if sl < pl then return false end
-- 	for i=1,pl do
-- 		if string.byte(str,i) ~= string.byte(pfx,i) then
-- 			return false
-- 		end
-- 	end
-- 	return true

end

function ss.enum(syms)
	local e = {}
	for i,v in pairs(syms) do
		e[v] = i
		e[i] = v
................................................................................
local fetchableProtocols = {
	http = {
		proto = {
			{'http'};
			{'https'};
			{'http', 'tls'};
		};

















		fetch = function(uri)
			fetchexn('cortav must be compiled with the C shim and libcurl support to use http fetch'):throw()
		end;
	};
	file = {
		proto = {
			{'file'};
			{'file', 'txt'};
................................................................................
		class = nil;
		namespace = nil;
		path = nil;
		query = nil;
		frag = nil;
		auth = nil;
	} end;



	construct = function(me, str)
		local enc = ss.str.enc.utf8
		-- URIs must be either ASCII or utf8, so we  read and
		-- store as UTF8. to use a URI in another encoding, it
		-- must be manually converted to and fro using the
		-- appropriate functions, such as encodeUCS
		if not str then return end







>
>







 







>
|
>
>
>
>
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







 







>
>
>







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
....
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
....
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
		end
		return pkg
	end
	ss = namespace 'sirsem'
	ss.namespace = namespace
end

local native = _G.native

function ss.map(fn, lst)
	local new = {}
	for k,v in pairs(lst) do
		table.insert(new, fn(v,k))
	end
	return new
end
................................................................................
                              -- tbl (lightweight alternative to shallow copies)
	tpl = tpl or {}
	return setmetatable({}, {__index=tbl})
end

ss.str = {}

if native then
	function ss.str.begins(str, pfx)
		return native.strutils.rangematch(str,1,pfx)
	end
else
	function ss.str.begins(str, pfx)
		-- appallingly, this is actually ~2/5ths faster than either
		-- of the below. i hate scripting languages so much
		return string.find(str, pfx, 1, true) == 1
		-- to my shock, disgust, and horror, even writing my own
		-- string scanning library for lua IN C only sped this up by
		-- a tiny fraction. i am just speechless.
	-- 	return string.sub(str, 1, #pfx) == pfx

	-- 	local pl = string.len(pfx)
	-- 	local sl = string.len(str)
	-- 	if sl < pl then return false end
	-- 	for i=1,pl do
	-- 		if string.byte(str,i) ~= string.byte(pfx,i) then
	-- 			return false
	-- 		end
	-- 	end
	-- 	return true
	end
end

function ss.enum(syms)
	local e = {}
	for i,v in pairs(syms) do
		e[v] = i
		e[i] = v
................................................................................
local fetchableProtocols = {
	http = {
		proto = {
			{'http'};
			{'https'};
			{'http', 'tls'};
		};
		fetch = native and native.net and function(uri)
			-- translate to a curl-compatible URI
			if uri.path and uri.path ~= '' and uri.path:sub(1,1) ~= '/' then
				fetchexn('relative HTTP URIs like โ€œ%sโ€ are not fetchable', uri):throw()
			end
			uri = uri:clone()
			if uri.class[2] == 'tls' then
				uri.class = {'https'}
			end
			if not uri.namespace then
				uri.namespace = 'localhost'
			end
			local body, e = native.net.fetchURI(tostring(uri))
			if e then
				fetchexn('could not fetch URI โ€œ%sโ€: %s',uri,e):throw()
			end
			return body
		end or function(uri)
			fetchexn('cortav must be compiled with the C shim and libcurl support to use http fetch'):throw()
		end;
	};
	file = {
		proto = {
			{'file'};
			{'file', 'txt'};
................................................................................
		class = nil;
		namespace = nil;
		path = nil;
		query = nil;
		frag = nil;
		auth = nil;
	} end;
	clonesetup = function(me)
		me.class = ss.clone(me.class)
	end;
	construct = function(me, str)
		local enc = ss.str.enc.utf8
		-- URIs must be either ASCII or utf8, so we  read and
		-- store as UTF8. to use a URI in another encoding, it
		-- must be manually converted to and fro using the
		-- appropriate functions, such as encodeUCS
		if not str then return end

Modified tool/makeshim.lua from [cea771ab78] to [f7d9ea5be8].

31
32
33
34
35
36
37









38
39
40
41
42
43
44
..
60
61
62
63
64
65
66





67
68
69
70
71




























72
73
74
75
76
77
78
..
90
91
92
93
94
95
96

97
98
99
100

	// load and run our payload
	int e = luaL_loadbufferx(l, ct_bytecode, sizeof(ct_bytecode), "cortav", "b");
	if (e != LUA_OK) {
		printf("some kind of error idk fam\n");
		return -1;
	}










	if (lua_pcall(l, 0, 0, 0) != LUA_OK) {
		size_t len;
		const char* msg = luaL_tolstring(l, -1, &len);
		if (isatty(2)) {
			fprintf(stderr, "\33[31;1m(fatal)\33[m %.*s\n", (int)len, msg);
		} else {
................................................................................
		io.stderr:write('(' .. arg[0]..' fatal) cannot open file '..arg[i])
	end
	return dflt
end

local src = setfile(1, io.stdin, "rb")
local dest = setfile(2, io.stdout, "w")






local cstr = {}
local strtpl = [[static char ct_bytecode [%u] = {
%s
};]]





























local bytes = {}

local bn = 1
local len = 0
while true do
	local byte = src:read(1)
................................................................................
	bytes[bn] = str
	bn = bn + 1
end

local lines = {
	includes;
	strtpl:format(#bytes, table.concat(bytes));

	main;
}

dest:write(table.concat(lines, '\n'))







>
>
>
>
>
>
>
>
>







 







>
>
>
>
>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>




31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
..
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
...
132
133
134
135
136
137
138
139
140
141
142
143

	// load and run our payload
	int e = luaL_loadbufferx(l, ct_bytecode, sizeof(ct_bytecode), "cortav", "b");
	if (e != LUA_OK) {
		printf("some kind of error idk fam\n");
		return -1;
	}

	// create the native interface table, if nothing
	// else to signal that cortav is running under a
	// binary shim
	lua_pushglobaltable(l);
		lua_newtable(l);
			_lua_env_setup
		lua_setfield(l, -2, "native");
	lua_pop(l, 1);

	if (lua_pcall(l, 0, 0, 0) != LUA_OK) {
		size_t len;
		const char* msg = luaL_tolstring(l, -1, &len);
		if (isatty(2)) {
			fprintf(stderr, "\33[31;1m(fatal)\33[m %.*s\n", (int)len, msg);
		} else {
................................................................................
		io.stderr:write('(' .. arg[0]..' fatal) cannot open file '..arg[i])
	end
	return dflt
end

local src = setfile(1, io.stdin, "rb")
local dest = setfile(2, io.stdout, "w")
local binds = {}
for i=3,#arg do
	io.stderr:write(string.format("(%s  info) including loader for bind %s\n", arg[0], arg[i]))
	table.insert(binds, arg[i])
end

local cstr = {}
local strtpl = [[static char ct_bytecode [%u] = {
%s
};]]

local bindfn = [[#define _lua_env_setup]]

if next(binds) then
	-- make cpp do our interpolation for us
	bindfn = [[#define _lua_env_setup init_binds(l);]]
	local calls = {}
	local decls = {}
	local ctpl = [[
	luaopen_bind_%s(l);
	lua_setfield(l, -2, "%s");
]]
	for n,b in ipairs(binds) do
		table.insert(decls, string.format('extern int luaopen_bind_%s(lua_State* l);\n', b))
		table.insert(calls, string.format(ctpl, b, b))
	end
	local hdr = [[
static void init_binds(lua_State* l) {
]]
	local foot = [[
}
]]
	bindfn = bindfn .. '\n'
		.. table.concat(decls)
		.. hdr
			.. table.concat(calls)
		.. foot
end

local bytes = {}

local bn = 1
local len = 0
while true do
	local byte = src:read(1)
................................................................................
	bytes[bn] = str
	bn = bn + 1
end

local lines = {
	includes;
	strtpl:format(#bytes, table.concat(bytes));
	bindfn;
	main;
}

dest:write(table.concat(lines, '\n'))