www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - We could use a hasExt function in std.path

reply Andrej Mitrovic <none none.none> writes:
At least on Windows, as far as I know, the casing of a file extension doesn't
come into play. But when comparing extensions, you have to be careful to
lowercase the result of `getExt()`, for example:

foreach (string name; dirEntries(curdir, SpanMode.shallow))
{
    if (name.isFile && name.getExt == "txt")
    {
        // do something
    }
}

If the extension is cased "tXt", the if block will not be entered. That's a
silent bug in your code right there!

I think we could use a function in Phobos that returns true if an extension of
a file matches any number of strings passed to it (a range). And an extra
argument could be a flag (enum) or a boolean which can set the case sensitivity
to true, but is false by default, e.g.:

bool hasExt(Range)(string fileName, Range exts, bool caseSensitive = false)
{
    static if (isSomeString!Range)
    {
        if (caseSensitive)
        {
            if (exts == fileName.getExt)
                return true;
        }
        else
        {
            if (exts.tolower == fileName.getExt.tolower)
                return true;
        }        
    }
    else
    {
        foreach (ext; exts)
        {
            if (caseSensitive)
            {
                if (ext == fileName.getExt)
                    return true;
            }
            else
            {
                if (ext.tolower == fileName.getExt.tolower)
                    return true;
            }
        }        
    }

    return false;
}

foreach (string name; dirEntries(curdir, SpanMode.shallow))
{
    if (name.isFile && name.hasExt(["ini", "conf"]))
    {
        // do something
    }
}

Yes, that is a horrible implementation, but I can't be bothered with trying to
make it nice and simple right now, I'm in a rush. Sorry. :)

I often have to search for files that have a certain extension. Having to
expand the code to the following becomes ugly real fast:

foreach (string name; dirEntries(curdir, SpanMode.shallow))
{
    if (name.isFile && name.hasExt.tolower == "ini" ||
                   name.hasExt.tolower == "conf"))
    {
        // do something
    }
}
Apr 01 2011
next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 4/1/11, Andrej Mitrovic <none none.none> wrote:
 I often have to search for files that have a certain extension. Having to
 expand the code to the following becomes ugly real fast:

 foreach (string name; dirEntries(curdir, SpanMode.shallow))
 {
     if (name.isFile && name.hasExt.tolower == "ini" ||
                    name.hasExt.tolower == "conf"))
     {
         // do something
     }
 }

Oops, that showcase was supposed to use `getExt`.
Apr 01 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 04/01/2011 11:03 PM, Andrej Mitrovic wrote:
 At least on Windows, as far as I know, the casing of a file extension doesn't
come into play. But when comparing extensions, you have to be careful to
lowercase the result of `getExt()`, for example:

 foreach (string name; dirEntries(curdir, SpanMode.shallow))
 {
      if (name.isFile&&  name.getExt == "txt")
      {
          // do something
      }
 }

 If the extension is cased "tXt", the if block will not be entered. That's a
silent bug in your code right there!

 I think we could use a function in Phobos that returns true if an extension of
a file matches any number of strings passed to it (a range). And an extra
argument could be a flag (enum) or a boolean which can set the case sensitivity
to true, but is false by default, e.g.:

 bool hasExt(Range)(string fileName, Range exts, bool caseSensitive = false)
 {
      static if (isSomeString!Range)
      {
          if (caseSensitive)
          {
              if (exts == fileName.getExt)
                  return true;
          }
          else
          {
              if (exts.tolower == fileName.getExt.tolower)
                  return true;
          }
      }
      else
      {
          foreach (ext; exts)
          {
              if (caseSensitive)
              {
                  if (ext == fileName.getExt)
                      return true;
              }
              else
              {
                  if (ext.tolower == fileName.getExt.tolower)
                      return true;
              }
          }
      }

      return false;
 }

 foreach (string name; dirEntries(curdir, SpanMode.shallow))
 {
      if (name.isFile&&  name.hasExt(["ini", "conf"]))
      {
          // do something
      }
 }

 Yes, that is a horrible implementation, but I can't be bothered with trying to
make it nice and simple right now, I'm in a rush. Sorry. :)

 I often have to search for files that have a certain extension. Having to
expand the code to the following becomes ugly real fast:

 foreach (string name; dirEntries(curdir, SpanMode.shallow))
 {
      if (name.isFile&&  name.hasExt.tolower == "ini" ||
                     name.hasExt.tolower == "conf"))
      {
          // do something
      }
 }

Would be nice eg to match a whole set of image formats at once (while also caring for "uncased" matching). But why a range? Denis -- _________________ vita es estrany spir.wikidot.com
Apr 01 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Match a single extension or any number of extensions. I've said
"range", but I didn't mean a custom type. Just that it works with
either 1 value or an array of values.
Apr 01 2011