2

Well, not sure what to do in this regard. A little while ago I modified a logging script for an eggdrop bot.. but now an issue unfolds that for some reason, it is logging actions/text in separate files because of an issue of character case. #channel.html exists, as does #Channel.html, though the former is written to because of the current state of the channel name(it can change if all users leave and one rejoins with different case).

I've narrowed this problem down to what I believe is the issue. file exists 'filename_here'. I've looked through tcl's documentation, and I've read through the wiki regarding mixed case file names(it treats them as different files of course), but I have yet to find such an option(or user made proc) that would allow me to disable this behavior.

Is there a way around/to do this?

Daedalus
  • 7,518
  • 3
  • 29
  • 56

3 Answers3

4

It really depends on the file system (i.e., the OS) as file exists is just a thin wrapper around the OS's basic file existence test. Classic Unix filesystems are mostly case-sensitive, whereas Windows filesystems are usually case-insensitive. This means that it is usually best to write your code to be careful with handling the case of things; you probably ought to consider using string tolower to get a channel name in an expected case (since I think IRC channel names are case-insensitive).

But if you can't do that, the best you can do is to get the list of filenames that match case-insensitively and check if that's a single value. Alas, this is a messy operation as glob doesn't have a -nocase option (it's rare that people want such a thing), so we need to use string match -nocase to help out:

set files [lmap f [glob *.html] {
    expr {[string match -nocase ${channel}.html $f] ? $f : [continue]}
}]
if {[llength $files] == 1} {
    set channel_file [lindex $files 0]
} else {
    # Oh no! Ambiguity!
}

That uses lmap from Tcl 8.6; earlier versions of Tcl should use this instead:

set files {}
foreach f [glob *.html] {
    if {[string match -nocase ${channel}.html $f]} {
        lappend files $f
    }
}
if {[llength $files] == 1} {
    set channel_file [lindex $files 0]
} else {
    # Oh no! Ambiguity!
}
Donal Fellows
  • 120,022
  • 18
  • 134
  • 199
  • To clarify, I don't have any doubts that this will work, however I'm holding off on accepting because I haven't had a chance to attempt implementation yet. – Daedalus Mar 06 '13 at 08:02
1

Pick a filename case (#channel.html, #Channel.html or #CHANNEL.HTML) and use string tolower, string totitle or string toupper respectively on filename_here. Then use that value for all file operations.

potrzebie
  • 1,660
  • 1
  • 12
  • 23
0

An lsearch filter on glob can be used to perform a case-insensitive search for a particular file name, e.g.

% lsearch -nocase -all -inline -glob [glob ./*] {*/myfile.txt}
./myFile.txt ./Myfile.txt ./MYFILE.txt

A sanity check using llength on the lsearch result above can be used to flag an error in case more than one file name is returned.