00001
00002 #include "idep_aliasdep.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 "adep - create aliases to group files into cohesive components." NL
00013 "" NL
00014 " The following 3 command line interface modes are supported:" NL
00015 "" NL
00016 " adep [-s] [-a<alias>] [-f<filelist> ] [-X<fn>] [-x<xFile>] <filename>*" NL
00017 " adep -v [-a<alias>] [-f<filelist>] [-X<fn>] [-x<xFile>] <cfilename>*" NL
00018 " adep -e [-a<alias>] [-f<filelist>] [-X<fn>] [-x<xFile>] <cfilename>*" NL
00019 "" NL
00020 " -s Suppress the printing of suffixes for unpaired names." NL
00021 " -v Verify file contains component name as 1st dependency." NL
00022 " -e Extract aliases using name of first dependency." NL
00023 " -a<alias> Specify file containing component name aliases." NL
00024 " -f<filelist> Specify file containing a list of files to consider." NL
00025 " -X<fn> Specify name of file to ignore during processing." NL
00026 " -x<xFile> Specify file containing a list of filenames to ignore." NL
00027 "" NL
00028 " Each filename on the command line specifies a file to be considered for"NL
00029 " processing. Specifying no arguments indicates that the list of files" NL
00030 " is to come from standard input unless the -f option has been invoked." NL
00031 "" NL
00032 " TYPICAL USAGE:" NL
00033 "" NL
00034 " adep -s *.[ch] // print unpaired files to stdout" NL
00035 "" NL
00036 " adep -v -aaliases *.c // print #include errors to stderr" NL
00037 "" NL
00038 " adep -e *.c // print extracted aliases to stderr"NL
00039 NL;
00040 }
00041
00042 static enum { IOERROR = -1, GOOD = 0, BAD = 1 } s_status = GOOD;
00043
00044 static ostream& err()
00045 {
00046 s_status = IOERROR;
00047 return cerr << "Error: ";
00048 }
00049
00050 static int missing(const char *argName, char option)
00051 {
00052 err() << "missing `" << argName << "' argument for -"
00053 << option << " option." << endl;
00054 return s_status;
00055 }
00056
00057 static int extra(const char *text, char option)
00058 {
00059 err() << "extra text \"" << text << "\" encountered after -"
00060 << option << " option." << endl;
00061 return s_status;
00062 }
00063
00064 static int unreadable(const char *dirFile, char option)
00065 {
00066 err() << "unable to read \"" << dirFile << "\" for -"
00067 << option << " option." << endl;
00068 return s_status;
00069 }
00070
00071 static int incorrect(const char *file, char option)
00072 {
00073 err() << "file \"" << file << "\" contained invalid contents for -"
00074 << option << " option." << endl;
00075 return s_status;
00076 }
00077
00078 static const char *getArg(int *i, int argc, char *argv[])
00079 {
00080 return 0 != argv[*i][2] ? argv[*i] + 2 :
00081 ++*i >= argc || '-' == argv[*i][0] ? "" : argv[*i];
00082 }
00083
00084 int main (int argc, char *argv[])
00085 {
00086 int argCount = 0;
00087 int fileFlag = 0;
00088 int suffixFlag = 1;
00089 int verifyFlag = 0;
00090 int extractFlag = 0;
00091
00092 idep_AliasDep environment;
00093 for (int i = 1; i < argc; ++i) {
00094 const char *word = argv[i];
00095 if ('-' == word[0]) {
00096 char option = word[1];
00097 switch(option) {
00098 case 'X': {
00099 const char *arg = getArg(&i, argc, argv);
00100 if (!*arg) {
00101 return missing("dir", option);
00102 }
00103 environment.addIgnoreName(arg);
00104 } break;
00105 case 'x': {
00106 const char *arg = getArg(&i, argc, argv);
00107 if (!*arg) {
00108 return missing("file", option);
00109 }
00110 if (0 != environment.readIgnoreNames(arg)) {
00111 return unreadable(arg, option);
00112 }
00113 } break;
00114 case 'a': {
00115 const char *arg = getArg(&i, argc, argv);
00116 if (!*arg) {
00117 return missing("file", option);
00118 }
00119 int s = environment.readAliases(cerr, arg);
00120 if (s < 0) {
00121 return unreadable(arg, option);
00122 }
00123 if (s > 0) {
00124 return incorrect(arg, option);
00125 }
00126 } break;
00127 case 'f': {
00128 const char *arg = getArg(&i, argc, argv);
00129 if (!*arg) {
00130 return missing("file", option);
00131 }
00132 if (0 != environment.readFileNames(arg)) {
00133 return unreadable(arg, option);
00134 }
00135 fileFlag = 1;
00136 } break;
00137 case 's': {
00138 const char *arg = word + 2;
00139 if (*arg) {
00140 return extra(arg, option);
00141 }
00142 suffixFlag = 0;
00143 } break;
00144 case 'v': {
00145 const char *arg = word + 2;
00146 if (*arg) {
00147 return extra(arg, option);
00148 }
00149 verifyFlag = 1;
00150 } break;
00151 case 'e': {
00152 const char *arg = word + 2;
00153 if (*arg) {
00154 return extra(arg, option);
00155 }
00156 extractFlag = 1;
00157 } break;
00158 default: {
00159 err() << "unknown option \"" << word << "\"." << endl
00160 << help();
00161 return s_status;
00162 } break;
00163 }
00164 }
00165 else {
00166 ++argCount;
00167 environment.addFileName(argv[i]);
00168 }
00169 }
00170
00171 if (!fileFlag && !argCount) {
00172 environment.inputFileNames();
00173 }
00174
00175 int result = extractFlag ? environment.extract(cout, cerr)
00176 : verifyFlag
00177 ? environment.verify(cerr)
00178 : environment.unpaired(cout, cerr, suffixFlag);
00179
00180 s_status = result < 0 ? IOERROR : result > 0 ? BAD : GOOD;
00181
00182 return s_status;
00183 }
00184