[latex3-commits] [l3svn] 06/06: Experimental file hash/mod-date/size functions

noreply at latex-project.org noreply at latex-project.org
Sun Jul 9 20:06:49 CEST 2017


This is an automated email from the git hooks/post-receive script.

joseph pushed a commit to branch master
in repository l3svn.

commit 335d21bd058a73c6e08b74b4a7e9d025aa5b303d
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date:   Sun Jul 9 18:57:31 2017 +0100

    Experimental file hash/mod-date/size functions
    
    These are essentially thin wrappers around primitives, with
    approrpiate emulation taken from pdftexcmds for LuaTeX.
    
    The slightly odd test for mod date here is due to the test set up:
    we copy the test files to a 'clean' location so the timestamp
    is not predictable.
---
 l3kernel/l3candidates.dtx               |  107 +++++++++++++++++++++-
 l3kernel/l3luatex.dtx                   |  149 +++++++++++++++++++++++++++++++
 l3kernel/l3names.dtx                    |    4 +
 l3kernel/testfiles/m3expl001.luatex.tlg |    5 ++
 l3kernel/testfiles/m3expl001.ptex.tlg   |    5 ++
 l3kernel/testfiles/m3expl001.tlg        |    5 ++
 l3kernel/testfiles/m3expl001.uptex.tlg  |    5 ++
 l3kernel/testfiles/m3expl001.xetex.tlg  |    5 ++
 l3kernel/testfiles/m3expl003.luatex.tlg |    5 ++
 l3kernel/testfiles/m3expl003.ptex.tlg   |    5 ++
 l3kernel/testfiles/m3expl003.tlg        |    5 ++
 l3kernel/testfiles/m3expl003.uptex.tlg  |    5 ++
 l3kernel/testfiles/m3expl003.xetex.tlg  |    5 ++
 l3kernel/testfiles/m3file001.lvt        |   20 +++++
 l3kernel/testfiles/m3file001.ptex.tlg   |   27 ++++++
 l3kernel/testfiles/m3file001.tlg        |   27 ++++++
 l3kernel/testfiles/m3file001.uptex.tlg  |   27 ++++++
 l3kernel/testfiles/m3file001.xetex.tlg  |   87 ++++++++++++++++++
 18 files changed, 497 insertions(+), 1 deletion(-)

diff --git a/l3kernel/l3candidates.dtx b/l3kernel/l3candidates.dtx
index 81101ec..d67116b 100644
--- a/l3kernel/l3candidates.dtx
+++ b/l3kernel/l3candidates.dtx
@@ -206,6 +206,40 @@
 %
 % \section{Additions to \pkg{l3file}}
 %
+% \begin{function}[added = 2017-07-09]{\file_get_hash:nN}
+%   \begin{syntax}
+%     \cs{file_get_hash:nN} \Arg{file name} \meta{str var}
+%   \end{syntax}
+%   Searches for \meta{file name} using the current \TeX{} search
+%   path and the additional paths controlled by \cs{file_path_include:n}.
+%   If found, sets the \meta{str var} to the MD5 sum generated from the
+%   content of the file.
+%   Where the file is not found, the \meta{str var} will be empty.
+% \end{function}
+%
+% \begin{function}[added = 2017-07-09]{\file_get_size:nN}
+%   \begin{syntax}
+%     \cs{file_get_size:nN} \Arg{file name} \meta{str var}
+%   \end{syntax}
+%   Searches for \meta{file name} using the current \TeX{} search
+%   path and the additional paths controlled by \cs{file_path_include:n}.
+%   If found, sets the \meta{str var} to the size of the file in bytes.
+%   Where the file is not found, the \meta{str var} will be empty.
+% \end{function}
+%
+% \begin{function}[added = 2017-07-09]{\file_get_timestamp:nN}
+%   \begin{syntax}
+%     \cs{file_get_timestamp:nN} \Arg{file name} \meta{str var}
+%   \end{syntax}
+%   Searches for \meta{file name} using the current \TeX{} search
+%   path and the additional paths controlled by \cs{file_path_include:n}.
+%   If found, sets the \meta{str var} to the modification timestamp of
+%   the file in the form D:|\meta{year}\meta{month}\meta{day}\meta{hour}^^A
+%   \meta{minute}\meta{second}\meta{offset}, where the latter may be |Z|
+%   (UTC) or \meta{plus-minus}\meta{hours}|'|\meta{minutes}|'|.
+%   Where the file is not found, the \meta{str var} will be empty.
+% \end{function}
+%
 % \begin{function}[TF, added = 2014-07-02]{\file_if_exist_input:n}
 %   \begin{syntax}
 %     \cs{file_if_exist_input:n} \Arg{file name}
