heinrichmartin <
[email protected]> wrote:
On Saturday, October 8, 2022 at 9:27:26 PM UTC+2, Paul Obermeier wrote:
to make it work on Linux, the retrieval of the Windows specific
environment variable SystemRoot must be guarded. See
https://github.com/lamuzzachiodi/tclfpdf/issues/1
While looking at that code, I stumbled upon
variable TCLFPDF_FONTPATH "[file join [pwd] [file dirname [info script]]]/font"
and a few other occurrences of file join + pwd + info script. I wondered
* Is info script not guaranteed to return an absolute path (while it
was not overwritten with info script newpath)?
man n info:
info script ?filename?
If a Tcl script file is currently being evaluated (i.e.
there is a call to Tcl_EvalFile active or there is an active
invocation of the source command), then this command returns
the name of the innermost file being processed. If filename
is specified, then the return value of this command will be
modified for the duration of the active invocation to return
that name. This is useful in virtual file system
applications. Otherwise the command returns an empty string.
It is defined as "the name of the innermost file". Some quick testing
with 8.6.11 on linux appears to indicate that what gets returned is the
literal string given to whichever libc exec() call launched the script:
Test file, sitting at /tmp/info-script:
#!/usr/bin/tclsh
puts "info script = [info script]"
Current directory not /tmp:
$ /tmp/info-script
info script = /tmp/info-script
Make current directory be /tmp:
$ cd /tmp/
$ ./info-script
info script = ./info-script
Try a really weird, but valid, path to the file:
$ /tmp/../tmp/../tmp/info-script
info script = /tmp/../tmp/../tmp/info-script
* Is one of these patterns preferable: [file join [pwd] $path1 $path2
...] vs [file normalize [file join $path1 $path2 ...]]?
File normalize and file join are two different operators, with
different meanings. File join just joins path pieces together to create
a single string without trying to remove any relative references or
links that might exist along that final path (i.e., my
/tmp/../tmp/../tmp example above). It does ignore multiple absolute references, using only the last absolute one found:
$ rlwrap tclsh
% file join tmp .. tmp .. tmp .. tmp
tmp/../tmp/../tmp/../tmp
% file join /tmp /xyz /pdq
/pdq
Note just literally "joined" if relative, but only last absolute is
used.
File normalize also does not 'join' anything, it expects to get a
single fully 'joined' path string. It defined task is then to convert
that path into a filesystem unique name by removing relative
references:
% file normalize [file join tmp .. tmp .. tmp .. tmp]
/tmp
# untested
variable TCLFPDF_BASEPATH [file normalize [file dirname [info script]]] variable TCLFPDF_FONTPATH [file join $TCLFPDF_BASEPATH font]
In the end, this will most likely be a matter of taste with no real performance or maintainability impact - but it has caught my eyes.
Not really, the original code can return some ugly looking path strings
if called with a relative path. It still 'works' but resolving the
extra relative steps might be a bit of a performance hit:
$ cat /tmp/fpdf
#!/usr/bin/tclsh
puts "[file join [pwd] [file dirname [info script]]]/font"
pwd in a different directory, with an absolute path call, the [pwd] is pointless because it is never used:
$ cd /var/log/
$ /tmp/fpdf
/tmp/font
pwd in a different directory, with a relative path call:
$ cd /var/log
$ ./../../tmp/fpdf
/var/log/./../../tmp/font
We get six path lookups per access instead of just one, but we do
find the correct location. Whether six extra lookup is noticable
depends on the performance of the underlying filesystem/hardware.
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)