View mode: basic / threaded / horizontal-split · Log in · Help
April 01, 2011
We could use a hasExt function in std.path
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
   }
}
April 01, 2011
Re: We could use a hasExt function in std.path
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`.
April 01, 2011
Re: We could use a hasExt function in std.path
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
April 01, 2011
Re: We could use a hasExt function in std.path
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.
Top | Discussion index | About this forum | D home