@@ -213,7 +247,7 @@
 %   \end{syntax}
 %   Searches for \meta{file name} using the current \TeX{} search
 %   path and the additional paths controlled by
-%   \cs{file_path_include:n}). If found, inserts the \meta{true code} then
+%   \cs{file_path_include:n}. If found, inserts the \meta{true code} then
 %   reads in the file as additional \LaTeX{} source as described for
 %   \cs{file_input:n}. Note that \cs{file_if_exist_input:n} does not raise
 %   an error if the file is not found, in contrast to \cs{file_input:n}.
@@ -1521,6 +1555,77 @@
 %<@@=file>
 %    \end{macrocode}
 %
+% \begin{macro}{\file_get_hash:nN, \file_get_size:nN, \file_get_timestamp:nN, }
+% \begin{macro}[aux]{\@@_get_details:nnN}
+%   These are all wrappers around the \pdfTeX{} primitives doing the same
+%   jobs: as we want consistent file paths to be found, they are all set up
+%   using \cs{file_get_full_name:nN} and so are non-expandable \texttt{get}
+%   functions. Much of the code is repetitive but we need to branch for
+%   \LuaTeX{} (emulation in Lua), for the slightly different syntax
+%   needed for \tn{pdftex_mdfivesum:D} and for the fact that primitive
+%   coverage varies in other engines.
+%    \begin{macrocode}
+\cs_new_protected:Npn \file_get_hash:nN #1#2
+  { \@@_get_details:nnN {#1} { mdfivesum } {#2} }
+\cs_new_protected:Npn \file_get_size:nN #1#2
+  { \@@_get_details:nnN {#1} { size } {#2} }
+\cs_new_protected:Npn \file_get_timestamp:nN #1#2
+  { \@@_get_details:nnN {#1} { moddate } {#2} }
+\cs_new_protected:Npn \@@_get_details:nnN #1#2#3
+  {
+    \file_get_full_name:nN {#1} \l_@@_full_name_str
+    \str_set:Nx #3
+      {
+        \use:c { pdftex_file #2 :D } \exp_after:wN
+          { \l_@@_full_name_str }
+      }
+  }
+\cs_if_exist:NTF \luatex_directlua:D
+  {
+    \cs_set_protected:Npn \@@_get_details:nnN #1#2#3
+      {
+        \file_get_full_name:nN {#1} \l_@@_full_name_str
+        \str_set:Nx #3
+          {
+            \lua_now_x:n
+              {
+                l3kernel.file#2
+                  ( " \lua_escape_x:n { \l_@@_full_name_str } " )
+              }
+          }
+       }
+  }
+  {
+    \cs_set_protected:Npn \file_get_hash:nN #1#2
+      {
+        \file_get_full_name:nN {#1} \l_@@_full_name_str
+        \tl_set:Nx #2
+          {
+            \pdftex_mdfivesum:D file \exp_after:wN
+              { \l_@@_full_name_str }
+          }
+      }
+    \cs_if_exist:NT \xetex_XeTeXversion:D
+      {
+        \cs_set_protected:Npn \@@_get_details:nnN #1#2#3
+          {
+            \tl_clear:N #3
+            \__msg_kernel_error:nnx
+              { kernel } { xetex-primitive-not-available }
+              { \exp_not:c { pdffile #2 } }
+          }
+      }
+  }
+\__msg_kernel_new:nnnn { kernel } { xetex-primitive-not-available }
+  { Primitive~\token_to_str:N #1 not~available }
+  {
+    XeTeX~does~not~currently~provide~functionality~equivalent~to~the~
+    \token_to_str:N #1 primitive.
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
 % \begin{macro}[TF]{\file_if_exist_input:n}
 %   Input of a file with a test for existence cannot be done the usual
 %   way as the tokens to insert are in an odd place.
diff --git a/l3kernel/l3luatex.dtx b/l3kernel/l3luatex.dtx
index c7b34f1..c665ff4 100644
--- a/l3kernel/l3luatex.dtx
+++ b/l3kernel/l3luatex.dtx
@@ -136,6 +136,33 @@
 %   the result to \TeX{}.
 % \end{function}
 %
+% \begin{function}{l3kernel.filemdfivesum}
+%   \begin{syntax}
+%     \cs{l3kernel.filemdfivesum}|(|\meta{file}|)|
+%   \end{syntax}
+%   Returns the of the MD5 sum of the file contents read as bytes. If the
+%   \meta{file} is not found, nothing is returned with \emph{no error raised}.
+% \end{function}
+%
+% \begin{function}{l3kernel.filemoddate}
+%   \begin{syntax}
+%     \cs{l3kernel.filemoddate}|(|\meta{file}|)|
+%   \end{syntax}
+%   Returns the of the date/time of last modification of the \meta{file} in the
+%   format |D:|\meta{year}\meta{month}\meta{day}\meta{hour}\meta{minute}^^A
+%   \meta{second}\meta{offset}, where the latter may be |Z| (UTC) or
+%   \meta{plus-minus}\meta{hours}|'|\meta{minutes}|'|. If the \meta{file} is
+%   not found, nothing is returned with \emph{no error raised}.
+% \end{function}
+%
+% \begin{function}{l3kernel.filesize}
+%   \begin{syntax}
+%     \cs{l3kernel.filesize}|(|\meta{file}|)|
+%   \end{syntax}
+%   Returns the size of the \meta{file} in bytes. If the \meta{file} is not
+%   found, nothing is returned with \emph{no error raised}.
+% \end{function}
+%
 % \begin{function}{l3kernel.strcmp}
 %   \begin{syntax}
 %     \cs{l3kernel.strcmp}|(|\meta{str one}, \meta{str two}|)|
@@ -221,6 +248,9 @@
 %<*lua>
 %    \end{macrocode}
 %
+% Most of the emulation of \pdfTeX{} here is based heavily on Heiko Oberdiek's
+% \pkg{pdftexcmds} package.
+%
 % \begin{macro}[int]{l3kernel}
 %   Create a table for the kernel's own use.
 %    \begin{macrocode}
@@ -230,18 +260,48 @@ l3kernel = l3kernel or { }
 %
 %   Local copies of global tables.
 %    \begin{macrocode}
+local io      = io
+local kpse    = kpse
+local lfs     = lfs
+local math    = math
+local md5     = md5
+local os      = os
+local string  = string
 local tex     = tex
 local unicode = unicode
 %    \end{macrocode}
 %
 %   Local copies of standard functions.
 %    \begin{macrocode}
+local abs        = math.abs
+local byte       = string.byte
+local floor      = math.floor
+local format     = string.format
+local gsub       = string.gsub
+local kpse_find  = kpse.find_file
+local lfs_attr   = lfs.attributes
+local md5_sum    = md5.sum
+local open       = io.open
+local os_date    = os.date
 local setcatcode = tex.setcatcode
+local str_format = string.format
 local sprint     = tex.sprint
 local write      = tex.write
 local utf8_char  = unicode.utf8.char
 %    \end{macrocode}
 %
+% \begin{macro}[aux]{escapehex}
+%   An internal auxiliary to convert a string to the matching hex escape.
+%   This works on a byte basis: extension to handled UTF-8 input is
+%   covered in \pkg{pdftexcmds} but is not currently required here.
+%    \begin{macrocode}
+local function escapehex(str)
+  write((gsub(str, ".",
+    function (ch) return format("%02X", byte(ch)) end)))
+end
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}[int]{l3kernel.charcat}
 %   Creating arbitrary chars needs a category code table. As set up here,
 %   one may have been assigned earlier (see \pkg{l3bootstrap}) or a hard-coded
@@ -257,6 +317,95 @@ l3kernel.charcat = charcat
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}[int]{l3kernel.filemdfivesum}
+%   Read an entire file and hash it: the hash function itself is a built-in.
+%   As Lua is byte-based there is no work needed here in terms of UTF-8
+%   (see \pkg{pdftexcmds} and how it handles strings that have passed through
+%   \LuaTeX{}).
+%    \begin{macrocode}
+local function filemdfivesum(name)
+  local file =  kpse_find(name, "tex", true)
+  if file then
+    local f = open(file, "r")
+    if f then
+      local data = f:read("*a")
+      escapehex(md5_sum(data))
+      f:close()
+    end
+  end
+end
+l3kernel.filemdfivesum = filemdfivesum
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{l3kernel.filemoddate}
+%   See procedure \texttt{makepdftime} in \texttt{utils.c} of
+%   \pdfTeX{}.
+%    \begin{macrocode}
+local function filemoddate(name)
+  local file =  kpse_find(name, "tex", true)
+  if file then
+    local date = lfs_attr(file, "modification")
+    if date then
+      local d = os_date("*t", date)
+      if d.sec >= 60 then
+        d.sec = 59
+      end
+      local u = os_date("!*t", date)
+      local off = 60 * (d.hour - u.hour) + d.min - u.min
+      if d.year ~= u.year then
+        if d.year > u.year then
+          off = off + 1440
+        else
+          off = off - 1440
+        end
+      elseif d.yday ~= u.yday then
+        if d.yday > u.yday then
+          off = off + 1440
+        else
+          off = off - 1440
+        end
+      end
+      local timezone
+      if off == 0 then
+        timezone = "Z"
+      else
+        local hours = floor(off / 60)
+        local mins  = abs(off - hours * 60)
+        timezone = str_format("%+03d", hours)
+          .. "'" .. str_format("%02d", mins) .. "'"
+      end
+      write("D:"
+        .. str_format("%04d", d.year)
+        .. str_format("%02d", d.month)
+        .. str_format("%02d", d.day)
+        .. str_format("%02d", d.hour)
+        .. str_format("%02d", d.min)
+        .. str_format("%02d", d.sec)
+        .. timezone)
+    end
+  end
+end
+l3kernel.filemoddate = filemoddate
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{l3kernel.filesize}
+%   A simple disk lookup.
+%    \begin{macrocode}
+local function filesize(name)
+  local file =  kpse_find(name, "tex", true)
+  if file then
+    local size = lfs_attr(file, "size")
+    if size then
+      write(size)
+    end
+  end
+end
+l3kernel.filesize = filesize
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}[int]{l3kernel.strcmp}
 %   String comparison which gives the same results as \pdfTeX{}'s
 %   \tn{pdfstrcmp}, although the ordering should likely not be relied upon!
diff --git a/l3kernel/l3names.dtx b/l3kernel/l3names.dtx
index 3c8768b..2f1790f 100644
--- a/l3kernel/l3names.dtx
+++ b/l3kernel/l3names.dtx
@@ -628,6 +628,8 @@
   \__kernel_primitive:NN \pdfdraftmode                \pdftex_draftmode:D
   \__kernel_primitive:NN \pdfeachlinedepth            \pdftex_eachlinedepth:D
   \__kernel_primitive:NN \pdfeachlineheight           \pdftex_eachlineheight:D
+  \__kernel_primitive:NN \pdffilemoddate              \pdftex_filemoddate:D
+  \__kernel_primitive:NN \pdffilesize                 \pdftex_filesize:D
   \__kernel_primitive:NN \pdffirstlineheight          \pdftex_firstlineheight:D
   \__kernel_primitive:NN \pdffontexpand               \pdftex_fontexpand:D
   \__kernel_primitive:NN \pdffontsize                 \pdftex_fontsize:D
@@ -638,6 +640,7 @@
   \__kernel_primitive:NN \pdflastypos                 \pdftex_lastypos:D
   \__kernel_primitive:NN \pdfmapfile                  \pdftex_mapfile:D
   \__kernel_primitive:NN \pdfmapline                  \pdftex_mapline:D
+  \__kernel_primitive:NN \pdfmdfivesum                \pdftex_mdfivesum:D
   \__kernel_primitive:NN \pdfnoligatures              \pdftex_noligatures:D
   \__kernel_primitive:NN \pdfnormaldeviate            \pdftex_normaldeviate:D
   \__kernel_primitive:NN \pdfpageheight               \pdftex_pageheight:D
@@ -762,6 +765,7 @@
 % Primitives from \pdfTeX{} that \XeTeX{} renames: also helps with
 % \LuaTeX{}.
 %    \begin{macrocode}
+  \__kernel_primitive:NN \mdfivesum                   \pdftex_mdfivesum:D
   \__kernel_primitive:NN \ifprimitive                 \pdftex_ifprimitive:D
   \__kernel_primitive:NN \primitive                   \pdftex_primitive:D
   \__kernel_primitive:NN \shellescape                 \pdftex_shellescape:D
diff --git a/l3kernel/testfiles/m3expl001.luatex.tlg b/l3kernel/testfiles/m3expl001.luatex.tlg
index 038332c..88ee5f4 100644
--- a/l3kernel/testfiles/m3expl001.luatex.tlg
+++ b/l3kernel/testfiles/m3expl001.luatex.tlg
@@ -5403,6 +5403,11 @@ Defining \__coffin_scale_corner:Nnnn on line ...
 Defining \__coffin_scale_pole:Nnnnnn on line ...
 Defining \__coffin_x_shift_corner:Nnnn on line ...
 Defining \__coffin_x_shift_pole:Nnnnnn on line ...
+Defining \file_get_hash:nN on line ...
+Defining \file_get_size:nN on line ...
+Defining \file_get_timestamp:nN on line ...
+Defining \__file_get_details:nnN on line ...
+Defining message LaTeX/kernel/xetex-primitive-not-available on line ...
 Defining \file_if_exist_input:n on line ...
 Defining \file_if_exist_input:nT on line ...
 Defining \file_if_exist_input:nF on line ...
diff --git a/l3kernel/testfiles/m3expl001.ptex.tlg b/l3kernel/testfiles/m3expl001.ptex.tlg
index 5ee69b9..2459442 100644
--- a/l3kernel/testfiles/m3expl001.ptex.tlg
+++ b/l3kernel/testfiles/m3expl001.ptex.tlg
@@ -5393,6 +5393,11 @@ Defining \__coffin_scale_corner:Nnnn on line ...
 Defining \__coffin_scale_pole:Nnnnnn on line ...
 Defining \__coffin_x_shift_corner:Nnnn on line ...
 Defining \__coffin_x_shift_pole:Nnnnnn on line ...
+Defining \file_get_hash:nN on line ...
+Defining \file_get_size:nN on line ...
+Defining \file_get_timestamp:nN on line ...
+Defining \__file_get_details:nnN on line ...
+Defining message LaTeX/kernel/xetex-primitive-not-available on line ...
 Defining \file_if_exist_input:n on line ...
 Defining \file_if_exist_input:nT on line ...
 Defining \file_if_exist_input:nF on line ...
diff --git a/l3kernel/testfiles/m3expl001.tlg b/l3kernel/testfiles/m3expl001.tlg
index 13c0a15..bc3997e 100644
--- a/l3kernel/testfiles/m3expl001.tlg
+++ b/l3kernel/testfiles/m3expl001.tlg
@@ -5393,6 +5393,11 @@ Defining \__coffin_scale_corner:Nnnn on line ...
 Defining \__coffin_scale_pole:Nnnnnn on line ...
 Defining \__coffin_x_shift_corner:Nnnn on line ...
 Defining \__coffin_x_shift_pole:Nnnnnn on line ...
+Defining \file_get_hash:nN on line ...
+Defining \file_get_size:nN on line ...
+Defining \file_get_timestamp:nN on line ...
+Defining \__file_get_details:nnN on line ...
+Defining message LaTeX/kernel/xetex-primitive-not-available on line ...
 Defining \file_if_exist_input:n on line ...
 Defining \file_if_exist_input:nT on line ...
 Defining \file_if_exist_input:nF on line ...
diff --git a/l3kernel/testfiles/m3expl001.uptex.tlg b/l3kernel/testfiles/m3expl001.uptex.tlg
index f5f15d9..c121a90 100644
--- a/l3kernel/testfiles/m3expl001.uptex.tlg
+++ b/l3kernel/testfiles/m3expl001.uptex.tlg
@@ -5391,6 +5391,11 @@ Defining \__coffin_scale_corner:Nnnn on line ...
 Defining \__coffin_scale_pole:Nnnnnn on line ...
 Defining \__coffin_x_shift_corner:Nnnn on line ...
 Defining \__coffin_x_shift_pole:Nnnnnn on line ...
+Defining \file_get_hash:nN on line ...
+Defining \file_get_size:nN on line ...
+Defining \file_get_timestamp:nN on line ...
+Defining \__file_get_details:nnN on line ...
+Defining message LaTeX/kernel/xetex-primitive-not-available on line ...
 Defining \file_if_exist_input:n on line ...
 Defining \file_if_exist_input:nT on line ...
 Defining \file_if_exist_input:nF on line ...
diff --git a/l3kernel/testfiles/m3expl001.xetex.tlg b/l3kernel/testfiles/m3expl001.xetex.tlg
index 7bbf495..96ed0a8 100644
--- a/l3kernel/testfiles/m3expl001.xetex.tlg
+++ b/l3kernel/testfiles/m3expl001.xetex.tlg
@@ -5381,6 +5381,11 @@ Defining \__coffin_scale_corner:Nnnn on line ...
 Defining \__coffin_scale_pole:Nnnnnn on line ...
 Defining \__coffin_x_shift_corner:Nnnn on line ...
 Defining \__coffin_x_shift_pole:Nnnnnn on line ...
+Defining \file_get_hash:nN on line ...
+Defining \file_get_size:nN on line ...
+Defining \file_get_timestamp:nN on line ...
+Defining \__file_get_details:nnN on line ...
+Defining message LaTeX/kernel/xetex-primitive-not-available on line ...
 Defining \file_if_exist_input:n on line ...
 Defining \file_if_exist_input:nT on line ...
 Defining \file_if_exist_input:nF on line ...
diff --git a/l3kernel/testfiles/m3expl003.luatex.tlg b/l3kernel/testfiles/m3expl003.luatex.tlg
index 252c270..bb756cc 100644
--- a/l3kernel/testfiles/m3expl003.luatex.tlg
+++ b/l3kernel/testfiles/m3expl003.luatex.tlg
@@ -5404,6 +5404,11 @@ Defining \__coffin_scale_corner:Nnnn on line ...
 Defining \__coffin_scale_pole:Nnnnnn on line ...
 Defining \__coffin_x_shift_corner:Nnnn on line ...
 Defining \__coffin_x_shift_pole:Nnnnnn on line ...
+Defining \file_get_hash:nN on line ...
+Defining \file_get_size:nN on line ...
+Defining \file_get_timestamp:nN on line ...
+Defining \__file_get_details:nnN on line ...
+Defining message LaTeX/kernel/xetex-primitive-not-available on line ...
 Defining \file_if_exist_input:n on line ...
 Defining \file_if_exist_input:nT on line ...
 Defining \file_if_exist_input:nF on line ...
diff --git a/l3kernel/testfiles/m3expl003.ptex.tlg b/l3kernel/testfiles/m3expl003.ptex.tlg
index 0392e51..864b65b 100644
--- a/l3kernel/testfiles/m3expl003.ptex.tlg
+++ b/l3kernel/testfiles/m3expl003.ptex.tlg
@@ -5394,6 +5394,11 @@ Defining \__coffin_scale_corner:Nnnn on line ...
 Defining \__coffin_scale_pole:Nnnnnn on line ...
 Defining \__coffin_x_shift_corner:Nnnn on line ...
 Defining \__coffin_x_shift_pole:Nnnnnn on line ...
+Defining \file_get_hash:nN on line ...
+Defining \file_get_size:nN on line ...
+Defining \file_get_timestamp:nN on line ...
+Defining \__file_get_details:nnN on line ...
+Defining message LaTeX/kernel/xetex-primitive-not-available on line ...
 Defining \file_if_exist_input:n on line ...
 Defining \file_if_exist_input:nT on line ...
 Defining \file_if_exist_input:nF on line ...
diff --git a/l3kernel/testfiles/m3expl003.tlg b/l3kernel/testfiles/m3expl003.tlg
index 87af906..2ab58e4 100644
--- a/l3kernel/testfiles/m3expl003.tlg
+++ b/l3kernel/testfiles/m3expl003.tlg
@@ -5394,6 +5394,11 @@ Defining \__coffin_scale_corner:Nnnn on line ...
 Defining \__coffin_scale_pole:Nnnnnn on line ...
 Defining \__coffin_x_shift_corner:Nnnn on line ...
 Defining \__coffin_x_shift_pole:Nnnnnn on line ...
+Defining \file_get_hash:nN on line ...
+Defining \file_get_size:nN on line ...
+Defining \file_get_timestamp:nN on line ...
+Defining \__file_get_details:nnN on line ...
+Defining message LaTeX/kernel/xetex-primitive-not-available on line ...
 Defining \file_if_exist_input:n on line ...
 Defining \file_if_exist_input:nT on line ...
 Defining \file_if_exist_input:nF on line ...
diff --git a/l3kernel/testfiles/m3expl003.uptex.tlg b/l3kernel/testfiles/m3expl003.uptex.tlg
index f2c4ed4..884ea58 100644
--- a/l3kernel/testfiles/m3expl003.uptex.tlg
+++ b/l3kernel/testfiles/m3expl003.uptex.tlg
@@ -5392,6 +5392,11 @@ Defining \__coffin_scale_corner:Nnnn on line ...
 Defining \__coffin_scale_pole:Nnnnnn on line ...
 Defining \__coffin_x_shift_corner:Nnnn on line ...
 Defining \__coffin_x_shift_pole:Nnnnnn on line ...
+Defining \file_get_hash:nN on line ...
+Defining \file_get_size:nN on line ...
+Defining \file_get_timestamp:nN on line ...
+Defining \__file_get_details:nnN on line ...
+Defining message LaTeX/kernel/xetex-primitive-not-available on line ...
 Defining \file_if_exist_input:n on line ...
 Defining \file_if_exist_input:nT on line ...
 Defining \file_if_exist_input:nF on line ...
diff --git a/l3kernel/testfiles/m3expl003.xetex.tlg b/l3kernel/testfiles/m3expl003.xetex.tlg
index 57ff3bf..d8ead14 100644
--- a/l3kernel/testfiles/m3expl003.xetex.tlg
+++ b/l3kernel/testfiles/m3expl003.xetex.tlg
@@ -5382,6 +5382,11 @@ Defining \__coffin_scale_corner:Nnnn on line ...
 Defining \__coffin_scale_pole:Nnnnnn on line ...
 Defining \__coffin_x_shift_corner:Nnnn on line ...
 Defining \__coffin_x_shift_pole:Nnnnnn on line ...
+Defining \file_get_hash:nN on line ...
+Defining \file_get_size:nN on line ...
+Defining \file_get_timestamp:nN on line ...
+Defining \__file_get_details:nnN on line ...
+Defining message LaTeX/kernel/xetex-primitive-not-available on line ...
 Defining \file_if_exist_input:n on line ...
 Defining \file_if_exist_input:nT on line ...
 Defining \file_if_exist_input:nF on line ...
diff --git a/l3kernel/testfiles/m3file001.lvt b/l3kernel/testfiles/m3file001.lvt
index 6860b47..96b9914 100644
--- a/l3kernel/testfiles/m3file001.lvt
+++ b/l3kernel/testfiles/m3file001.lvt
@@ -141,4 +141,24 @@
     \tl_show:N \l_tmpa_str
   }
 
+\TEST { Getting~file~information }
+  {
+    \OMIT
+      \cs_generate_variant:Nn \regex_match:nnTF { nV }
+    \TIMO
+    \file_get_hash:nN { filetest-utf8.txt } \l_tmpa_str
+    \tl_show:N \l_tmpa_str
+    \file_get_hash:nN { NotAFile.txt } \l_tmpa_str
+    \tl_show:N \l_tmpa_str
+    \file_get_size:nN { filetest.txt } \l_tmpa_str
+    \tl_show:N \l_tmpa_str
+    \file_get_size:nN { NotAFile.txt } \l_tmpa_str
+    \tl_show:N \l_tmpa_str
+    \file_get_timestamp:nN { filetest.txt } \l_tmpa_str
+    \regex_match:nVTF
+      { ^D\:\d{14} } \l_tmpa_tl \TRUE \ERROR
+    \file_get_timestamp:nN { NotAFile.txt } \l_tmpa_str
+    \tl_show:N \l_tmpa_str
+  }
+
 \END
diff --git a/l3kernel/testfiles/m3file001.ptex.tlg b/l3kernel/testfiles/m3file001.ptex.tlg
index 849fe29..5e88459 100644
--- a/l3kernel/testfiles/m3file001.ptex.tlg
+++ b/l3kernel/testfiles/m3file001.ptex.tlg
@@ -226,3 +226,30 @@ l. ...  }
 <recently read> }
 l. ...  }
 ============================================================
+============================================================
+TEST 9: Getting file information
+============================================================
+> \l_tmpa_str=4F918CB10404DD50E3C1B9990FF54D4A.
+<recently read> }
+l. ...  }
+> \l_tmpa_str=.
+<recently read> }
+l. ...  }
+> \l_tmpa_str=120.
+<recently read> }
+l. ...  }
+> \l_tmpa_str=.
+<recently read> }
+l. ...  }
+! Undefined control sequence.
+<argument> \ERROR 
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+> \l_tmpa_str=.
+<recently read> }
+l. ...  }
+============================================================
diff --git a/l3kernel/testfiles/m3file001.tlg b/l3kernel/testfiles/m3file001.tlg
index bcd5b55..f000a49 100644
--- a/l3kernel/testfiles/m3file001.tlg
+++ b/l3kernel/testfiles/m3file001.tlg
@@ -220,3 +220,30 @@ l. ...  }
 <recently read> }
 l. ...  }
 ============================================================
