// 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 #include #include #include "ltx.hh" // Includes: functional, iostream, string #include "cleandir.hh" // Includes: string extern "C" { #include #include } 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 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; } }