texlive[54975] Master/texmf-dist: lualibs (2may20)

commits+karl at tug.org commits+karl at tug.org
Sat May 2 23:03:20 CEST 2020


Revision: 54975
          http://tug.org/svn/texlive?view=revision&revision=54975
Author:   karl
Date:     2020-05-02 23:03:20 +0200 (Sat, 02 May 2020)
Log Message:
-----------
lualibs (2may20)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/luatex/lualibs/NEWS
    trunk/Master/texmf-dist/doc/luatex/lualibs/README.md
    trunk/Master/texmf-dist/doc/luatex/lualibs/lualibs.pdf
    trunk/Master/texmf-dist/source/luatex/lualibs/lualibs.dtx
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic-merged.lua
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic.lua
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended.lua
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-os.lua
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-table.lua
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-trac-inf.lua
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-tab.lua
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs.lua

Modified: trunk/Master/texmf-dist/doc/luatex/lualibs/NEWS
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/lualibs/NEWS	2020-05-02 21:03:03 UTC (rev 54974)
+++ trunk/Master/texmf-dist/doc/luatex/lualibs/NEWS	2020-05-02 21:03:20 UTC (rev 54975)
@@ -1,4 +1,7 @@
                         History of the lualibs package
+2020/05/01 v2.71/
+    * sync with Context current as of 2020/04/30.
+                        
 2020/02/02 v2.70/
     * sync with Context current as of 2020/01/26.
                             

Modified: trunk/Master/texmf-dist/doc/luatex/lualibs/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/lualibs/README.md	2020-05-02 21:03:03 UTC (rev 54974)
+++ trunk/Master/texmf-dist/doc/luatex/lualibs/README.md	2020-05-02 21:03:20 UTC (rev 54975)
@@ -1,10 +1,10 @@
 # The Lualibs Package
 
-VERSION: 2.70
+VERSION: 2.71
 
-DATE: 2020-02-02
+DATE: 2020-05-01
 
-FONTLOADERDATE: 2020-01-26
+FONTLOADERDATE: 2020-04-30
 
 Lualibs is a collection of Lua modules useful for general programming.
 

Modified: trunk/Master/texmf-dist/doc/luatex/lualibs/lualibs.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/source/luatex/lualibs/lualibs.dtx
===================================================================
--- trunk/Master/texmf-dist/source/luatex/lualibs/lualibs.dtx	2020-05-02 21:03:03 UTC (rev 54974)
+++ trunk/Master/texmf-dist/source/luatex/lualibs/lualibs.dtx	2020-05-02 21:03:20 UTC (rev 54975)
@@ -37,7 +37,7 @@
 \input docstrip.tex
 \Msg{************************************************************************}
 \Msg{* Installation}
-\Msg{* Package: lualibs 2020-02-02 v2.70 Lua additional functions.}
+\Msg{* Package: lualibs 2020-05-01 v2.71 Lua additional functions.}
 \Msg{************************************************************************}
 
 \keepsilent
@@ -107,7 +107,7 @@
 %<*driver>
 \NeedsTeXFormat{LaTeX2e}
 \ProvidesFile{lualibs.drv}
-  [2020/02/02 v2.70 Lua Libraries.]
+  [2020/05/01 v2.71 Lua Libraries.]
 \documentclass{ltxdoc}
 \usepackage{fancyvrb,xspace}
 \usepackage[x11names]{xcolor}
@@ -208,7 +208,7 @@
 % \GetFileInfo{lualibs.drv}
 %
 % \title{The \identifier{lualibs} package}
