summaryrefslogtreecommitdiff
path: root/support/lintex/cxx/ltx.cxx
blob: a82de99fdb026868378fb41bb17c0a5834c6dc26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
//     Author: Maurizio Loreti, aka MLO or (HAM) I3NOO
//     Work:   University of Padova - Department of Physics
//             Via F. Marzolo, 8 - 35131 PADOVA - Italy
//     Phone:  +39 (049) 827-7216   FAX: +39 (049) 827-7102
//     EMail:  loreti@pd.infn.it
//     WWW:    http://www.pd.infn.it/~loreti/mlo.html
//
// -------------------------------------------------------------------
//
//     C++ version of the program "lintex", born as an exercise
//     in programming.
//
//     $Id: ltx.cxx,v 1.9 2006/09/11 12:25:41 loreti Exp $
//
// -------------------------------------------------------------------

#include <algorithm>
#include <list>
#include <cstring>
#include "ltx.hh"               // Includes: functional, iostream, string
#include "cleandir.hh"          // Includes: string

extern "C" {
  #include <getopt.h>
  #include <unistd.h>
}

using std::cout;
using std::endl;
using std::string;

// Global variables (definition)

namespace ltx {
  string            progname;
  string            trailEd("~");
  string::size_type lTrailEd;
  bool              confirm(false);
  bool              recurse(false);
}

using namespace ltx;

// Local procedures

namespace {
  char *basename(char *);
  void  syntax();
}

int main(
  int   argc,
  char *argv[]
) {
  std::list<string> targets;

  // Gets the executable name

  progname = argv[0] = basename(argv[0]);

  // Decodes the command line options and arguments

  char          shortOpts[] = "irb::";
  struct option longOpts[]  = {
    {"interactive", no_argument,       0, 'i'},
    {"recursive",   no_argument,       0, 'r'},
    {"backup",      optional_argument, 0, 'b'},
    { 0,            0,                 0,  0}
  };

  int c;
  while ((c = getopt_long(argc, argv, shortOpts, longOpts, 0)) != -1) {
    switch (c) {
      case 'i':
        confirm = true;
        break;

      case 'r':
        recurse = true;
        break;

      case 'b':
        trailEd = optarg ? optarg : "";
        break;

      case 'h':
      case '?':
        syntax();
        return 0;

      default:
        std::cerr << "Can't happen: " << __FILE__ << ' '
                  << __LINE__ << endl;
        return 0;
    }
  }

  while (optind < argc) targets.push_back( argv[optind++] );

  // Computes the length of the extension identifying the backup
  // files, and, if no target directories were explicitly given,
  // scans the current one.

  lTrailEd = trailEd.size();

  if (targets.empty()) targets.push_back(".");

#if defined(DEBUG)
  cout << "--------------------Argument analysis\n";
  cout << "Confirm = " << confirm << endl;
  cout << "Recurse = " << recurse << endl;
  cout << "Trailing editor extension = \"" << trailEd
       << "\" (length " << lTrailEd << ")\n";
  cout << "Target directories:\n";

  for_each(targets.begin(), targets.end(), printBefore("  "));
#endif // DEBUG

  // Scans in turn all the wanted directories

  for_each(targets.begin(), targets.end(), std::ptr_fun(scan_dir));

  return 0;
}

namespace {
  char *basename(
    char *pc
  ) {
    // Strips the (eventual) path name from the full file name pointed
    // to by "pc"; if no file name is given, returns an empty string.

    char *p = std::strrchr(pc, '/');
    if (p == 0) return pc;
    return ++p;
  }

  void syntax()
  {
    cout <<
      "\nUsage:\t " << progname << " [options] [dir [dir ... ]]\n";
    cout <<
      "Purpose: removes TeX auxiliary files and editor backup files from "
      "the\n";
    cout
      << "\t given directories (default: from the current directory).  TeX\n";
    cout <<
      "\t auxiliary files are actually removed only if their modification\n";
    cout <<
      "\t time is more recent than the one of the related TeX source file.\n";
    cout <<
      "Options: -i     | --interactive : asks before removing files;\n";
    cout <<
      "\t -r     | --recursive   : scans recursively the given directories;\n";
    cout <<
      "\t -b=ext | --backup=ext  : \"ext\" is the trailing string "
      "identifying\n";
    cout <<
      "\t\t\t\t  editor backup files.\n";
    cout <<
      "Notes:\t \"ext\" defaults to \"~\"; -b \"\" avoids the unconditional "
      "cleanup of\n";
    cout <<
      "\t any special file.\n" << endl;
  }
}