1if not modules then modules = { } end modules ['l-os'] = {
2 version = 1.001,
3 comment = "companion to luat-lib.mkiv",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files"
7}
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28local os = os
29local date, time, difftime = os.date, os.time, os.difftime
30local find, format, gsub, upper, gmatch = string.find, string.format, string.gsub, string.upper, string.gmatch
31local concat = table.concat
32local random, ceil, randomseed, modf = math.random, math.ceil, math.randomseed, math.modf
33local type, setmetatable, tonumber, tostring = type, setmetatable, tonumber, tostring
34
35
36
37
38do
39
40 local selfdir = os.selfdir
41
42 if selfdir == "" then
43 selfdir = nil
44 end
45
46 if not selfdir then
47
48
49
50 if arg then
51
52 for i=1,#arg do
53 local a = arg[i]
54 if find(a,"^%-%-[c:]*texmfbinpath=") then
55 selfdir = gsub(a,"^.-=","")
56 break
57 end
58 end
59 end
60
61 if not selfdir then
62 selfdir = os.selfbin or "luatex"
63 if find(selfdir,"[/\\]") then
64 selfdir = gsub(selfdir,"[/\\][^/\\]*$","")
65 elseif os.getenv then
66 local path = os.getenv("PATH")
67 local name = gsub(selfdir,"^.*[/\\][^/\\]","")
68 local patt = "[^:]+"
69 if os.type == "windows" then
70 patt = "[^;]+"
71 name = name .. ".exe"
72 end
73 local isfile
74 if lfs then
75
76 local attributes = lfs.attributes
77 isfile = function(name)
78 local a = attributes(name,"mode")
79 return a == "file" or a == "link" or nil
80 end
81 else
82
83 local open = io.open
84 isfile = function(name)
85 local f = open(name)
86 if f then
87 f:close()
88 return true
89 end
90 end
91 end
92 for p in gmatch(path,patt) do
93
94 if isfile(p .. "/" .. name) then
95 selfdir = p
96 break
97 end
98 end
99 end
100 end
101
102
103
104 os.selfdir = selfdir or "."
105
106 end
107
108
109
110end
111
112
113
114
115
116
117
118
119math.initialseed = tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
120
121randomseed(math.initialseed)
122
123if not os.__getenv__ then
124
125 os.__getenv__ = os.getenv
126 os.__setenv__ = os.setenv
127
128 if os.env then
129
130 local osgetenv = os.getenv
131 local ossetenv = os.setenv
132 local osenv = os.env local _ = osenv.PATH
133
134 function os.setenv(k,v)
135 if v == nil then
136 v = ""
137 end
138 local K = upper(k)
139 osenv[K] = v
140 if type(v) == "table" then
141 v = concat(v,";")
142 end
143 ossetenv(K,v)
144 end
145
146 function os.getenv(k)
147 local K = upper(k)
148 local v = osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
149 if v == "" then
150 return nil
151 else
152 return v
153 end
154 end
155
156 else
157
158 local ossetenv = os.setenv
159 local osgetenv = os.getenv
160 local osenv = { }
161
162 function os.setenv(k,v)
163 if v == nil then
164 v = ""
165 end
166 local K = upper(k)
167 osenv[K] = v
168 end
169
170 function os.getenv(k)
171 local K = upper(k)
172 local v = osenv[K] or osgetenv(K) or osgetenv(k)
173 if v == "" then
174 return nil
175 else
176 return v
177 end
178 end
179
180 local function __index(t,k)
181 return os.getenv(k)
182 end
183 local function __newindex(t,k,v)
184 os.setenv(k,v)
185 end
186
187 os.env = { }
188
189 setmetatable(os.env, { __index = __index, __newindex = __newindex } )
190
191 end
192
193end
194
195
196
197if not io.fileseparator then
198
199 if find(os.getenv("PATH"),";",1,true) then
200 io.fileseparator, io.pathseparator, os.type = "\\", ";", os.type or "windows"
201 else
202 io.fileseparator, io.pathseparator, os.type = "/" , ":", os.type or "unix"
203 end
204
205end
206
207os.type = os.type or (io.pathseparator == ";" and "windows") or "unix"
208os.name = os.name or (os.type == "windows" and "mswin" ) or "linux"
209
210if os.type == "windows" then
211 os.libsuffix, os.binsuffix, os.binsuffixes = 'dll', 'exe', { 'exe', 'cmd', 'bat' }
212else
213 os.libsuffix, os.binsuffix, os.binsuffixes = 'so', '', { '' }
214end
215
216do
217
218 local execute = os.execute
219 local iopopen = io.popen
220 local ostype = os.type
221
222 local function resultof(command)
223
224 local handle = iopopen(command,ostype == "windows" and "rb" or "r")
225 if handle then
226 local result = handle:read("*all") or ""
227 handle:close()
228 return result
229 else
230 return ""
231 end
232 end
233
234 os.resultof = resultof
235
236 function os.pipeto(command)
237 return iopopen(command,"w")
238 end
239
240 local launchers = {
241 windows = "start %s",
242 macosx = "open %s",
243 unix = "xdg-open %s &> /dev/null &",
244 }
245
246 function os.launch(str)
247 local command = format(launchers[os.name] or launchers.unix,str)
248
249
250 execute(command)
251 end
252
253end
254
255do
256
257 local gettimeofday = os.gettimeofday or os.clock
258 os.gettimeofday = gettimeofday
259
260 local startuptime = gettimeofday()
261
262 function os.runtime()
263 return gettimeofday() - startuptime
264 end
265
266
267
268
269
270
271
272end
273
274
275
276
277
278
279
280
281
282
283
284
285
286do
287
288 local name = os.name or "linux"
289 local platform = os.getenv("MTX_PLATFORM") or ""
290 local architecture = os.uname and os.uname().machine
291 local bits = os.getenv("MTX_BITS") or find(platform,"64") and 64 or 32
292
293 if platform ~= "" then
294
295
296
297 elseif os.type == "windows" then
298
299
300
301
302 architecture = string.lower(architecture or os.getenv("PROCESSOR_ARCHITECTURE") or "")
303 if architecture == "x86_64" then
304 bits, platform = 64, "win64"
305 elseif find(architecture,"amd64") then
306 bits, platform = 64, "win64"
307 elseif find(architecture,"arm64") then
308 bits, platform = 64, "windows-arm64"
309 elseif find(architecture,"arm32") then
310 bits, platform = 32, "windows-arm32"
311 else
312 bits, platform = 32, "mswin"
313 end
314
315 elseif name == "linux" then
316
317
318
319
320
321
322
323 architecture = architecture or os.getenv("HOSTTYPE") or resultof("uname -m") or ""
324 local musl = find(os.selfdir or "","linuxmusl")
325 if find(architecture,"x86_64") then
326 bits, platform = 64, musl and "linuxmusl" or "linux-64"
327 elseif find(architecture,"ppc") then
328 bits, platform = 32, "linux-ppc"
329 else
330 bits, platform = 32, musl and "linuxmusl" or "linux"
331 end
332
333 elseif name == "macosx" then
334
335
336
337
338
339
340
341
342 architecture = architecture or resultof("echo $HOSTTYPE") or ""
343 if architecture == "" then
344 bits, platform = 64, "osx-intel"
345 elseif find(architecture,"i386") then
346 bits, platform = 64, "osx-intel"
347 elseif find(architecture,"x86_64") then
348 bits, platform = 64, "osx-64"
349 elseif find(architecture,"arm64") then
350 bits, platform = 64, "osx-arm"
351 else
352 bits, platform = 32, "osx-ppc"
353 end
354
355 elseif name == "sunos" then
356
357 architecture = architecture or resultof("uname -m") or ""
358 if find(architecture,"sparc") then
359 bits, platform = 32, "solaris-sparc"
360 else
361 bits, platform = 32, "solaris-intel"
362 end
363
364 elseif name == "freebsd" then
365
366 architecture = architecture or os.getenv("MACHTYPE") or resultof("uname -m") or ""
367 if find(architecture,"amd64") or find(architecture,"AMD64") then
368 bits, platform = 64, "freebsd-amd64"
369 else
370 bits, platform = 32, "freebsd"
371 end
372
373 elseif name == "kfreebsd" then
374
375 architecture = architecture or os.getenv("HOSTTYPE") or resultof("uname -m") or ""
376 if architecture == "x86_64" then
377 bits, platform = 64, "kfreebsd-amd64"
378 else
379 bits, platform = 32, "kfreebsd-i386"
380 end
381
382 else
383
384 architecture = architecture or resultof("uname -m") or ""
385
386 if find(architecture,"aarch64") then
387 bits, platform = "linux-aarch64"
388 elseif find(architecture,"armv7l") then
389
390 bits, platform = 32, "linux-armhf"
391 elseif find(architecture,"mips64") or find(architecture,"mips64el") then
392 bits, platform = 64, "linux-mipsel"
393 elseif find(architecture,"mipsel") or find(architecture,"mips") then
394 bits, platform = 32, "linux-mipsel"
395 else
396 bits, platform = 64, "linux-64"
397 end
398
399 end
400
401 os.setenv("MTX_PLATFORM",platform)
402 os.setenv("MTX_BITS", bits)
403
404 os.platform = platform
405 os.bits = bits
406 os.newline = name == "windows" and "\013\010" or "\010"
407
408end
409
410
411
412
413
414
415
416
417
418
419do
420
421 local t = { 8, 9, "a", "b" }
422
423 function os.uuid()
424 return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
425 random(0xFFFF),random(0xFFFF),
426 random(0x0FFF),
427 t[ceil(random(4))] or 8,random(0x0FFF),
428 random(0xFFFF),
429 random(0xFFFF),random(0xFFFF),random(0xFFFF)
430 )
431 end
432
433end
434
435do
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451 local hour, min
452
453 function os.timezone(difference)
454 if not hour then
455
456 local current = time()
457 local utcdate = date("!*t", current)
458 local localdate = date("*t", current)
459 localdate.isdst = false
460 local timediff = difftime(time(localdate), time(utcdate))
461 hour, min = modf(timediff / 3600)
462 min = min * 60
463 end
464 if difference then
465 return hour, min
466 else
467 return format("%+03d:%02d",hour,min)
468 end
469 end
470
471
472
473 local timeformat = format("%%s%s",os.timezone())
474 local dateformat = "%Y-%m-%d %H:%M:%S"
475 local lasttime = nil
476 local lastdate = nil
477
478 function os.fulltime(t,default)
479 t = t and tonumber(t) or 0
480 if t > 0 then
481
482 elseif default then
483 return default
484 else
485 t = time()
486 end
487 if t ~= lasttime then
488 lasttime = t
489 lastdate = format(timeformat,date(dateformat))
490 end
491 return lastdate
492 end
493
494
495
496 local dateformat = "%Y-%m-%d %H:%M:%S"
497 local lasttime = nil
498 local lastdate = nil
499
500 function os.localtime(t,default)
501 t = t and tonumber(t) or 0
502 if t > 0 then
503
504 elseif default then
505 return default
506 else
507 t = time()
508 end
509 if t ~= lasttime then
510 lasttime = t
511 lastdate = date(dateformat,t)
512 end
513 return lastdate
514 end
515
516 function os.converttime(t,default)
517 local t = tonumber(t)
518 if t and t > 0 then
519 return date(dateformat,t)
520 else
521 return default or "-"
522 end
523 end
524
525
526
527 function os.today()
528 return date("!*t")
529 end
530
531
532
533 function os.now()
534 return date("!%Y-%m-%d %H:%M:%S")
535 end
536
537end
538
539do
540
541 local cache = { }
542
543 local function which(filename)
544 local fullname = cache[filename]
545 if fullname == nil then
546 local suffix = file.suffix(filename)
547 local suffixes = suffix == "" and os.binsuffixes or { suffix }
548 for directory in gmatch(os.getenv("PATH"),"[^" .. io.pathseparator .."]+") do
549 local df = file.join(directory,filename)
550 for i=1,#suffixes do
551 local dfs = file.addsuffix(df,suffixes[i])
552 if io.exists(dfs) then
553 fullname = dfs
554 break
555 end
556 end
557 end
558 if not fullname then
559 fullname = false
560 end
561 cache[filename] = fullname
562 end
563 return fullname
564 end
565
566 os.which = which
567 os.where = which
568
569
570
571
572
573
574end
575
576if not os.sleep then
577
578 local socket = socket
579
580 function os.sleep(n)
581 if not socket then
582
583
584 socket = require("socket")
585 end
586 socket.sleep(n)
587 end
588
589end
590
591
592
593do
594
595 local function isleapyear(year)
596
597 return (year % 4 == 0) and (year % 100 ~= 0 or year % 400 == 0)
598
599 end
600
601 os.isleapyear = isleapyear
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617 local days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
618
619 local function nofdays(year,month,day)
620 if not month then
621 return isleapyear(year) and 365 or 364
622 elseif not day then
623 return month == 2 and isleapyear(year) and 29 or days[month]
624 else
625 for i=1,month-1 do
626 day = day + days[i]
627 end
628 if month > 2 and isleapyear(year) then
629 day = day + 1
630 end
631 return day
632 end
633 end
634
635 os.nofdays = nofdays
636
637 function os.weekday(day,month,year)
638 return date("%w",time { year = year, month = month, day = day }) + 1
639 end
640
641 function os.validdate(year,month,day)
642
643
644 if month < 1 then
645 month = 1
646 elseif month > 12 then
647 month = 12
648 end
649 if day < 1 then
650 day = 1
651 else
652 local max = nofdays(year,month)
653 if day > max then
654 day = max
655 end
656 end
657 return year, month, day
658 end
659
660 function os.date(fmt,...)
661 if not fmt then
662
663 fmt = "%Y-%m-%d %H:%M"
664 end
665 return date(fmt,...)
666 end
667
668end
669
670do
671
672 local osexit = os.exit
673 local exitcode = nil
674
675 function os.setexitcode(code)
676 exitcode = code
677 end
678
679 function os.exit(c)
680 if exitcode ~= nil then
681 return osexit(exitcode)
682 end
683 if c ~= nil then
684 return osexit(c)
685 end
686 return osexit()
687 end
688
689end
690 |