Roxen.git / server / etc / modules / Roxen.pmod

version» Context lines:

Roxen.git/server/etc/modules/Roxen.pmod:6357:   //! If a segment ambiguously matches several entries in a directory   //! then it and all remaining segments are returned as-is. A warning   //! is also logged in this case, unless @[no_warn] is nonzero.   //!   //! The given path is assumed to be absolute, and it is normalized   //! with @[combine_path] before being checked. The returned paths   //! always have "/" as directory separators. If there is a trailing   //! slash then it is kept intact.   //!   //! If @[charset] is set then charset conversion is done: @[path] is - //! assumed to be a (possibly wide) unicode string, and @[charset] is + //! assumed to be a (possibly wide) unicode string in NFC, and @[charset] is   //! taken as the charset used in the file system. The returned path is - //! a unicode string as well. If @[charset] isn't specified then no - //! charset conversion is done anywhere, which means that @[path] must - //! have the same charset as the file system, and the case insensitive - //! comparisons only work in as far as @[lower_case] does the right - //! thing with that charset. + //! a unicode string as well. If @[charset] isn't specified then it + //! and the filesystem are assumed to be in utf-8, and the result will + //! be utf-8 encoded.   //!   //! If @[charset] is given then it's assumed to be a charset accepted   //! by @[Charset]. If there are charset conversion errors in @[path]   //! or in the file system then those paths are treated as nonexisting.   //!   //! @note   //! Existing paths are cached without any time limit, but the cached   //! paths are always verified to still exist before being reused. Thus   //! the only overcaching effect that can occur is if the underlying   //! file system is case insensitive and some path segment only has   //! changed in case.   {    ASSERT_IF_DEBUG (is_absolute_path (path));       string cache_name = "case_insens_paths";       function(string:string) encode, decode; -  switch (charset) { +  switch (charset && lower_case(charset)) {    case 0: -  +  // NB: NT has a filesystem that uses UTF-16. + #ifndef __NT__ +  return string_to_utf8(this_function(utf8_to_string(path), no_warn, "utf8")); + #endif    break;    case "utf8":    case "utf-8":    encode = string_to_utf8;    decode = utf8_to_string;    cache_name += ":utf8";    break;    default:    Charset.Encoder enc = Charset.encoder (charset);    Charset.Decoder dec = Charset.decoder (charset);
Roxen.git/server/etc/modules/Roxen.pmod:6443:    }    recur (dec_path);       if (!nonexist) {    // FIXME: Note that get_dir on windows accepts and returns    // unicode paths, so the following isn't correct there. The    // charset handling in the file system interface on windows is    // inconsistent however, since most other functions do not    // accept neither wide strings nor strings encoded with any    // charset. This applies at least up to pike 7.8.589. +  string name = basename(path);    search_dir:    if (array(string) dir_list = get_dir (enc_path)) {    string lc_name = basename (lc_path);    string dec_name, enc_name; -  +  int fail;       foreach (dir_list, string enc_ent) {    string dec_ent;    if (!decode)    dec_ent = enc_ent;    else if (mixed err = catch (dec_ent = decode (enc_ent))) {    if (decode != utf8_to_string)    // utf8_to_string doesn't throw Charset.DecodeErrors.    if (!objectp (err) || !err->is_charset_decode_error)    throw (err);    // Ignore file system paths that we cannot decode.    //werror ("path ignore in %O: %O\n", enc_path, enc_ent);    continue;    } -  +  if (String.width(dec_ent) > 8) { +  dec_ent = Unicode.normalize(dec_ent, "NFC"); +  }       if (lower_case (dec_ent) == lc_name) {    if (dec_name) {    if (!no_warn)    report_warning ("Ambiguous path %q matches both %q and %q "    "in %q.\n", path, dec_name, dec_ent, dec_path); -  break search_dir; +  fail = 1;    }    dec_name = dec_ent;    enc_name = enc_ent; -  +  if (enc_ent == name) { +  fail = 0; +  break;    }    } -  +  }    -  if (dec_name) { +  if (dec_name && !fail) {    dec_path = combine_path_unix (dec_path, dec_name);    enc_path = combine_path (enc_path, enc_name);    //werror ("path %O -> %O/%O\n", path, dec_path, enc_path);    cache_set (cache_name, lc_path, dec_path);    return;    }    }       nonexist = 1;    }