+============================================================
+TEST 9: Getting file information
+============================================================
+> \l_tmpa_str=4F918CB10404DD50E3C1B9990FF54D4A.
+<recently read> }
+l. ...  }
+> \l_tmpa_str=.
+<recently read> }
+l. ...  }
+> \l_tmpa_str=120.
+<recently read> }
+l. ...  }
+> \l_tmpa_str=.
+<recently read> }
+l. ...  }
+! Undefined control sequence.
+<argument> \ERROR 
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+> \l_tmpa_str=.
+<recently read> }
+l. ...  }
+============================================================
diff --git a/l3kernel/testfiles/m3file001.uptex.tlg b/l3kernel/testfiles/m3file001.uptex.tlg
index 409581a..77aac84 100644
--- a/l3kernel/testfiles/m3file001.uptex.tlg
+++ b/l3kernel/testfiles/m3file001.uptex.tlg
@@ -226,3 +226,30 @@ l. ...  }
 <recently read> }
 l. ...  }
 ============================================================
+============================================================
+TEST 9: Getting file information
+============================================================
+> \l_tmpa_str=4F918CB10404DD50E3C1B9990FF54D4A.
+<recently read> }
+l. ...  }
+> \l_tmpa_str=.
+<recently read> }
+l. ...  }
+> \l_tmpa_str=120.
+<recently read> }
+l. ...  }
+> \l_tmpa_str=.
+<recently read> }
+l. ...  }
+! Undefined control sequence.
+<argument> \ERROR 
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+> \l_tmpa_str=.
+<recently read> }
+l. ...  }
+============================================================
diff --git a/l3kernel/testfiles/m3file001.xetex.tlg b/l3kernel/testfiles/m3file001.xetex.tlg
index 300ae5dc..1f89b92 100644
--- a/l3kernel/testfiles/m3file001.xetex.tlg
+++ b/l3kernel/testfiles/m3file001.xetex.tlg
@@ -220,3 +220,90 @@ l. ...  }
 <recently read> }
 l. ...  }
 ============================================================
