00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <unistd.h>
00027 #include <Basics.H>
00028 #include <Sequence.H>
00029 #include <Generics.H>
00030 #include <FS.H>
00031 #include <ParseImports.H>
00032
00033 using std::ostream;
00034 using std::cout;
00035 using std::cerr;
00036 using std::endl;
00037
00038 class ShowEntry {
00039 public:
00040 Text name;
00041 int depth;
00042 ShowEntry() throw () { }
00043 ShowEntry(const Text &name, int depth) throw ()
00044 : name(name), depth(depth) { }
00045 };
00046
00047 typedef Sequence<ShowEntry> ShowEntrySeq;
00048
00049 void Syntax(char *msg, char *arg = (char *)NULL) throw ()
00050 {
00051 cerr << "Error: " << msg;
00052 if (arg != (char *)NULL) cerr << ": '" << arg << "'";
00053 cerr << endl;
00054 cerr << "Syntax: vimports [-depth num] "
00055 << "[-elide name]... [-show name [depth]]... "
00056 << "[model]" << endl;
00057 exit(1);
00058 }
00059
00060 void Indent(ostream &os, int n) throw ()
00061 {
00062 for (; n > 0; n--) os << "| ";
00063 }
00064
00065 int Search(const Text &model, int depth, int elideDepth,
00066 const TextSeq &elideNames, const ShowEntrySeq &showNames) throw ()
00067 {
00068
00069
00070
00071
00072
00073
00074 int status = 0;
00075 Indent(cout, depth); cout << model;
00076 ImportSeq imports( 10);
00077 try {
00078 ParseImports::P(model, imports);
00079
00080
00081 bool elide = false;
00082 for (int i = 0; i < elideNames.size(); i++) {
00083 if (model.FindText(elideNames.get(i)) >= 0) {
00084 elide = true;
00085 break;
00086 }
00087 }
00088
00089 if (!elide) {
00090
00091 bool show = false;
00092 int maxShowDepth = 0;
00093 for (int i = 0; i < showNames.size(); i++) {
00094 if (model.FindText(showNames.get(i).name) >= 0) {
00095 show = true;
00096 if (maxShowDepth >= 0) {
00097 int thisDepth = showNames.get(i).depth;
00098 if (thisDepth < 0) maxShowDepth = thisDepth;
00099 else maxShowDepth = max(maxShowDepth, thisDepth);
00100 }
00101 }
00102 }
00103 if (show) {
00104
00105 elideDepth = maxShowDepth;
00106 if (elideDepth >= 0) elideDepth += depth;
00107 }
00108 }
00109
00110
00111 if (!elide && (elideDepth < 0 || depth < elideDepth)) {
00112 cout << endl;
00113 while (imports.size() > 0) {
00114 Import imp(*(imports.getlo()));
00115 delete imports.remlo();
00116 Search(imp.path, depth+1, elideDepth, elideNames, showNames);
00117 }
00118 } else {
00119 if (imports.size() > 0) cout << "...";
00120 cout << endl;
00121 }
00122 }
00123 catch (FS::DoesNotExist) {
00124 cerr << endl; Indent(cerr, depth);
00125 cerr << "vimports: model file " << model << " does not exist" << endl;
00126 status = 2;
00127 }
00128 catch (const FS::Failure &f) {
00129 cerr << endl << "vimports: " << f << endl;
00130 status = 4;
00131 }
00132 catch (const ParseImports::Error &err) {
00133 cerr << endl; Indent(cerr, depth);
00134 cerr << endl << "vimports: " << err << endl;
00135 status = 3;
00136 }
00137
00138 while (imports.size() > 0)
00139 delete imports.remlo();
00140 return status;
00141 }
00142
00143 static bool isnumber(char *s) throw ()
00144 {
00145 while (isdigit(*s)) s++;
00146 return (*s == '\0');
00147 }
00148
00149 int main(int argc, char *argv[])
00150 {
00151
00152
00153
00154
00155
00156
00157 int status;
00158
00159 int elideDepth = -1;
00160 TextSeq elideNames;
00161 ShowEntrySeq showNames;
00162
00163
00164 int arg = 1;
00165 while (arg < argc && *(argv[arg]) == '-') {
00166 if (strcmp(argv[arg], "-depth") == 0) {
00167 arg++;
00168 if (arg < argc) {
00169 int res = sscanf(argv[arg], "%d", &elideDepth);
00170 if (res != 1) {
00171 Syntax("argument to '-depth' not a number", argv[arg]);
00172 }
00173 arg++;
00174 } else {
00175 Syntax("no argument to '-depth' switch");
00176 }
00177 } else if (strcmp(argv[arg], "-elide") == 0) {
00178 arg++;
00179 if (arg < argc) {
00180 elideNames.addhi(argv[arg++]);
00181 } else {
00182 Syntax("no argument to '-elide' switch");
00183 }
00184 } else if (strcmp(argv[arg], "-show") == 0) {
00185 arg++;
00186 if (arg < argc) {
00187 int depth = -1;
00188 Text name(argv[arg++]);
00189 if (arg < argc) {
00190 if (isnumber(argv[arg])) {
00191 int res = sscanf(argv[arg], "%d", &depth);
00192 assert(res == 1);
00193 arg++;
00194 } else if (*argv[arg] != '-' && arg != argc - 1) {
00195 Syntax("bad depth argument to '-show' switch",
00196 argv[arg]);
00197 }
00198 }
00199 showNames.addhi(ShowEntry(name, depth));
00200 } else {
00201 Syntax("no argument to '-show' switch");
00202 }
00203 } else {
00204 Syntax("unrecognized argument", argv[arg]);
00205 }
00206 }
00207 if (argc > arg+1) {
00208 Syntax("too many arguments");
00209 }
00210 Text model((arg < argc) ? argv[arg] : ".main.ves");
00211
00212
00213 char wd_buff[PATH_MAX+1];
00214 char *res = getcwd(wd_buff, PATH_MAX+1); assert(res != (char *)NULL);
00215 res = strcat(wd_buff, "/"); assert(res != (char *)NULL);
00216 Text wd(wd_buff);
00217
00218
00219
00220 status = Search(ParseImports::ResolvePath(model, wd),
00221 0, elideDepth,
00222 elideNames, showNames);
00223 return status;
00224 }
00225