• missing command: file concat

    From aotto1968@21:1/5 to All on Sun May 12 11:58:19 2024
    Hi,

    the following code does *not* work :

    set tmpFile [file join $TMP [ file normalize $F ]]

    because *file normalize* will return an *absolute* path and *file join* will skip "$TMP" if
    *absolute* path is found.

    → the GOAL is to create a new path with *prefix* "$TMP" using the local path separator

    set tmpFile [file concat $TMP [ file normalize $F ]]

    will solve this issue.

    example:

    TMP = /tmp
    file normalize $F = /a/b

    OLD: file join /tmp /a/b → /a/b
    NEW: file concat /tmp /a/b → /tmp/a/b


    mfg AO

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert Heller@21:1/5 to [email protected] on Sun May 12 12:37:36 2024
    At Sun, 12 May 2024 11:58:19 +0200 aotto1968 <[email protected]> wrote:


    Hi,

    the following code does *not* work :

    set tmpFile [file join $TMP [ file normalize $F ]]

    because *file normalize* will return an *absolute* path and *file join* will skip "$TMP" if
    *absolute* path is found.

    - the GOAL is to create a new path with *prefix* "$TMP" using the local path separator

    Why would you really want to do that? Please explain your use case...


    set tmpFile [file concat $TMP [ file normalize $F ]]

    will solve this issue.

    example:

    TMP = /tmp
    file normalize $F = /a/b

    OLD: file join /tmp /a/b -> /a/b
    NEW: file concat /tmp /a/b -> /tmp/a/b



    Your solution *will fail* under MS-Windows (and maybe MacOSX). I *think* file normalize under MS-Windows might include the drive letter and may swap '/'s with '\'s. Under MacOSX might result in a path starting with MacOSX root paths. Note: under Linux (and UNIX) this also happens. This means that you final result is not going to be a valid existing pathname on any system, although under UNIX-ish systems it might make some kind of sense, if one is playing with virtual file systems or something.


    mfg AO



    --
    Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
    Deepwoods Software -- Custom Software Services
    http://www.deepsoft.com/ -- Linux Administration Services
    [email protected] -- Webhosting Services

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From greg@21:1/5 to All on Sun May 12 14:21:10 2024
    Am 12.05.24 um 11:58 schrieb aotto1968:
    Hi,

    the following code does *not* work :

    set tmpFile [file join $TMP [ file normalize $F ]]

    because *file normalize* will return an *absolute* path and *file join*
    will skip "$TMP" if
    *absolute* path is found.

    → the GOAL is to create a new path with *prefix* "$TMP" using the local path separator

    set tmpFile [file concat $TMP [ file normalize  $F ]]

    will solve this issue.

    example:

    TMP = /tmp
    file normalize $F = /a/b

    OLD: file join /tmp /a/b → /a/b
    NEW: file concat /tmp /a/b → /tmp/a/b


    mfg AO

    # Idea
    #https://wiki.tcl-lang.org/page/namespace+ensemble
    #proc ::tcl::dict::get?

    package require fileutil
    proc ::tcl::file::concat {args} {
    if {[llength $args] != 2} {
    return -code error "This function expects exactly two arguments"
    }
    try {
    file normalize [file join [lindex $args 0] [fileutil::stripPath
    [lindex [file split [lindex $args 1 ]] 0] [lindex $args 1]]]
    }
    }
    namespace ensemble configure file -map \
    [dict merge [namespace ensemble configure file -map] {concat ::tcl::file::concat}]

    #Example
    puts [file concat /tmp [pwd]]

    #This Tcl script defines a procedure
    #::tcl::file::concat that concatenates two file paths and normalizes the result.



    mfg
    Gregor

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From greg@21:1/5 to All on Sun May 12 15:19:05 2024
    Am 12.05.24 um 14:21 schrieb greg:
    Am 12.05.24 um 11:58 schrieb aotto1968:
    Hi,

    the following code does *not* work :

    set tmpFile [file join $TMP [ file normalize $F ]]

    because *file normalize* will return an *absolute* path and *file
    join* will skip "$TMP" if
    *absolute* path is found.

    → the GOAL is to create a new path with *prefix* "$TMP" using the
    local path separator

    set tmpFile [file concat $TMP [ file normalize  $F ]]

    will solve this issue.

    example:

    TMP = /tmp
    file normalize $F = /a/b

    OLD: file join /tmp /a/b → /a/b
    NEW: file concat /tmp /a/b → /tmp/a/b


    mfg AO

    # Idea
    #https://wiki.tcl-lang.org/page/namespace+ensemble
    #proc ::tcl::dict::get?

    package require fileutil
    proc ::tcl::file::concat {args} {
      if {[llength $args] != 2} {
            return -code error "This function expects exactly two arguments"
        }
      try {
        file normalize [file join [lindex $args 0] [fileutil::stripPath [lindex [file split [lindex $args 1 ]] 0] [lindex $args 1]]]
      }
    }
    namespace ensemble configure file -map \
            [dict merge [namespace ensemble configure file -map] {concat ::tcl::file::concat}]

    #Example
    puts  [file concat /tmp [pwd]]

    #This Tcl script defines a procedure
    #::tcl::file::concat that concatenates two file paths and normalizes the result.



    mfg
    Gregor


    Works for me here on Linux and Windows.
    - check if two arguments
    - applies file split to argument 2 to find "root"
    - applies fileutil:stripPath along with the "root" and removes the
    "root" from argument 2
    -applies file join to argument 1 and argument 2
    -applies file normalize

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to [email protected] on Sun May 12 16:46:22 2024
    aotto1968 <[email protected]> wrote:
    Hi,

    the following code does *not* work :

    set tmpFile [file join $TMP [ file normalize $F ]]

    because *file normalize* will return an *absolute* path and *file
    join* will skip "$TMP" if *absolute* path is found.

    Which is also the exact documented behavior of [file join]. From the
    man page (read last two sentences carefully):

    file join name ?name ...?
    Takes one or more file names and combines them, using the cor‐
    rect path separator for the current platform. If a particular
    name is relative, then it will be joined to the previous file
    name argument. Otherwise, any earlier arguments will be dis‐
    carded, and joining will proceed from the current argument.

    → the GOAL is to create a new path with *prefix* "$TMP" using the local path separator

    Then one way to do that is to not 'normalize' the one presently being normalized. Otherwise, if you /really/ need to join a 'normalized'
    path then remove the leading path separator after
    normalizing:

    set tmpFile [file join $TMP [string range [file normalize $F] 1 end]]

    Although the above will fail for names beginning with windows drive
    letter's or windows UNC paths.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From greg@21:1/5 to All on Sun May 12 18:33:51 2024
    Am 12.05.24 um 15:19 schrieb greg:
    Am 12.05.24 um 14:21 schrieb greg:
    Am 12.05.24 um 11:58 schrieb aotto1968:
    Hi,

    the following code does *not* work :

    set tmpFile [file join $TMP [ file normalize $F ]]

    because *file normalize* will return an *absolute* path and *file
    join* will skip "$TMP" if
    *absolute* path is found.

    → the GOAL is to create a new path with *prefix* "$TMP" using the
    local path separator

    set tmpFile [file concat $TMP [ file normalize  $F ]]

    will solve this issue.

    example:

    TMP = /tmp
    file normalize $F = /a/b

    OLD: file join /tmp /a/b → /a/b
    NEW: file concat /tmp /a/b → /tmp/a/b


    mfg AO

    # Idea
    #https://wiki.tcl-lang.org/page/namespace+ensemble
    #proc ::tcl::dict::get?

    package require fileutil
    proc ::tcl::file::concat {args} {
       if {[llength $args] != 2} {
             return -code error "This function expects exactly two arguments"
         }
       try {
         file normalize [file join [lindex $args 0] [fileutil::stripPath
    [lindex [file split [lindex $args 1 ]] 0] [lindex $args 1]]]
       }
    }
    namespace ensemble configure file -map \
             [dict merge [namespace ensemble configure file -map] {concat
    ::tcl::file::concat}]

    #Example
    puts  [file concat /tmp [pwd]]

    #This Tcl script defines a procedure
    #::tcl::file::concat that concatenates two file paths and normalizes
    the result.



    mfg
    Gregor


      Works for me here on Linux and Windows.
    - check if two arguments
    - applies file split to argument 2 to find "root"
    - applies fileutil:stripPath along with the "root" and removes the
    "root" from argument 2
    -applies file join to argument 1 and argument 2
    -applies file normalize



    #without fileutil::stripPath
    in proc ::tcl::file::concat {args}

    file normalize [file join [lindex $args 0] {*}[lrange [file split
    [lindex $args 1 ]] 1 end]]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From greg@21:1/5 to All on Sun May 12 22:16:23 2024
    Am 12.05.24 um 11:58 schrieb aotto1968:
    Hi,

    the following code does *not* work :

    set tmpFile [file join $TMP [ file normalize $F ]]

    because *file normalize* will return an *absolute* path and *file join*
    will skip "$TMP" if
    *absolute* path is found.

    → the GOAL is to create a new path with *prefix* "$TMP" using the local path separator

    set tmpFile [file concat $TMP [ file normalize  $F ]]

    will solve this issue.

    example:

    TMP = /tmp
    file normalize $F = /a/b

    OLD: file join /tmp /a/b → /a/b
    NEW: file concat /tmp /a/b → /tmp/a/b


    mfg AO

    Using file split.
    Separates the absolute part.
    Linux and Windows (unc path)

    mfg
    Gregor

    #! /usr/bin/env tclsh

    # Idea from
    #https://wiki.tcl-lang.org/page/namespace+ensemble
    #proc ::tcl::dict::get?

    proc ::tcl::file::concat {args} {
    if {[llength $args] != 2} {
    return -code error "This function expects exactly two arguments"
    }
    try {
    file normalize [file join [lindex $args 0] {*}[lrange [file split
    [lindex $args 1 ]] 1 end]]
    }
    }
    namespace ensemble configure file -map \
    [dict merge [namespace ensemble configure file -map] {concat ::tcl::file::concat}]


    #Examples
    puts " [info patchlevel] $tcl_platform(os)"
    puts " absolute"
    set ndir [pwd]
    puts "ndir: $ndir"
    puts "file concat [file concat /tmp $ndir]"

    puts "\n relative"
    set ndir ./greg/tmp
    puts "ndir: $ndir"
    puts "file concat: [file concat /tmp $ndir]"

    puts "\n unc path in windows"
    set ndir {\\myserver\files\projects\tcl\info.txt}
    puts "ndir: $ndir"
    puts "file concat: [file concat /tmp $ndir]"

    puts "\n unc path in windows"
    set ndir //myserver/files/projects/tcl/info.txt
    puts "ndir: $ndir"
    puts "file concat: [file concat /tmp $ndir]"

    puts "\n unc path in windows"
    set ndir //myserver/files/projects/tcl/info.txt
    puts "ndir: $ndir"
    puts "file concat: [file concat //tmpserver/tmp $ndir]"

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From aotto1968@21:1/5 to Robert Heller on Sun May 12 22:57:37 2024
    One reason to introduce the *file concat* is that windows etc add a lot of extra chars.
    I'm on unix *without* drive-letter etc

    some restrictions:
    1) the windows-file-letter should be skipped *or* be first part of the path

    file concat c:\tmp d:\a\b → c:\tmp\a\b … or … c:\tmp\_d_\a\b

    the *goal* of this is to make a kind of "backup" from an exiting file with path into a *tmp* directory
    *and* keep the directory-tree valid

    I think "wget" is doing something like this to copy a html-tree on to disc


    On 12.05.24 14:37, Robert Heller wrote:
    At Sun, 12 May 2024 11:58:19 +0200 aotto1968 <[email protected]> wrote:


    Hi,

    the following code does *not* work :

    set tmpFile [file join $TMP [ file normalize $F ]]

    because *file normalize* will return an *absolute* path and *file join* will skip "$TMP" if
    *absolute* path is found.

    - the GOAL is to create a new path with *prefix* "$TMP" using the local path separator

    Why would you really want to do that? Please explain your use case...


    set tmpFile [file concat $TMP [ file normalize $F ]]

    will solve this issue.

    example:

    TMP =tmp
    file normalize $F =a/b

    OLD: file join /tmp /a/b -> /a/b
    NEW: file concat /tmp /a/b -> /tmp/a/b



    Your solution *will fail* under MS-Windows (and maybe MacOSX). I *think* file
    normalize under MS-Windows might include the drive letter and may swap '/'s with '\'s. Under MacOSX might result in a path starting with MacOSX root paths. Note: under Linux (and UNIX) this also happens. This means that you final result is not going to be a valid existing pathname on any system, although under UNIX-ish systems it might make some kind of sense, if one is playing with virtual file systems or something.


    mfg AO




    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert Heller@21:1/5 to [email protected] on Mon May 13 02:39:52 2024
    At Sun, 12 May 2024 22:57:37 +0200 aotto1968 <[email protected]> wrote:



    One reason to introduce the *file concat* is that windows etc add a lot of extra chars.
    I'm on unix *without* drive-letter etc

    some restrictions:
    1) the windows-file-letter should be skipped *or* be first part of the path

    file concat c:\tmp d:\a\b → c:\tmp\a\b … or … c:\tmp\_d_\a\b

    the *goal* of this is to make a kind of "backup" from an exiting file with path into a *tmp* directory
    *and* keep the directory-tree valid

    I think "wget" is doing something like this to copy a html-tree on to disc

    I suspect wget is doing something else.

    I think "file normalize" is not really needed or wanted. Maybe a different function to "just" deal with "../" and "./" segments, but not a full normalization to an abs path is really what you want.



    On 12.05.24 14:37, Robert Heller wrote:
    At Sun, 12 May 2024 11:58:19 +0200 aotto1968 <[email protected]> wrote:


    Hi,

    the following code does *not* work :

    set tmpFile [file join $TMP [ file normalize $F ]]

    because *file normalize* will return an *absolute* path and *file join* will skip "$TMP" if
    *absolute* path is found.

    - the GOAL is to create a new path with *prefix* "$TMP" using the local path separator

    Why would you really want to do that? Please explain your use case...


    set tmpFile [file concat $TMP [ file normalize $F ]]

    will solve this issue.

    example:

    TMP =tmp
    file normalize $F =a/b

    OLD: file join /tmp /a/b -> /a/b
    NEW: file concat /tmp /a/b -> /tmp/a/b



    Your solution *will fail* under MS-Windows (and maybe MacOSX). I *think* file
    normalize under MS-Windows might include the drive letter and may swap '/'s with '\'s. Under MacOSX might result in a path starting with MacOSX root paths. Note: under Linux (and UNIX) this also happens. This means that you final result is not going to be a valid existing pathname on any system, although under UNIX-ish systems it might make some kind of sense, if one is playing with virtual file systems or something.


    mfg AO







    --
    Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
    Deepwoods Software -- Custom Software Services
    http://www.deepsoft.com/ -- Linux Administration Services
    [email protected] -- Webhosting Services

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)