-% \date{2020/02/02 v2.70}
+% \date{2020/05/01 v2.71}
 % \author{Élie Roux      · \email{elie.roux at telecom-bretagne.eu}\\
 %         Philipp Gesang · \email{phg at phi-gamma.net}\\
 %         The \LaTeX3 Project · \email{https://github.com/latex3/lualibs/}\\
@@ -429,8 +429,8 @@
 
 lualibs.module_info = {
   name          = "lualibs",
-  version       = "2.70",       --TAGVERSION
-    date        = "2020-02-02", --TAGDATE
+  version       = "2.71",       --TAGVERSION
+    date        = "2020-05-01", --TAGDATE
   description   = "ConTeXt Lua standard libraries.",
   author        = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
   copyright     = "PRAGMA ADE / ConTeXt Development Team",
@@ -583,8 +583,8 @@
 
 local lualibs_basic_module = {
   name          = "lualibs-basic",
-  version       = "2.70",       --TAGVERSION
-  date          = "2020-02-02", --TAGDATE
+  version       = "2.71",       --TAGVERSION
+  date          = "2020-05-01", --TAGDATE
   description   = "ConTeXt Lua libraries -- basic collection.",
   author        = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
   copyright     = "PRAGMA ADE / ConTeXt Development Team",
@@ -665,8 +665,8 @@
 
 local lualibs_extended_module = {
   name          = "lualibs-extended",
-  version       = "2.70",       --TAGVERSION
-  date          = "2020-02-02", --TAGDATE
+  version       = "2.71",       --TAGVERSION
+  date          = "2020-05-01", --TAGDATE
   description   = "ConTeXt Lua libraries -- extended collection.",
   author        = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
   copyright     = "PRAGMA ADE / ConTeXt Development Team",

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic-merged.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic-merged.lua	2020-05-02 21:03:03 UTC (rev 54974)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic-merged.lua	2020-05-02 21:03:20 UTC (rev 54975)
@@ -1,6 +1,6 @@
 -- merged file : lualibs-basic-merged.lua
 -- parent file : lualibs-basic.lua
--- merge date  : Sun Feb  2 22:31:00 2020
+-- merge date  : 2020-05-01 15:49
 
 do -- begin closure to overcome local limits and interference
 
@@ -1700,13 +1700,13 @@
  end
  return hsh
 end
-local noquotes,hexify,handle,compact,inline,functions,metacheck
+local noquotes,hexify,handle,compact,inline,functions,metacheck,accurate
 local reserved=table.tohash { 
  'and','break','do','else','elseif','end','false','for','function','if',
  'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
+ 'NaN','goto','const',
 }
-local function is_simple_table(t,hexify) 
+local function is_simple_table(t,hexify,accurate) 
  local nt=#t
  if nt>0 then
   local n=0
@@ -1725,6 +1725,8 @@
     if tv=="number" then
      if hexify then
       tt[i]=format("0x%X",v)
+     elseif accurate then
+      tt[i]=format("%q",v)
      else
       tt[i]=v 
      end
@@ -1745,6 +1747,8 @@
     if tv=="number" then
      if hexify then
       tt[i+1]=format("0x%X",v)
+     elseif accurate then
+      tt[i+1]=format("%q",v)
      else
       tt[i+1]=v 
      end
@@ -1816,6 +1820,8 @@
     if tv=="number" then
      if hexify then
       handle(format("%s 0x%X,",depth,v))
+     elseif accurate then
+      handle(format("%s %q,",depth,v))
      else
       handle(format("%s %s,",depth,v)) 
      end
@@ -1825,7 +1831,7 @@
      if next(v)==nil then
       handle(format("%s {},",depth))
      elseif inline then 
-      local st=is_simple_table(v,hexify)
+      local st=is_simple_table(v,hexify,accurate)
       if st then
        handle(format("%s { %s },",depth,concat(st,", ")))
       else
@@ -1853,6 +1859,8 @@
     if tk=="number" then
      if hexify then
       handle(format("%s [0x%X]=0x%X,",depth,k,v))
+     elseif accurate then
+      handle(format("%s [%s]=%q,",depth,k,v))
      else
       handle(format("%s [%s]=%s,",depth,k,v)) 
      end
@@ -1859,6 +1867,8 @@
     elseif tk=="boolean" then
      if hexify then
       handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+     elseif accurate then
+      handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
      else
       handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) 
      end
@@ -1866,6 +1876,8 @@
     elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
      if hexify then
       handle(format("%s %s=0x%X,",depth,k,v))
+     elseif accurate then
+      handle(format("%s %s=%q,",depth,k,v))
      else
       handle(format("%s %s=%s,",depth,k,v)) 
      end
@@ -1872,6 +1884,8 @@
     else
      if hexify then
       handle(format("%s [%q]=0x%X,",depth,k,v))
+     elseif accurate then
+      handle(format("%s [%q]=%q,",depth,k,v))
      else
       handle(format("%s [%q]=%s,",depth,k,v)) 
      end
@@ -1880,6 +1894,8 @@
     if tk=="number" then
      if hexify then
       handle(format("%s [0x%X]=%q,",depth,k,v))
+     elseif accurate then
+      handle(format("%s [%q]=%q,",depth,k,v))
      else
       handle(format("%s [%s]=%q,",depth,k,v))
      end
@@ -1896,6 +1912,8 @@
      if tk=="number" then
       if hexify then
        handle(format("%s [0x%X]={},",depth,k))
+      elseif accurate then
+       handle(format("%s [%q]={},",depth,k))
       else
        handle(format("%s [%s]={},",depth,k))
       end
@@ -1908,11 +1926,13 @@
       handle(format("%s [%q]={},",depth,k))
      end
     elseif inline then
-     local st=is_simple_table(v,hexify)
+     local st=is_simple_table(v,hexify,accurate)
      if st then
       if tk=="number" then
        if hexify then
         handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+       elseif accurate then
+        handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
        else
         handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
        end
@@ -1934,6 +1954,8 @@
     if tk=="number" then
      if hexify then
       handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+     elseif accurate then
+      handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
      else
       handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
      end
@@ -1953,6 +1975,8 @@
       if tk=="number" then
        if hexify then
         handle(format("%s [0x%X]=load(%q),",depth,k,f))
+       elseif accurate then
+        handle(format("%s [%q]=load(%q),",depth,k,f))
        else
         handle(format("%s [%s]=load(%q),",depth,k,f))
        end
@@ -1970,6 +1994,8 @@
     if tk=="number" then
      if hexify then
       handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+     elseif accurate then
+      handle(format("%s [%q]=%q,",depth,k,tostring(v)))
      else
       handle(format("%s [%s]=%q,",depth,k,tostring(v)))
      end
@@ -1993,6 +2019,7 @@
  if type(specification)=="table" then
   noquotes=specification.noquotes
   hexify=specification.hexify
+  accurate=specification.accurate
   handle=_handle or specification.handle or print
   functions=specification.functions
   compact=specification.compact
@@ -3399,7 +3426,7 @@
 end
 local d
 function os.timezone(delta)
- d=d or tonumber(tonumber(date("%H")-date("!%H")))
+ d=d or ((tonumber(date("%H")) or 0)-(tonumber(date("!%H")) or 0))
  if delta then
   if d>0 then
    return format("+%02i:00",d)
@@ -3525,6 +3552,12 @@
  end
  return year,month,day
 end
+function os.date(fmt,...)
+ if not fmt then
+  fmt="%Y-%m-%d %H:%M"
+ end
+ return date(fmt,...)
+end
 local osexit=os.exit
 local exitcode=nil
 function os.setexitcode(code)

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic.lua	2020-05-02 21:03:03 UTC (rev 54974)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic.lua	2020-05-02 21:03:20 UTC (rev 54975)
@@ -29,8 +29,8 @@
 
 local lualibs_basic_module = {
   name          = "lualibs-basic",
-  version       = "2.70",       --TAGVERSION
-  date          = "2020-02-02", --TAGDATE
+  version       = "2.71",       --TAGVERSION
+  date          = "2020-05-01", --TAGDATE
   description   = "ConTeXt Lua libraries -- basic collection.",
   author        = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
   copyright     = "PRAGMA ADE / ConTeXt Development Team",

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua	2020-05-02 21:03:03 UTC (rev 54974)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua	2020-05-02 21:03:20 UTC (rev 54975)
@@ -1,6 +1,6 @@
 -- merged file : lualibs-extended-merged.lua
 -- parent file : lualibs-extended.lua
--- merge date  : Sun Feb  2 22:30:49 2020
+-- merge date  : 2020-05-01 15:49
 
 do -- begin closure to overcome local limits and interference
 
@@ -417,9 +417,12 @@
   return format("a%s..utfpadding(a%s,%i)",n,n,-f)
  end
 end
-local format_q=function()
+local format_q=JITSUPPORTED and function()
  n=n+1
  return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
+end or function()
+ n=n+1
+ return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
 end
 local format_Q=function() 
  n=n+1
@@ -1410,92 +1413,160 @@
   } )
  end
 end
-local f_hashed_string=formatters["[%Q]=%Q,"]
-local f_hashed_number=formatters["[%Q]=%s,"]
-local f_hashed_boolean=formatters["[%Q]=%l,"]
-local f_hashed_table=formatters["[%Q]="]
-local f_indexed_string=formatters["[%s]=%Q,"]
-local f_indexed_number=formatters["[%s]=%s,"]
-local f_indexed_boolean=formatters["[%s]=%l,"]
-local f_indexed_table=formatters["[%s]="]
-local f_ordered_string=formatters["%Q,"]
-local f_ordered_number=formatters["%s,"]
-local f_ordered_boolean=formatters["%l,"]
-function table.fastserialize(t,prefix)
- local r={ type(prefix)=="string" and prefix or "return" }
- local m=1
- local function fastserialize(t,outer) 
-  local n=#t
-  m=m+1
-  r[m]="{"
-  if n>0 then
-   local v=t[0]
-   if v then
-    local tv=type(v)
-    if tv=="string" then
-     m=m+1 r[m]=f_indexed_string(0,v)
-    elseif tv=="number" then
-     m=m+1 r[m]=f_indexed_number(0,v)
-    elseif tv=="table" then
-     m=m+1 r[m]=f_indexed_table(0)
-     fastserialize(v)
-    elseif tv=="boolean" then
-     m=m+1 r[m]=f_indexed_boolean(0,v)
+if JITSUPPORTED then
+ local f_hashed_string=formatters["[%Q]=%Q,"]
+ local f_hashed_number=formatters["[%Q]=%s,"]
+ local f_hashed_boolean=formatters["[%Q]=%l,"]
+ local f_hashed_table=formatters["[%Q]="]
+ local f_indexed_string=formatters["[%s]=%Q,"]
+ local f_indexed_number=formatters["[%s]=%s,"]
+ local f_indexed_boolean=formatters["[%s]=%l,"]
+ local f_indexed_table=formatters["[%s]="]
+ local f_ordered_string=formatters["%Q,"]
+ local f_ordered_number=formatters["%s,"]
+ local f_ordered_boolean=formatters["%l,"]
+ function table.fastserialize(t,prefix)
+  local r={ type(prefix)=="string" and prefix or "return" }
+  local m=1
+  local function fastserialize(t,outer) 
+   local n=#t
+   m=m+1
+   r[m]="{"
+   if n>0 then
+    local v=t[0]
+    if v then
+     local tv=type(v)
+     if tv=="string" then
+      m=m+1 r[m]=f_indexed_string(0,v)
+     elseif tv=="number" then
+      m=m+1 r[m]=f_indexed_number(0,v)
+     elseif tv=="table" then
+      m=m+1 r[m]=f_indexed_table(0)
+      fastserialize(v)
+      m=m+1 r[m]=f_indexed_table(0)
+     elseif tv=="boolean" then
+      m=m+1 r[m]=f_indexed_boolean(0,v)
+     end
     end
-   end
-   for i=1,n do
-    local v=t[i]
-    local tv=type(v)
-    if tv=="string" then
-     m=m+1 r[m]=f_ordered_string(v)
-    elseif tv=="number" then
-     m=m+1 r[m]=f_ordered_number(v)
-    elseif tv=="table" then
-     fastserialize(v)
-    elseif tv=="boolean" then
-     m=m+1 r[m]=f_ordered_boolean(v)
+    for i=1,n do
+     local v=t[i]
+     local tv=type(v)
+     if tv=="string" then
+      m=m+1 r[m]=f_ordered_string(v)
+     elseif tv=="number" then
+      m=m+1 r[m]=f_ordered_number(v)
+     elseif tv=="table" then
+      fastserialize(v)
+     elseif tv=="boolean" then
+      m=m+1 r[m]=f_ordered_boolean(v)
+     end
     end
    end
-  end
-  for k,v in next,t do
-   local tk=type(k)
-   if tk=="number" then
-    if k>n or k<0 then
+   for k,v in next,t do
+    local tk=type(k)
+    if tk=="number" then
+     if k>n or k<0 then
+      local tv=type(v)
+      if tv=="string" then
+       m=m+1 r[m]=f_indexed_string(k,v)
+      elseif tv=="number" then
+       m=m+1 r[m]=f_indexed_number(k,v)
+      elseif tv=="table" then
+       m=m+1 r[m]=f_indexed_table(k)
+       fastserialize(v)
+      elseif tv=="boolean" then
+       m=m+1 r[m]=f_indexed_boolean(k,v)
+      end
+     end
+    else
      local tv=type(v)
      if tv=="string" then
-      m=m+1 r[m]=f_indexed_string(k,v)
+      m=m+1 r[m]=f_hashed_string(k,v)
      elseif tv=="number" then
-      m=m+1 r[m]=f_indexed_number(k,v)
+      m=m+1 r[m]=f_hashed_number(k,v)
      elseif tv=="table" then
-      m=m+1 r[m]=f_indexed_table(k)
+      m=m+1 r[m]=f_hashed_table(k)
       fastserialize(v)
      elseif tv=="boolean" then
-      m=m+1 r[m]=f_indexed_boolean(k,v)
+      m=m+1 r[m]=f_hashed_boolean(k,v)
      end
     end
+   end
+   m=m+1
+   if outer then
+    r[m]="}"
    else
-    local tv=type(v)
-    if tv=="string" then
-     m=m+1 r[m]=f_hashed_string(k,v)
-    elseif tv=="number" then
-     m=m+1 r[m]=f_hashed_number(k,v)
-    elseif tv=="table" then
-     m=m+1 r[m]=f_hashed_table(k)
-     fastserialize(v)
-    elseif tv=="boolean" then
-     m=m+1 r[m]=f_hashed_boolean(k,v)
+    r[m]="},"
+   end
+   return r
+  end
+  return concat(fastserialize(t,true))
+ end
+else
+ local f_v=formatters["[%q]=%q,"]
+ local f_t=formatters["[%q]="]
+ local f_q=formatters["%q,"]
+ function table.fastserialize(t,prefix) 
+  local r={ type(prefix)=="string" and prefix or "return" }
+  local m=1
+  local function fastserialize(t,outer) 
+   local n=#t
+   m=m+1
+   r[m]="{"
+   if n>0 then
+    local v=t[0]
+    if v then
+     m=m+1
+     r[m]="[0]='"
+     if type(v)=="table" then
+      fastserialize(v)
+     else
+      r[m]=format("%q,",v)
+     end
     end
+    for i=1,n do
+     local v=t[i]
+     m=m+1
+     if type(v)=="table" then
+      r[m]=format("[%i]=",i)
+      fastserialize(v)
+     else
+      r[m]=format("[%i]=%q,",i,v)
+     end
+    end
    end
+   for k,v in next,t do
+    local tk=type(k)
+    if tk=="number" then
+     if k>n or k<0 then
+      m=m+1
+      if type(v)=="table" then
+       r[m]=format("[%i]=",k)
+       fastserialize(v)
+      else
+       r[m]=format("[%i]=%q,",k,v)
+      end
+     end
+    else
+     m=m+1
+     if type(v)=="table" then
+      r[m]=format("[%q]=",k)
+      fastserialize(v)
+     else
+      r[m]=format("[%q]=%q,",k,v)
+     end
+    end
+   end
+   m=m+1
+   if outer then
+    r[m]="}"
+   else
+    r[m]="},"
+   end
+   return r
   end
-  m=m+1
-  if outer then
-   r[m]="}"
-  else
-   r[m]="},"
-  end
-  return r
+  return concat(fastserialize(t,true))
  end
- return concat(fastserialize(t,true))
 end
 function table.deserialize(str)
  if not str or str=="" then
@@ -1589,27 +1660,27 @@
  return t
 end
 local f_start_key_idx=formatters["%w{"]
-local f_start_key_num=formatters["%w[%s]={"]
+local f_start_key_num=JITSUPPORTED and formatters["%w[%s]={"] or formatters["%w[%q]={"]
 local f_start_key_str=formatters["%w[%q]={"]
 local f_start_key_boo=formatters["%w[%l]={"]
 local f_start_key_nop=formatters["%w{"]
 local f_stop=formatters["%w},"]
-local f_key_num_value_num=formatters["%w[%s]=%s,"]
-local f_key_str_value_num=formatters["%w[%Q]=%s,"]
-local f_key_boo_value_num=formatters["%w[%l]=%s,"]
-local f_key_num_value_str=formatters["%w[%s]=%Q,"]
+local f_key_num_value_num=JITSUPPORTED and formatters["%w[%s]=%s,"] or formatters["%w[%s]=%q,"]
+local f_key_str_value_num=JITSUPPORTED and formatters["%w[%Q]=%s,"] or formatters["%w[%Q]=%q,"]
+local f_key_boo_value_num=JITSUPPORTED and formatters["%w[%l]=%s,"] or formatters["%w[%l]=%q,"]
+local f_key_num_value_str=JITSUPPORTED and formatters["%w[%s]=%Q,"] or formatters["%w[%q]=%Q,"]
 local f_key_str_value_str=formatters["%w[%Q]=%Q,"]
 local f_key_boo_value_str=formatters["%w[%l]=%Q,"]
-local f_key_num_value_boo=formatters["%w[%s]=%l,"]
+local f_key_num_value_boo=JITSUPPORTED and formatters["%w[%s]=%l,"] or formatters["%w[%q]=%l,"]
 local f_key_str_value_boo=formatters["%w[%Q]=%l,"]
 local f_key_boo_value_boo=formatters["%w[%l]=%l,"]
-local f_key_num_value_not=formatters["%w[%s]={},"]
+local f_key_num_value_not=JITSUPPORTED and formatters["%w[%s]={},"] or formatters["%w[%q]={},"]
 local f_key_str_value_not=formatters["%w[%Q]={},"]
 local f_key_boo_value_not=formatters["%w[%l]={},"]
-local f_key_num_value_seq=formatters["%w[%s]={ %, t },"]
+local f_key_num_value_seq=JITSUPPORTED and formatters["%w[%s]={ %, t },"] or formatters["%w[%q]={ %, t },"]
 local f_key_str_value_seq=formatters["%w[%Q]={ %, t },"]
 local f_key_boo_value_seq=formatters["%w[%l]={ %, t },"]
-local f_val_num=formatters["%w%s,"]
+local f_val_num=JITSUPPORTED and formatters["%w%s,"] or formatters["%w%q,"]
 local f_val_str=formatters["%w%Q,"]
 local f_val_boo=formatters["%w%l,"]
 local f_val_not=formatters["%w{},"]
@@ -3178,6 +3249,37 @@
 end
 local ticks=clock
 local seconds=function(n) return n or 0 end
+if os.type~="windows" then
+elseif lua.getpreciseticks then
+ ticks=lua.getpreciseticks
+ seconds=lua.getpreciseseconds
+elseif FFISUPPORTED then
+ local okay,kernel=pcall(ffi.load,"kernel32")
+ if kernel then
+  local tonumber=ffi.number or tonumber
+  ffi.cdef[[
+            int QueryPerformanceFrequency(int64_t *lpFrequency);
+            int QueryPerformanceCounter(int64_t *lpPerformanceCount);
+        ]]
+  local target=ffi.new("__int64[1]")
+  ticks=function()
+   if kernel.QueryPerformanceCounter(target)==1 then
+    return tonumber(target[0])
+   else
+    return 0
+   end
+  end
+  local target=ffi.new("__int64[1]")
+  seconds=function(ticks)
+   if kernel.QueryPerformanceFrequency(target)==1 then
+    return ticks/tonumber(target[0])
+   else
+    return 0
+   end
+  end
+ end
+else
+end
 local function starttiming(instance,reset)
  local timer=timers[instance or "notimer"]
  local it=timer.timing
@@ -3289,12 +3391,12 @@
   end)
   if LUATEXENGINE=="luametatex" then
    register("used engine",function()
-    return format("%s version %s, functionality level %s, format id %s",
-     LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,LUATEXFORMATID)
+    return format("%s version: %s, functionality level: %s, format id: %s, compiler: %s",
+     LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,LUATEXFORMATID,status.used_compiler)
    end)
   else
    register("used engine",function()
-    return format("%s version %s with functionality level %s, banner: %s",
+    return format("%s version: %s, functionality level: %s, banner: %s",
      LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
    end)
   end
@@ -3302,7 +3404,7 @@
    return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
   end)
   register("callbacks",statistics.callbacks)
-  if TEXENGINE=="luajittex" and JITSUPPORTED then
+  if JITSUPPORTED then
    local jitstatus=jit.status
    if jitstatus then
     local jitstatus={ jitstatus() }
@@ -3336,7 +3438,7 @@
 end
 function statistics.memused() 
  local round=math.round or math.floor
- return format("%s MB, ctx: %s MB, max: %s MB)",
+ return format("%s MB, ctx: %s MB, max: %s MB",
   round(collectgarbage("count")/1000),
   round(status.luastate_bytes/1000000),
   status.luastate_bytes_max and round(status.luastate_bytes_max/1000000) or "unknown"

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended.lua	2020-05-02 21:03:03 UTC (rev 54974)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended.lua	2020-05-02 21:03:20 UTC (rev 54975)
@@ -30,8 +30,8 @@
 
 local lualibs_extended_module = {
   name          = "lualibs-extended",
-  version       = "2.70",       --TAGVERSION
-  date          = "2020-02-02", --TAGDATE
+  version       = "2.71",       --TAGVERSION
+  date          = "2020-05-01", --TAGDATE
   description   = "ConTeXt Lua libraries -- extended collection.",
   author        = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
   copyright     = "PRAGMA ADE / ConTeXt Development Team",

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-os.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-os.lua	2020-05-02 21:03:03 UTC (rev 54974)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-os.lua	2020-05-02 21:03:20 UTC (rev 54975)
@@ -459,7 +459,7 @@
 local d
 
 function os.timezone(delta)
-    d = d or tonumber(tonumber(date("%H")-date("!%H")))
+    d = d or ((tonumber(date("%H")) or 0) - (tonumber(date("!%H")) or 0))
     if delta then
         if d > 0 then
             return format("+%02i:00",d)
@@ -637,6 +637,14 @@
     return year, month, day
 end
 
+function os.date(fmt,...)
+    if not fmt then
+        -- otherwise differences between unix, mingw and msvc
+        fmt = "%Y-%m-%d %H:%M"
+    end
+    return date(fmt,...)
+end
+
 local osexit   = os.exit
 local exitcode = nil
 

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-table.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-table.lua	2020-05-02 21:03:03 UTC (rev 54974)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-table.lua	2020-05-02 21:03:20 UTC (rev 54975)
@@ -525,84 +525,15 @@
     return hsh
 end
 
-local noquotes, hexify, handle, compact, inline, functions, metacheck
+local noquotes, hexify, handle, compact, inline, functions, metacheck, accurate
 
 local reserved = table.tohash { -- intercept a language inconvenience: no reserved words as key
     'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', 'function', 'if',
     'in', 'local', 'nil', 'not', 'or', 'repeat', 'return', 'then', 'true', 'until', 'while',
-    'NaN', 'goto',
+    'NaN', 'goto', 'const',
 }
 
--- local function is_simple_table(t)
---     if #t > 0 then
---         local n = 0
---         for _,v in next, t do
---             n = n + 1
---         end
---         if n == #t then
---             local tt, nt = { }, 0
---             for i=1,#t do
---                 local v = t[i]
---                 local tv = type(v)
---                 if tv == "number" then
---                     nt = nt + 1
---                     if hexify then
---                         tt[nt] = format("0x%X",v)
---                     else
---                         tt[nt] = tostring(v) -- tostring not needed
---                     end
---                 elseif tv == "string" then
---                     nt = nt + 1
---                     tt[nt] = format("%q",v)
---                 elseif tv == "boolean" then
---                     nt = nt + 1
---                     tt[nt] = v and "true" or "false"
---                 else
---                     return nil
---                 end
---             end
---             return tt
---         end
---     end
---     return nil
--- end
-
--- local function is_simple_table(t)
---     local nt = #t
---     if nt > 0 then
---         local n = 0
---         for _,v in next, t do
---             n = n + 1
---          -- if type(v) == "table" then
---          --     return nil
---          -- end
---         end
---         if n == nt then
---             local tt = { }
---             for i=1,nt do
---                 local v = t[i]
---                 local tv = type(v)
---                 if tv == "number" then
---                     if hexify then
---                         tt[i] = format("0x%X",v)
---                     else
---                         tt[i] = tostring(v) -- tostring not needed
---                     end
---                 elseif tv == "string" then
---                     tt[i] = format("%q",v)
---                 elseif tv == "boolean" then
---                     tt[i] = v and "true" or "false"
---                 else
---                     return nil
---                 end
---             end
---             return tt
---         end
---     end
---     return nil
--- end
-
-local function is_simple_table(t,hexify) -- also used in util-tab so maybe public
+local function is_simple_table(t,hexify,accurate) -- also used in util-tab so maybe public
     local nt = #t
     if nt > 0 then
         local n = 0
@@ -623,6 +554,8 @@
                  -- tt[i] = v -- not needed tostring(v)
                     if hexify then
                         tt[i] = format("0x%X",v)
+                    elseif accurate then
+                        tt[i] = format("%q",v)
                     else
                         tt[i] = v -- not needed tostring(v)
                     end
@@ -644,6 +577,8 @@
                  -- tt[i+1] = v -- not needed tostring(v)
                     if hexify then
                         tt[i+1] = format("0x%X",v)
+                    elseif accurate then
+                        tt[i+1] = format("%q",v)
                     else
                         tt[i+1] = v -- not needed tostring(v)
                     end
@@ -738,6 +673,8 @@
                 if tv == "number" then
                     if hexify then
                         handle(format("%s 0x%X,",depth,v))
+                    elseif accurate then
+                        handle(format("%s %q,",depth,v))
                     else
                         handle(format("%s %s,",depth,v)) -- %.99g
                     end
@@ -747,7 +684,7 @@
                     if next(v) == nil then
                         handle(format("%s {},",depth))
                     elseif inline then -- and #t > 0
-                        local st = is_simple_table(v,hexify)
+                        local st = is_simple_table(v,hexify,accurate)
                         if st then
                             handle(format("%s { %s },",depth,concat(st,", ")))
                         else
@@ -775,6 +712,8 @@
                 if tk == "number" then
                     if hexify then
                         handle(format("%s [0x%X]=0x%X,",depth,k,v))
+                    elseif accurate then
+                        handle(format("%s [%s]=%q,",depth,k,v))
                     else
                         handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g
                     end
@@ -781,6 +720,8 @@
                 elseif tk == "boolean" then
                     if hexify then
                         handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+                    elseif accurate then
+                        handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
                     else
                         handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) -- %.99g
                     end
@@ -789,6 +730,8 @@
                 elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
                     if hexify then
                         handle(format("%s %s=0x%X,",depth,k,v))
+                    elseif accurate then
+                        handle(format("%s %s=%q,",depth,k,v))
                     else
                         handle(format("%s %s=%s,",depth,k,v)) -- %.99g
                     end
@@ -795,6 +738,8 @@
                 else
                     if hexify then
                         handle(format("%s [%q]=0x%X,",depth,k,v))
+                    elseif accurate then
+                        handle(format("%s [%q]=%q,",depth,k,v))
                     else
                         handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
                     end
@@ -803,6 +748,8 @@
                 if tk == "number" then
                     if hexify then
                         handle(format("%s [0x%X]=%q,",depth,k,v))
+                    elseif accurate then
+                        handle(format("%s [%q]=%q,",depth,k,v))
                     else
                         handle(format("%s [%s]=%q,",depth,k,v))
                     end
@@ -820,6 +767,8 @@
                     if tk == "number" then
                         if hexify then
                             handle(format("%s [0x%X]={},",depth,k))
+                        elseif accurate then
+                            handle(format("%s [%q]={},",depth,k))
                         else
                             handle(format("%s [%s]={},",depth,k))
                         end
@@ -833,11 +782,13 @@
                         handle(format("%s [%q]={},",depth,k))
                     end
                 elseif inline then
-                    local st = is_simple_table(v,hexify)
+                    local st = is_simple_table(v,hexify,accurate)
                     if st then
                         if tk == "number" then
                             if hexify then
                                 handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+                            elseif accurate then
+                                handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
                             else
                                 handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
                             end
@@ -860,6 +811,8 @@
                 if tk == "number" then
                     if hexify then
                         handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+                    elseif accurate then
+                        handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
                     else
                         handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
                     end
@@ -881,6 +834,8 @@
                         if tk == "number" then
                             if hexify then
                                 handle(format("%s [0x%X]=load(%q),",depth,k,f))
+                            elseif accurate then
+                                handle(format("%s [%q]=load(%q),",depth,k,f))
                             else
                                 handle(format("%s [%s]=load(%q),",depth,k,f))
                             end
@@ -899,6 +854,8 @@
                 if tk == "number" then
                     if hexify then
                         handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+                    elseif accurate then
+                        handle(format("%s [%q]=%q,",depth,k,tostring(v)))
                     else
                         handle(format("%s [%s]=%q,",depth,k,tostring(v)))
                     end
@@ -927,6 +884,7 @@
     if type(specification) == "table" then
         noquotes  = specification.noquotes
         hexify    = specification.hexify
+        accurate  = specification.accurate
         handle    = _handle or specification.handle or print
         functions = specification.functions
         compact   = specification.compact

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-trac-inf.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-trac-inf.lua	2020-05-02 21:03:03 UTC (rev 54974)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-trac-inf.lua	2020-05-02 21:03:20 UTC (rev 54975)
@@ -45,43 +45,60 @@
 local ticks   = clock
 local seconds = function(n) return n or 0 end
 
--- if FFISUPPORTED and ffi and os.type == "windows" then
---
---     local okay, kernel = pcall(ffi.load,"kernel32")
---
---     if kernel then
---
---         local tonumber = ffi.number or tonumber
---
---         ffi.cdef[[
---             int QueryPerformanceFrequency(int64_t *lpFrequency);
---             int QueryPerformanceCounter(int64_t *lpPerformanceCount);
---         ]]
---
---         local target = ffi.new("__int64[1]")
---
---         ticks = function()
---             if kernel.QueryPerformanceCounter(target) == 1 then
---                 return tonumber(target[0])
---             else
---                 return 0
---             end
---         end
---
---         local target = ffi.new("__int64[1]")
---
---         seconds = function(ticks)
---             if kernel.QueryPerformanceFrequency(target) == 1 then
---                 return ticks / tonumber(target[0])
---             else
---                 return 0
---             end
---         end
---
---     end
---
--- end
+if os.type ~= "windows" then
 
+    -- doesn't work well yet on unix (system time vs process time so a mtxrun
+    -- timing with nested call gives the wrong result)
+
+elseif lua.getpreciseticks then
+
+    ticks   = lua.getpreciseticks
+    seconds = lua.getpreciseseconds
+
+elseif FFISUPPORTED then
+
+    -- Do we really care when not in luametatex? For now we do, so:
+
+    local okay, kernel = pcall(ffi.load,"kernel32")
+
+    if kernel then
+
+        local tonumber = ffi.number or tonumber
+
+        ffi.cdef[[
+            int QueryPerformanceFrequency(int64_t *lpFrequency);
+            int QueryPerformanceCounter(int64_t *lpPerformanceCount);
+        ]]
+
+        local target = ffi.new("__int64[1]")
+
+        ticks = function()
+            if kernel.QueryPerformanceCounter(target) == 1 then
+                return tonumber(target[0])
+            else
+                return 0
+            end
+        end
+
+        local target = ffi.new("__int64[1]")
+
+        seconds = function(ticks)
+            if kernel.QueryPerformanceFrequency(target) == 1 then
+                return ticks / tonumber(target[0])
+            else
+                return 0
+            end
+        end
+
+    end
+
+else
+
+    -- excessive timing costs some 1-2 percent runtime
+
+end
+
+
 local function starttiming(instance,reset)
     local timer = timers[instance or "notimer"]
     local it = timer.timing
@@ -211,12 +228,12 @@
      -- end)
         if LUATEXENGINE == "luametatex" then
             register("used engine", function()
-                return format("%s version %s, functionality level %s, format id %s",
-                    LUATEXENGINE, LUATEXVERSION, LUATEXFUNCTIONALITY, LUATEXFORMATID)
+                return format("%s version: %s, functionality level: %s, format id: %s, compiler: %s",
+                    LUATEXENGINE, LUATEXVERSION, LUATEXFUNCTIONALITY, LUATEXFORMATID, status.used_compiler)
             end)
         else
             register("used engine", function()
-                return format("%s version %s with functionality level %s, banner: %s",
+                return format("%s version: %s, functionality level: %s, banner: %s",
                     LUATEXENGINE, LUATEXVERSION, LUATEXFUNCTIONALITY, lower(status.banner))
             end)
         end
@@ -224,7 +241,7 @@
             return format("%s of %s + %s", status.cs_count, status.hash_size,status.hash_extra)
         end)
         register("callbacks", statistics.callbacks)
-        if TEXENGINE == "luajittex" and JITSUPPORTED then
+        if JITSUPPORTED then
             local jitstatus = jit.status
             if jitstatus then
                 local jitstatus = { jitstatus() }
@@ -262,7 +279,7 @@
 
 function statistics.memused() -- no math.round yet -)
     local round = math.round or math.floor
-    return format("%s MB, ctx: %s MB, max: %s MB)",
+    return format("%s MB, ctx: %s MB, max: %s MB",
         round(collectgarbage("count")/1000),
         round(status.luastate_bytes/1000000),
         status.luastate_bytes_max and round(status.luastate_bytes_max/1000000) or "unknown"

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua	2020-05-02 21:03:03 UTC (rev 54974)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua	2020-05-02 21:03:20 UTC (rev 54975)
@@ -701,14 +701,18 @@
     end
 end
 
-local format_q = function()
+local format_q = JITSUPPORTED and function()
     n = n + 1
     -- lua 5.3 has a different q than lua 5.2 (which does a tostring on numbers)
  -- return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
     return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
  -- return format("(a%s ~= nil and escapedquotes(tostring(a%s)) or '')",n,n)
+end or function()
+    n = n + 1
+    return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
 end
 
+
 local format_Q = function() -- fast escaping
     n = n + 1
 --  return format("format('%%q',tostring(a%s))",n)
@@ -1269,7 +1273,6 @@
             f = function() return str end
         end
     end
- -- if jit then jit.on(f,true) end
     t[str] = f
     return f
 end

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-tab.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-tab.lua	2020-05-02 21:03:03 UTC (rev 54974)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-tab.lua	2020-05-02 21:03:20 UTC (rev 54975)
@@ -314,102 +314,177 @@
 -- best keep [%q] keys (as we have some in older applications i.e. saving user data (otherwise
 -- we also need to check for reserved words)
 
-local f_hashed_string   = formatters["[%Q]=%Q,"]
-local f_hashed_number   = formatters["[%Q]=%s,"]
-local f_hashed_boolean  = formatters["[%Q]=%l,"]
-local f_hashed_table    = formatters["[%Q]="]
+if JITSUPPORTED then
 
-local f_indexed_string  = formatters["[%s]=%Q,"]
-local f_indexed_number  = formatters["[%s]=%s,"]
-local f_indexed_boolean = formatters["[%s]=%l,"]
-local f_indexed_table   = formatters["[%s]="]
+    local f_hashed_string   = formatters["[%Q]=%Q,"]
+    local f_hashed_number   = formatters["[%Q]=%s,"]
+    local f_hashed_boolean  = formatters["[%Q]=%l,"]
+    local f_hashed_table    = formatters["[%Q]="]
 
-local f_ordered_string  = formatters["%Q,"]
-local f_ordered_number  = formatters["%s,"]
-local f_ordered_boolean = formatters["%l,"]
+    local f_indexed_string  = formatters["[%s]=%Q,"]
+    local f_indexed_number  = formatters["[%s]=%s,"]
+    local f_indexed_boolean = formatters["[%s]=%l,"]
+    local f_indexed_table   = formatters["[%s]="]
 
-function table.fastserialize(t,prefix) -- todo, move local function out
+    local f_ordered_string  = formatters["%Q,"]
+    local f_ordered_number  = formatters["%s,"]
+    local f_ordered_boolean = formatters["%l,"]
 
-    -- prefix should contain the =
-    -- not sorted
-    -- only number and string indices (currently)
+    function table.fastserialize(t,prefix) -- todo, move local function out
 
-    local r = { type(prefix) == "string" and prefix or "return" }
-    local m = 1
-    local function fastserialize(t,outer) -- no mixes
-        local n = #t
-        m = m + 1
-        r[m] = "{"
-        if n > 0 then
-            local v = t[0]
-            if v then
-                local tv = type(v)
-                if tv == "string" then
-                    m = m + 1 r[m] = f_indexed_string(0,v)
-                elseif tv == "number" then
-                    m = m + 1 r[m] = f_indexed_number(0,v)
-                elseif tv == "table" then
-                    m = m + 1 r[m] = f_indexed_table(0)
-                    fastserialize(v)
-                elseif tv == "boolean" then
-                    m = m + 1 r[m] = f_indexed_boolean(0,v)
+        -- prefix should contain the =
+        -- not sorted
+        -- only number and string indices (currently)
+
+        local r = { type(prefix) == "string" and prefix or "return" }
+        local m = 1
+        local function fastserialize(t,outer) -- no mixes
+            local n = #t
+            m = m + 1
+            r[m] = "{"
+            if n > 0 then
+                local v = t[0]
+                if v then
+                    local tv = type(v)
+                    if tv == "string" then
+                        m = m + 1 r[m] = f_indexed_string(0,v)
+                    elseif tv == "number" then
+                        m = m + 1 r[m] = f_indexed_number(0,v)
+                    elseif tv == "table" then
+                        m = m + 1 r[m] = f_indexed_table(0)
+                        fastserialize(v)
+                        m = m + 1 r[m] = f_indexed_table(0)
+                    elseif tv == "boolean" then
+                        m = m + 1 r[m] = f_indexed_boolean(0,v)
+                    end
                 end
-            end
-            for i=1,n do
-                local v  = t[i]
-                local tv = type(v)
-                if tv == "string" then
-                    m = m + 1 r[m] = f_ordered_string(v)
-                elseif tv == "number" then
-                    m = m + 1 r[m] = f_ordered_number(v)
-                elseif tv == "table" then
-                    fastserialize(v)
-                elseif tv == "boolean" then
-                    m = m + 1 r[m] = f_ordered_boolean(v)
+                for i=1,n do
+                    local v  = t[i]
+                    local tv = type(v)
+                    if tv == "string" then
+                        m = m + 1 r[m] = f_ordered_string(v)
+                    elseif tv == "number" then
+                        m = m + 1 r[m] = f_ordered_number(v)
+                    elseif tv == "table" then
+                        fastserialize(v)
+                    elseif tv == "boolean" then
+                        m = m + 1 r[m] = f_ordered_boolean(v)
+                    end
                 end
             end
-        end
-        -- hm, can't we avoid this ... lua should have a way to check if there
-        -- is a hash part
-        for k, v in next, t do
-            local tk = type(k)
-            if tk == "number" then
-                if k > n or k < 0 then
+            -- hm, can't we avoid this ... lua should have a way to check if there
+            -- is a hash part
+            for k, v in next, t do
+                local tk = type(k)
+                if tk == "number" then
+                    if k > n or k < 0 then
+                        local tv = type(v)
+                        if tv == "string" then
+                            m = m + 1 r[m] = f_indexed_string(k,v)
+                        elseif tv == "number" then
+                            m = m + 1 r[m] = f_indexed_number(k,v)
+                        elseif tv == "table" then
+                            m = m + 1 r[m] = f_indexed_table(k)
+                            fastserialize(v)
+                        elseif tv == "boolean" then
+                            m = m + 1 r[m] = f_indexed_boolean(k,v)
+                        end
+                    end
+                else
                     local tv = type(v)
                     if tv == "string" then
-                        m = m + 1 r[m] = f_indexed_string(k,v)
+                        m = m + 1 r[m] = f_hashed_string(k,v)
                     elseif tv == "number" then
-                        m = m + 1 r[m] = f_indexed_number(k,v)
+                        m = m + 1 r[m] = f_hashed_number(k,v)
                     elseif tv == "table" then
-                        m = m + 1 r[m] = f_indexed_table(k)
+                        m = m + 1 r[m] = f_hashed_table(k)
                         fastserialize(v)
                     elseif tv == "boolean" then
-                        m = m + 1 r[m] = f_indexed_boolean(k,v)
+                        m = m + 1 r[m] = f_hashed_boolean(k,v)
                     end
                 end
+            end
+            m = m + 1
+            if outer then
+                r[m] = "}"
             else
-                local tv = type(v)
-                if tv == "string" then
-                    m = m + 1 r[m] = f_hashed_string(k,v)
-                elseif tv == "number" then
-                    m = m + 1 r[m] = f_hashed_number(k,v)
-                elseif tv == "table" then
-                    m = m + 1 r[m] = f_hashed_table(k)
-                    fastserialize(v)
-                elseif tv == "boolean" then
-                    m = m + 1 r[m] = f_hashed_boolean(k,v)
+                r[m] = "},"
+            end
+            return r
+        end
+        return concat(fastserialize(t,true))
+    end
+
+else
+
+    local f_v = formatters["[%q]=%q,"]
+    local f_t = formatters["[%q]="]
+    local f_q = formatters["%q,"]
+
+    function table.fastserialize(t,prefix) -- todo, move local function out
+        local r = { type(prefix) == "string" and prefix or "return" }
+        local m = 1
+        local function fastserialize(t,outer) -- no mixes
+            local n = #t
+            m = m + 1
+            r[m] = "{"
+            if n > 0 then
+                local v = t[0]
+                if v then
+                    m = m + 1
+                    r[m] = "[0]='"
+                    if type(v) == "table" then
+                        fastserialize(v)
+                    else
+                        r[m] = format("%q,",v)
+                    end
                 end
+                for i=1,n do
+                    local v = t[i]
+                    m = m + 1
+                    if type(v) == "table" then
+                        r[m] = format("[%i]=",i)
+                        fastserialize(v)
+                    else
+                        r[m] = format("[%i]=%q,",i,v)
+                    end
+                end
             end
+            -- hm, can't we avoid this ... lua should have a way to check if there
+            -- is a hash part
+            for k, v in next, t do
+                local tk = type(k)
+                if tk == "number" then
+                    if k > n or k < 0 then
+                        m = m + 1
+                        if type(v) == "table" then
+                            r[m] = format("[%i]=",k)
+                            fastserialize(v)
+                        else
+                            r[m] = format("[%i]=%q,",k,v)
+                        end
+                    end
+                else
+                    m = m + 1
+                    if type(v) == "table" then
+                        r[m] = format("[%q]=",k)
+                        fastserialize(v)
+                    else
+                        r[m] = format("[%q]=%q,",k,v)
+                    end
+                end
+            end
+            m = m + 1
+            if outer then
+                r[m] = "}"
+            else
+                r[m] = "},"
+            end
+            return r
         end
-        m = m + 1
-        if outer then
-            r[m] = "}"
-        else
-            r[m] = "},"
-        end
-        return r
+        return concat(fastserialize(t,true))
     end
-    return concat(fastserialize(t,true))
+
 end
 
 function table.deserialize(str)
@@ -533,7 +608,7 @@
 -- husayni.tma  : 0.28 -> 0.19
 
 local f_start_key_idx     = formatters["%w{"]
-local f_start_key_num     = formatters["%w[%s]={"]
+local f_start_key_num     = JITSUPPORTED and formatters["%w[%s]={"] or formatters["%w[%q]={"]
 local f_start_key_str     = formatters["%w[%q]={"]
 local f_start_key_boo     = formatters["%w[%l]={"]
 local f_start_key_nop     = formatters["%w{"]
@@ -540,27 +615,27 @@
 
 local f_stop              = formatters["%w},"]
 
-local f_key_num_value_num = formatters["%w[%s]=%s,"]
-local f_key_str_value_num = formatters["%w[%Q]=%s,"]
-local f_key_boo_value_num = formatters["%w[%l]=%s,"]
+local f_key_num_value_num = JITSUPPORTED and formatters["%w[%s]=%s,"] or formatters["%w[%s]=%q,"]
+local f_key_str_value_num = JITSUPPORTED and formatters["%w[%Q]=%s,"] or formatters["%w[%Q]=%q,"]
+local f_key_boo_value_num = JITSUPPORTED and formatters["%w[%l]=%s,"] or formatters["%w[%l]=%q,"]
 
-local f_key_num_value_str = formatters["%w[%s]=%Q,"]
+local f_key_num_value_str = JITSUPPORTED and formatters["%w[%s]=%Q,"] or formatters["%w[%q]=%Q,"]
 local f_key_str_value_str = formatters["%w[%Q]=%Q,"]
 local f_key_boo_value_str = formatters["%w[%l]=%Q,"]
 
-local f_key_num_value_boo = formatters["%w[%s]=%l,"]
+local f_key_num_value_boo = JITSUPPORTED and formatters["%w[%s]=%l,"] or formatters["%w[%q]=%l,"]
 local f_key_str_value_boo = formatters["%w[%Q]=%l,"]
 local f_key_boo_value_boo = formatters["%w[%l]=%l,"]
 
-local f_key_num_value_not = formatters["%w[%s]={},"]
+local f_key_num_value_not = JITSUPPORTED and formatters["%w[%s]={},"] or formatters["%w[%q]={},"]
 local f_key_str_value_not = formatters["%w[%Q]={},"]
 local f_key_boo_value_not = formatters["%w[%l]={},"]
 
-local f_key_num_value_seq = formatters["%w[%s]={ %, t },"]
+local f_key_num_value_seq = JITSUPPORTED and formatters["%w[%s]={ %, t },"] or formatters["%w[%q]={ %, t },"]
 local f_key_str_value_seq = formatters["%w[%Q]={ %, t },"]
 local f_key_boo_value_seq = formatters["%w[%l]={ %, t },"]
 
-local f_val_num           = formatters["%w%s,"]
+local f_val_num           = JITSUPPORTED and formatters["%w%s,"] or formatters["%w%q,"]
 local f_val_str           = formatters["%w%Q,"]
 local f_val_boo           = formatters["%w%l,"]
 local f_val_not           = formatters["%w{},"]
@@ -573,8 +648,6 @@
 local f_table_entry       = formatters["[%Q]={"]
 local f_table_finish      = formatters["}"]
 
------ f_string            = formatters["%q"]
-
 local spaces = utilities.strings.newrepeater(" ")
 
 local original_serialize = table.serialize -- the extensive one, the one we started with

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs.lua	2020-05-02 21:03:03 UTC (rev 54974)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs.lua	2020-05-02 21:03:20 UTC (rev 54975)
@@ -25,8 +25,8 @@
 
 lualibs.module_info = {
   name          = "lualibs",
-  version       = "2.70",       --TAGVERSION
-    date        = "2020-02-02", --TAGDATE
+  version       = "2.71",       --TAGVERSION
+    date        = "2020-05-01", --TAGDATE
   description   = "ConTeXt Lua standard libraries.",
   author        = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
   copyright     = "PRAGMA ADE / ConTeXt Development Team",



More information about the tex-live-commits mailing list.