• Problems with paths of Windows

    From Luis Alejandro Muzzachiodi@aleccp@yahoo.com to comp.lang.tcl on Sat May 17 13:37:42 2025
    From Newsgroup: comp.lang.tcl

    Hello,

    I have a procedure that accepts a list of paths.
    Assuming "$::env(SystemRoot)\my dir" is passed as a parameter, is there
    a way to process this so that it's interpreted correctly in the end?
    I've tried combinations of { }, [list], [file normalize], [file
    nativename] but that didn't work.
    (Working in Windows, tcl 8.6)

    Thanks,

    Alejandro

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From saito@saitology9@gmail.com to comp.lang.tcl on Sat May 17 12:51:05 2025
    From Newsgroup: comp.lang.tcl

    On 5/17/2025 12:37 PM, Luis Alejandro Muzzachiodi wrote:
    Hello,

    I have a procedure that accepts a list of paths.
    Assuming "$::env(SystemRoot)\my dir" is passed as a parameter, is there
    a way to process this so that it's interpreted correctly in the end?
    I've tried combinations of { }, [list], [file normalize], [file
    nativename] but that didn't work.
    (Working in Windows, tcl 8.6)


    It is not clear what you are asking.

    Are you trying to append a parameter to a list? You do "lappend mylist $parameter"

    Are you trying to modify the Windows path env variable? It is just a
    string separated by commas: "append env(path) \;[join $mylist \;]"
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Luis Alejandro Muzzachiodi@aleccp@yahoo.com to comp.lang.tcl on Sat May 17 23:36:00 2025
    From Newsgroup: comp.lang.tcl

    El 17/05/2025 a las 13:51, saito escribió:
    On 5/17/2025 12:37 PM, Luis Alejandro Muzzachiodi wrote:
    Hello,

    I have a procedure that accepts a list of paths.
    Assuming "$::env(SystemRoot)\my dir" is passed as a parameter, is
    there a way to process this so that it's interpreted correctly in the
    end?
    I've tried combinations of { }, [list], [file normalize], [file
    nativename] but that didn't work.
    (Working in Windows, tcl 8.6)


    It is not clear what you are asking.

    Are you trying to append a parameter to a list? You do "lappend mylist $parameter"

    Are you trying to modify the Windows path env variable?  It is just a string separated by commas: "append env(path) \;[join $mylist \;]"

    The question - generalizing - is how (if it is possible) to convert a
    path into a valid path if passed as a parameter to a procedure in the
    Windows format, for example, "c:\windows\my dir".
    The specific question would be:
    given the following procedure
    proc myproc { listofpaths } {
    foreach p $listofpaths {
    puts "$p - is valid? : [file isdirectory $p]"
    }
    }
    if a parameter is passed as "$::env(SystemRoot)\my dir"
    the result obtained is
    C:Windowsmy - is valid? : 0
    dir - is valid? : 0
    Then, is there a way to convert - within the procedure - that input into
    a valid directory?

    Alejandro





    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From saito@saitology9@gmail.com to comp.lang.tcl on Sun May 18 00:42:57 2025
    From Newsgroup: comp.lang.tcl

    On 5/17/2025 10:36 PM, Luis Alejandro Muzzachiodi wrote:
    The specific question would be:
    given the following procedure
    proc myproc { listofpaths } {
        foreach p  $listofpaths {
            puts "$p - is valid? : [file isdirectory $p]"
        }
    }
    if a parameter is passed as "$::env(SystemRoot)\my dir"
    the result obtained is
    C:Windowsmy - is valid? : 0
    dir - is valid? : 0
    Then, is there a way to convert - within the procedure - that input into
    a valid directory?

    OK, that clarifies it. So your proc is correct as above. Here is a test:

    % myproc [list [file join $::env(SystemRoot) "Offline Web Pages"]] C:/WINDOWS/Offline Web Pages - is valid? : 1


    What is causing trouble is a combination of a couple of factors: basic
    Tcl quoting involving spaces and the unfortunate use of backslash by
    Windows and Tcl for different purposes. In general, I would recommend
    using [file] commands like the test above to construct file names as
    opposed to what you are doing with "$::env(SystemRoot)\my dir".

    If you insist on doing it your way, you need to escape the spaces as
    well as the backslash that Windows uses as file separator. Here is an example:

    % myproc [list "$::env(SystemRoot)\\Offline\ Web\ Pages"]
    C:\WINDOWS\Offline Web Pages - is valid? : 1

    Note that each space is escaped with a backslash, and the file separator backslash is escaped as well with an extra backslash. But really it goes
    back to the basics of quoting.






    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From saito@saitology9@gmail.com to comp.lang.tcl on Sun May 18 06:35:38 2025
    From Newsgroup: comp.lang.tcl

    On 5/17/2025 10:36 PM, Luis Alejandro Muzzachiodi wrote:

    given the following procedure
    proc myproc { listofpaths } {
        foreach p  $listofpaths {
            puts "$p - is valid? : [file isdirectory $p]"
        }
    }
    if a parameter is passed as "$::env(SystemRoot)\my dir"
    the result obtained is
    C:Windowsmy - is valid? : 0
    dir - is valid? : 0

    You know, the problem here is something else completely: your proc is expecting a list of file names. Instead it gets a string containing a
    single file name. So what happens is that the foreach loop takes that
    string, splits it into a list at each space character, and processes
    each part separately. So "$::env(SystemRoot)\my dir" turns into "$::env(SystemRoot)\my" and "dir" as you see in your output. You don't
    want this implicit conversion.

    Instead, turn your input into a proper list before calling your proc
    above and all should be good.


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Alan Grunwald@nospam.nurdglaw@gmail.com to comp.lang.tcl on Sun May 18 14:41:59 2025
    From Newsgroup: comp.lang.tcl

    On 18/05/2025 03:36, Luis Alejandro Muzzachiodi wrote:
    El 17/05/2025 a las 13:51, saito escribió:
    On 5/17/2025 12:37 PM, Luis Alejandro Muzzachiodi wrote:
    Hello,

    I have a procedure that accepts a list of paths.
    Assuming "$::env(SystemRoot)\my dir" is passed as a parameter, is
    there a way to process this so that it's interpreted correctly in the
    end?
    I've tried combinations of { }, [list], [file normalize], [file
    nativename] but that didn't work.
    (Working in Windows, tcl 8.6)


    It is not clear what you are asking.

    Are you trying to append a parameter to a list? You do "lappend mylist
    $parameter"

    Are you trying to modify the Windows path env variable?  It is just a
    string separated by commas: "append env(path) \;[join $mylist \;]"

    The question - generalizing - is how (if it is possible) to convert a
    path into a valid path if passed as a parameter to a procedure in the Windows format, for example, "c:\windows\my dir".
    The specific question would be:
    given the following procedure
    proc myproc { listofpaths } {
        foreach p  $listofpaths {
            puts "$p - is valid? : [file isdirectory $p]"
        }
    }
    if a parameter is passed as "$::env(SystemRoot)\my dir"
    the result obtained is
    C:Windowsmy - is valid? : 0
    dir - is valid? : 0
    Then, is there a way to convert - within the procedure - that input into
    a valid directory?

    Alejandro





    It seems that the caller is mangling the parameter; it will be too late
    by the time the proc is entered.

    I suggest you try passing [file join $::env(SystemRoot) "my dir"]. If
    you feel that lots of up-front, non-portable string manipulation is more readable you might prefer "$::env(SystemRoot)\\my dir".

    Alan
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From et99@et99@rocketship1.me to comp.lang.tcl on Sun May 18 12:17:44 2025
    From Newsgroup: comp.lang.tcl

    On 5/18/2025 6:41 AM, Alan Grunwald wrote:
    On 18/05/2025 03:36, Luis Alejandro Muzzachiodi wrote:
    El 17/05/2025 a las 13:51, saito escribió:
    On 5/17/2025 12:37 PM, Luis Alejandro Muzzachiodi wrote:
    Hello,

    I have a procedure that accepts a list of paths.
    Assuming "$::env(SystemRoot)\my dir" is passed as a parameter, is there a way to process this so that it's interpreted correctly in the end?
    I've tried combinations of { }, [list], [file normalize], [file nativename] but that didn't work.
    (Working in Windows, tcl 8.6)


    It is not clear what you are asking.

    Are you trying to append a parameter to a list? You do "lappend mylist $parameter"

    Are you trying to modify the Windows path env variable?  It is just a string separated by commas: "append env(path) \;[join $mylist \;]"

    The question - generalizing - is how (if it is possible) to convert a path into a valid path if passed as a parameter to a procedure in the Windows format, for example, "c:\windows\my dir".
    The specific question would be:
    given the following procedure
    proc myproc { listofpaths } {
         foreach p  $listofpaths {
             puts "$p - is valid? : [file isdirectory $p]"
         }
    }
    if a parameter is passed as "$::env(SystemRoot)\my dir"
    the result obtained is
    C:Windowsmy - is valid? : 0
    dir - is valid? : 0
    Then, is there a way to convert - within the procedure - that input into a valid directory?

    Alejandro





    It seems that the caller is mangling the parameter; it will be too late by the time the proc is entered.

    I suggest you try passing [file join $::env(SystemRoot) "my dir"]. If you feel that lots of up-front, non-portable string manipulation is more readable you might prefer "$::env(SystemRoot)\\my dir".

    Alan


    Just to (hopefully) add a little more clarity, one can see why that result occurs, with this:


    % puts "$::env(SystemRoot)\my dir"
    C:\WINDOWSmy dir

    The \m became simply m, because of rule 9, \ followed by something NOT special (like \n), simply removes the \

    Then the foreach treats it's input as though lindex were used on each item in a list:

    % lindex "$::env(SystemRoot)\my dir" 0
    C:WINDOWSmy
    % lindex "$::env(SystemRoot)\my dir" 1
    dir

    Here, you are getting another round of substitution on the \W which likewise removed the \

    which all together then, explains why those 2 results showed up.

    In the above, one would actually need another \ as so:

    % puts "|$::env(SystemRoot)\\my\ dir|"
    |C:\WINDOWS\my dir|

    with the ||'s added to hopefully add more clarity.

    -e

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Luis Alejandro Muzzachiodi@aleccp@yahoo.com to comp.lang.tcl on Mon May 19 01:48:18 2025
    From Newsgroup: comp.lang.tcl

    Thanks for your answers, but it seems I haven't been able to express my question clearly.
    The question isn't about why the input isn't valid (it's a string, the
    slash is problematic, the spaces, etc.), but rather whether there's a reasonably simple way to make that input valid. Obviously, the simplest
    way would be to write the parameter "correctly." However, this comes
    through a procedure that allows the user to load one or more paths to
    add to those defined in the script, meaning it's not up to me. As I
    said, I tried several solutions, but they didn't work: automatically converting the parameter to a list, using the file normalize and/or
    nativename commands, or, as a first idea, checking whether the parameter
    is a list or a string (spoiler: in TCL, everything is a string...).
    Having said all that, I hope I've clarified the point of the question,
    and again, thanks for answering.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Ralf Fassel@ralfixx@gmx.de to comp.lang.tcl on Mon May 19 11:00:15 2025
    From Newsgroup: comp.lang.tcl

    * Luis Alejandro Muzzachiodi <aleccp@yahoo.com>
    | I tried several solutions, but they didn't work: automatically
    | converting the parameter to a list, using the file normalize and/or
    | nativename commands, or, as a first idea, checking whether the
    | parameter is a list or a string (spoiler: in TCL, everything is a
    | string...).

    Show your *exact* code and *exact* input.
    Otherwise all one can do is guesswork.
    I found many times that when I prepare something like that for posting,
    the answer comes automagically...

    R'
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Ralf Fassel@ralfixx@gmx.de to comp.lang.tcl on Mon May 19 11:07:12 2025
    From Newsgroup: comp.lang.tcl

    * Luis Alejandro Muzzachiodi <aleccp@yahoo.com>
    | However, this comes through a procedure that allows the user to load
    | one or more paths to add to those defined in the script, meaning it's
    | not up to me.

    It might be that this procedure already mangled the filenames, e.g. if it
    did not quote \\ correctly (or avoid it by using 'file join' in the first place).

    Your procedure

    proc myproc { listofpaths } {
    foreach p $listofpaths {
    puts "$p - is valid? : [file isdirectory $p]"
    }
    }

    works fine if it is passed correct input (i.e. a *list* of properly
    constructed filenames). If the function input is already incorrect
    - GIGO¹.

    R'
    ---
    ¹ http://www.catb.org/jargon/html/G/GIGO.html
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From et99@et99@rocketship1.me to comp.lang.tcl on Mon May 19 11:10:10 2025
    From Newsgroup: comp.lang.tcl

    On 5/18/2025 9:48 PM, Luis Alejandro Muzzachiodi wrote:
    Thanks for your answers, but it seems I haven't been able to express my question clearly.
    The question isn't about why the input isn't valid (it's a string, the slash is problematic, the spaces, etc.), but rather whether there's a reasonably simple way to make that input valid. Obviously, the simplest way would be to write the parameter "correctly." However, this comes through a procedure that allows the user to load one or more paths to add to those defined in the script, meaning it's not up to me. As I said, I tried several solutions, but they didn't work: automatically converting the parameter to a list, using the file normalize and/or nativename commands, or, as a first idea, checking whether the parameter is a list or a string (spoiler: in TCL, everything is a string...). Having said all that, I hope I've clarified the point of the question, and again, thanks for answering.

    If what you want is a way to unmangle a mangled filename, I would say there is no reasonably simple way to do this.

    If there are only a few valid directories to choose from, and you can generate a list of them, then an "almost equal" function might do this, but likely not with 100% accuracy.

    I have an application uses a fuzzy string compare function that produces a value that is a measure of a near match. I got the idea and some code from here, in particular I use the trigrams function:

    https://wiki.tcl-lang.org/page/Fuzzy+string+search



    --- Synchronet 3.21a-Linux NewsLink 1.2