file nativename

file nativename name

Returns the platform-specific name of the file name. This is useful if the filename is needed to pass to a platform-specific call, such as an argument to an execed program under Windows, or AppleScript on the Macintosh.


LES: What is the difference between file nativename and file normalize? What does file nativename do that file normalize doesn't?

RLH: file normalize "Returns a unique normalised path representation for the file-system object (file, directory, link, etc), whose string value can be used as a unique identifier for it. "

MG Basically, file normalize expands ., .. and ~ to the "proper" elements, and file nativename shows the platform-specific directory separators. Usually, for the purposes of displaying a path, you want to use both. For example:

 (Griffiths) 2 % pwd
 C:/Documents and Settings/Griffiths
 (Griffiths) 3 % set path [file join .. .. windows]
 ../../windows
 (Griffiths) 4 % file normalize $path
 C:/WINDOWS
 (Griffiths) 5 % file nativename $path
 ..\..\windows
 (Griffiths) 6 % file nativename [file normalize $path]
 C:\WINDOWS
 (Griffiths) 7 % file normalize [file nativename $path]
 C:/WINDOWS

So, to display a path the platform-specific way,

 file nativename [file normalize $path]

is the thing to use, as it expands everything properly. On Windows, you can go a step further, and use

 file nativename [file attributes [file normalize $path] -shortname]
 file nativename [file attributes [file normalize $path] -longname]

to guarantee you get the short (MS-DOS type 8.3) names, or the longer, full/"real" file names. (You still need the file nativename on the outside, though, to get backslashes, rather than forward slashes.)

Vince says that [file normalize] is guaranteed to be the 'longname', so the second example is longer than necessary. file nativename [file normalize $path] will do the same thing.

LES tells RLH: I am lazy indeed, but not THAT lazy. I asked that question because I read the manual, but that wording did not help me at all. That is a common problem in Tcl's documentation. To the other Tclers, I say that the explanations offered should be clear enough, but I am still puzzled because as a novice programmer I've certainly had problems with paths, but always fixed them completely with no more than file normalize. I still don't see why anyone would need [file nativename].

MG The main use (as far as I'm concerned from how I've used it) is to make programs look more native to the platform they're on. When you're on MS Windows (and only use it/rarely use anything else), paths with forward slashes just don't look right. Since they'll all work just the same internally, it's better IMHO to give users the right look for their platform - it's less confusing, and looks more professional, I think.

LES: So, if I got it right, file normalize replaces backslashes with forward slashes, which always is the best way to represent paths in Tcl source code, even on Windows. My guess, now, is that the only time we really need the backslashes is when we want to *display* a path to the user. Then, and only then, we would rather use file nativename than file normalize. Right?

Vince true, but also when you wish to pass the path to another executable which doesn't understand forward slashes, you'd want to use it: exec foo.exe [file nativename $path]

LV Les, file normalize might not really do much, if anything, with backslashes. For instance, here's what I see on Unix:

 $ tclsh
 % set p "\\desktop\\users\\virden"
 \desktop\users\virden
 % file normalize $p
 /home/lwv28/Mail/D.inbox/\desktop\users\virden
 % 

Notice that the backslashes were not touched. In fact, even when using both nativename and normalize, on Unix at least, they are not touched:

 % file nativename [file normalize $p]
 /home/lwv28/Mail/D.inbox/\desktop\users\virden

file normalize has to do with converting relative path names and symbolic links into non-symbolic linked full pathnames. For instance, again on Unix:

 % ln -s /etc /tmp/etc
 % file normalize /tmp/etc/motd
 /etc/motd

In this case, /tmp/etc/motd contains a symbolic link, etc, to another directory. normalize saw that and replaced /tmp/etc with /etc .

If your code guarantees that a normal, non-alias, full pathname will always be in a variable, then obviously you won't need to call normalize. However, if you are obtaining path names from other programs, from user input, from command link arguments, etc. and you are planning on saving the file name away somewhere so that it might be used again, regardless of where the program happens to be invoked, then using normalize is a good thing; it gets you a path that is less likely to be effected by changes in the working directory, etc.

As for the use of nativename, from the above other discussion, the function appears to have more use on Windows (and perhaps Mac? I'm uncertain, based on the man page info), than on Unix.


See also