+============================================================
+TEST 9: Getting file information
+============================================================
+> \l_tmpa_str=4F918CB10404DD50E3C1B9990FF54D4A.
+<recently read> }
+l. ...  }
+> \l_tmpa_str=.
+<recently read> }
+l. ...  }
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! LaTeX error: "kernel/xetex-primitive-not-available"
+! 
+! Primitive \pdffilesize not available
+! 
+! See the LaTeX3 documentation for further information.
+! 
+! For immediate help type H <return>.
+!...............................................  
+l. ...  }
+|'''''''''''''''''''''''''''''''''''''''''''''''
+| XeTeX does not currently provide functionality equivalent to the
+| \pdffilesize primitive.
+|...............................................
+> \l_tmpa_str=.
+<recently read> }
+l. ...  }
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! LaTeX error: "kernel/xetex-primitive-not-available"
+! 
+! Primitive \pdffilesize not available
+! 
+! See the LaTeX3 documentation for further information.
+! 
+! For immediate help type H <return>.
+!...............................................  
+l. ...  }
+|'''''''''''''''''''''''''''''''''''''''''''''''
+| XeTeX does not currently provide functionality equivalent to the
+| \pdffilesize primitive.
+|...............................................
+> \l_tmpa_str=.
+<recently read> }
+l. ...  }
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! LaTeX error: "kernel/xetex-primitive-not-available"
+! 
+! Primitive \pdffilemoddate not available
+! 
+! See the LaTeX3 documentation for further information.
+! 
+! For immediate help type H <return>.
+!...............................................  
+l. ...  }
+|'''''''''''''''''''''''''''''''''''''''''''''''
+| XeTeX does not currently provide functionality equivalent to the
+| \pdffilemoddate primitive.
+|...............................................
+! Undefined control sequence.
+<argument> \ERROR 
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! LaTeX error: "kernel/xetex-primitive-not-available"
+! 
+! Primitive \pdffilemoddate not available
+! 
+! See the LaTeX3 documentation for further information.
+! 
+! For immediate help type H <return>.
+!...............................................  
+l. ...  }
+|'''''''''''''''''''''''''''''''''''''''''''''''
+| XeTeX does not currently provide functionality equivalent to the
+| \pdffilemoddate primitive.
+|...............................................
+> \l_tmpa_str=.
+<recently read> }
+l. ...  }
+============================================================

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the latex3-commits mailing list