Listing 4: A sample remove utility based on CFileList

#include <stdio.h>
#include <ctype.h>

#include <iostream>
#include <string>

#include "cdir.h"

class CDelFileList: public CFileList
  {
  private:
    bool m_ask;       // should we ask user before removing file
    bool m_silent;    // should we show file names
  public:
    bool Ask() const { return m_ask; };
    bool &Ask() { return m_ask; };
    bool Silent() const { return m_silent; };
    CDelFileList(char *masks[], int count): CFileList(masks, count)
      {
      m_ask = true;
      m_silent = false;
      }

    virtual bool ParseArgs(int argc, char *argv[])
      {
      for (int i = 0; i < argc; ++i)
        if (IsOptionOn(argv[i], 'a'))
          m_ask = true;
      for (int i = 0; i < argc; ++i)
        if (IsOptionOn(argv[i], 's'))
          m_silent = true;
      return CFileList::ParseArgs(argc, argv);
      } // ParseArgs
      
  }; // CDelFileList


// callback function: remove file 
int DelFile(const char *name, void *data)
  {
  CDelFileList *DelFileListPtr = static_cast <CDelFileList *> (data);
  if (DelFileListPtr->Ask())
    {
    std::string tmp_str; // string to store user input
    cout << "remove: " << name << " ? (yes,no,all,cancel) ";
    cin >> tmp_str;
    switch (tolower(tmp_str[0]))
      {
      case 'a':
        DelFileListPtr->Ask() = false;
        break;
      case 'y':
        break;
      case 'c':
        throw 1;
      default:
        return 0;
      } // switch 
    }
  if (!DelFileListPtr->Silent())
    cout << "removing: " << name << endl;
  if (remove(name) != 0)
    {
    perror(name);
    return 0;
    } 
  return 1;
  } // DelFile

// print it if user don't know how to use this program
void ShowUsage()
  {
  cerr << "My own remove\n"
          "Usage: myrm [-r] [-i] [file_mask] ...\n"
          "  -a - ask\n"
          "  -s - silent\n"
          "  -r - recursive\n"
          "  -i - ignore case\n"
          "  file_masks - masks like \"*.cpp\" or \"*.h\"\n"
          "    (notice usage of \" to avoid shell interpretation\n"
          "    of command line args on unices)\n";
  exit(1);
  } // ShowUsage


int main(int argc, char *argv[])
  {
  int i;
  for (i = 1; i < argc; ++i)  // caalculate first mask index
    if (argv[i][0] != '-')
      break;
  if (argc == 0 || argc - i == 0)
    ShowUsage();
  CDelFileList DelFileList(&argv[i], argc - i);
  if (DelFileList.ParseArgs(argc, argv))
    {
    try
      {
      DelFileList.ProcessFiles(".", DelFile, NULL, static_cast<void *> (&DelFileList));
      }
    catch (...)
      {
      cout << "user abort" << endl;
      }
    }
  else
    ShowUsage();
  } // main