00001
00002 #include "idep_compiledep.h"
00003 #include <iostream>
00004 using namespace std;
00005
00006
00007
00008 #define NL "\n"
00009 static const char *help()
00010 {
00011 return NL
00012 "cdep: Extract compile-time dependencies from a collection of files." NL
00013 "" NL
00014 " The following command line interface is supported:" NL
00015 "" NL
00016 " cdep [-I<dir>] [-i<dirlist>] [-f<filelist>] [-x] <filename>*" NL
00017 "" NL
00018 " -I<dir> Specify include directory to search." NL
00019 " -i<dirlist> Specify file containing a list of directories to search."NL
00020 " -f<filelist> Specify file containing a list of files to process." NL
00021 " -x Do _not_ check recursively for nested includes." NL
00022 "" NL
00023 " Each filename on the command line specifies a file to be considered for"NL
00024 " processing. Specifying no arguments indicates that the list of files" NL
00025 " is to come from standard input unless the -f option has been invoked." NL
00026 "" NL
00027 " TYPICAL USAGE:" NL
00028 "" NL
00029 " cdep -iincludes *.[ch]" NL
00030 NL;
00031 }
00032
00033 static enum { IOERROR = -1, GOOD = 0 } s_status = GOOD;
00034
00035 static ostream& err()
00036 {
00037 s_status = IOERROR;
00038 return cerr << "Error: ";
00039 }
00040
00041 static int missing(const char *argName, char option)
00042 {
00043 err() << "missing `" << argName << "' argument for -"
00044 << option << " option." << endl;
00045 return s_status;
00046 }
00047
00048 static int extra(const char *text, char option)
00049 {
00050 err() << "extra text \"" << text << "\" encountered after -"
00051 << option << " option." << endl;
00052 return s_status;
00053 }
00054
00055 static int unreadable(const char *dirFile, char option)
00056 {
00057 err() << "unable to read \"" << dirFile << "\" for -"
00058 << option << " option." << endl;
00059 return s_status;
00060 }
00061
00062 static const char *getArg(int *i, int argc, const char *argv[])
00063 {
00064 return 0 != argv[*i][2] ? argv[*i] + 2 :
00065 ++*i >= argc || '-' == argv[*i][0] ? "" : argv[*i];
00066 }
00067
00068 int main (int argc, const char *argv[])
00069 {
00070 int argCount = 0;
00071 int fileFlag = 0;
00072 int recursionFlag = 1;
00073 idep_CompileDep environment;
00074 for (int i = 1; i < argc; ++i) {
00075 const char *word = argv[i];
00076 if ('-' == word[0]) {
00077 char option = word[1];
00078 switch(option) {
00079 case 'I': {
00080 const char *arg = getArg(&i, argc, argv);
00081 if (!*arg) {
00082 return missing("dir", option);
00083 }
00084 environment.addIncludeDirectory(arg);
00085 } break;
00086 case 'i': {
00087 const char *arg = getArg(&i, argc, argv);
00088 if (!*arg) {
00089 return missing("file", option);
00090 }
00091 if (0 != environment.readIncludeDirectories(arg)) {
00092 return unreadable(arg, option);
00093 }
00094 } break;
00095 case 'f': {
00096 const char *arg = getArg(&i, argc, argv);
00097 if (!*arg) {
00098 return missing("file", option);
00099 }
00100 if (0 != environment.readRootFiles(arg)) {
00101 return unreadable(arg, option);
00102 }
00103 fileFlag = 1;
00104 } break;
00105 case 'x': {
00106 const char *arg = getArg(&i, argc, argv);
00107 if (*arg) {
00108 return extra(arg, option);
00109 }
00110 recursionFlag = 0;
00111 } break;
00112 default: {
00113 err() << "unknown option \"" << word << "\"." << endl
00114 << help();
00115 return s_status;
00116 } break;
00117 }
00118 }
00119 else {
00120 ++argCount;
00121 environment.addRootFile(argv[i]);
00122 }
00123 }
00124
00125 if (!fileFlag && !argCount) {
00126 environment.inputRootFiles();
00127 }
00128
00129 if (environment.calculate(cerr, recursionFlag)) {
00130 s_status = IOERROR;
00131 }
00132
00133 cout << environment;
00134
00135 return s_status;
00136 }
00137