00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdio.h>
00024 #include <string>
00025 #include <sys/types.h>
00026 #include <dirent.h>
00027 #include <vector>
00028 #include <sys/stat.h>
00029 #include <unistd.h>
00030 #include <map>
00031 #include "Parse.h"
00032 #include "SimpleParser.h"
00033 #include "BlackAdder.h"
00034 #include "dp.h"
00035
00036 #define DEB(x)
00037
00038
00039
00040
00041 namespace ugly {
00042 int beep;
00043 }
00044
00045 static BlackAdder add;
00046 config_m config;
00047 config_m box;
00048 std::string includes = "";
00049 std::string defines = "";
00050 int fontsize = 12;
00051 std::map<std::string, std::list<std::string> > group;
00052 int cluster = 1;
00053
00054
00055 std::string get_group(const std::string& class_name)
00056 {
00057 for (std::map<std::string, std::list<std::string> >::iterator it = group.begin(); it != group.end(); it++)
00058 {
00059 std::string group_name = it -> first;
00060 std::list<std::string>& ref = it -> second;
00061 for (std::list<std::string>::iterator it = ref.begin(); it != ref.end(); it++)
00062 {
00063 if (*it == class_name)
00064 return group_name;
00065 }
00066 }
00067 return "";
00068 }
00069
00070
00071 void read_makefile()
00072 {
00073 FILE *fil;
00074 if ((fil = fopen("Makefile","rt")) != NULL)
00075 {
00076 char slask[1000];
00077 fgets(slask,1000,fil);
00078 while (!feof(fil))
00079 {
00080 slask[strlen(slask) - 1] = 0;
00081 if (*slask != '#')
00082 {
00083 Parse pa(slask);
00084 strcpy(slask,pa.getword().c_str());
00085 while (*slask)
00086 {
00087 if (!strncmp(slask,"-I",2))
00088 {
00089 if (includes.size())
00090 includes += " ";
00091 includes += slask;
00092 }
00093 if (!strncmp(slask,"-D",2))
00094 {
00095 if (defines.size())
00096 defines += " ";
00097 defines += slask;
00098 }
00099
00100 strcpy(slask,pa.getword().c_str());
00101 }
00102 }
00103
00104 fgets(slask,1000,fil);
00105 }
00106 fclose(fil);
00107 }
00108 }
00109
00110
00111
00112
00113 void parse_file(const std::string &path,const std::string &filename)
00114 {
00115 std::string cmd;
00116 std::string out;
00117 out = path + "/" + filename + ".preprocessed";
00118 out = "/tmp/" + filename + ".preprocessed";
00119 cmd = "/usr/bin/cpp"
00120
00121 " -I."
00122
00123 " " + includes + " " + defines + " " + path + "/" + filename + " > " + out;
00124 fprintf(stderr, "%s\n", cmd.c_str());
00125 if (system( cmd.c_str() ) == -1)
00126 {
00127 DEB( fprintf(stderr,"Command failed: '%s'...\n",cmd.c_str());)
00128 }
00129 else
00130 {
00131 FILE *fil = fopen(out.c_str(),"rt");
00132 if (fil)
00133 {
00134 SimpleParser p(path,&add);
00135 int line = 0;
00136 std::string name;
00137 name = path + "/";
00138 name += filename;
00139 add.clear_using();
00140 p.Parser(fil,line,name);
00141 fclose(fil);
00142 unlink(out.c_str());
00143 }
00144 }
00145 }
00146
00147
00148 void loop(std::list<std::pair<std::string, std::string> >& vec, const std::string &path, bool recursive)
00149 {
00150 DIR *d;
00151 struct dirent *p;
00152 struct stat st;
00153 char filename[4000];
00154 if ((d = opendir(path.c_str())) != NULL)
00155 {
00156 p = readdir(d);
00157 while (p)
00158 {
00159 sprintf(filename,"%s/%s",path.c_str(),p -> d_name);
00160 stat(filename, &st);
00161
00162 if (S_ISDIR(st.st_mode))
00163 {
00164 if (p -> d_name[0] != '.' && recursive)
00165 {
00166 std::string subdir = path;
00167 subdir += "/";
00168 subdir += p -> d_name;
00169 loop( vec, subdir, recursive );
00170 }
00171 }
00172 else
00173 {
00174 if (
00175
00176 !strcasecmp(p -> d_name + strlen(p -> d_name) - 4,".cpp") ||
00177
00178 !strcasecmp(p -> d_name + strlen(p -> d_name) - 3,".cc") ||
00179 !strcasecmp(p -> d_name + strlen(p -> d_name) - 4,".c")
00180 )
00181 {
00182 fprintf(stderr, ">>>> File %s\n", p -> d_name);
00183
00184 vec.push_back( std::pair<std::string, std::string>(path, p -> d_name) );
00185 }
00186 }
00187
00188 p = readdir(d);
00189 }
00190 closedir(d);
00191 }
00192 }
00193
00194
00195 int main(int argc,char *argv[])
00196 {
00197 if (argc < 2)
00198 {
00199 printf("Usage: %s <options>\n", *argv);
00200 printf(" -fontsize xx Use custom font size\n");
00201 printf(" -Dxxx Define symbol 'xxx'\n");
00202 printf(" -Ixxx Add include path\n");
00203 printf(" -box <namespace> Add box around namespace\n");
00204 printf(" -group name class1 class2 class3 -\n");
00205 printf(" Group classes together, end with \"-\"\n");
00206
00207 printf(" -dot Print .dot display source to stdout\n");
00208 printf(" -lr Change orientation\n");
00209 printf(" -cluster \n");
00210 printf(" -r Find source files recursively\n");
00211 return -1;
00212 }
00213 char *args[] = {"-dot","-lr","-cluster","-r",""};
00214 read_makefile();
00215 for (int i = 1; i < argc; i++)
00216 {
00217 bool ok = false;
00218 bool more = false;
00219 int x = 0;
00220 if (!strcmp(argv[i], "-fontsize") && i < argc - 1)
00221 {
00222 fontsize = atoi(argv[++i]);
00223 }
00224 else
00225 if (!strncmp(argv[i], "-D", 2))
00226 {
00227 if (defines.size())
00228 defines += " ";
00229 defines += argv[i];
00230 }
00231 else
00232 if (!strncmp(argv[i], "-I", 2))
00233 {
00234 if (includes.size())
00235 includes += " ";
00236 includes += argv[i];
00237 }
00238 else
00239 if (!strcmp(argv[i],"-box"))
00240 {
00241 box[argv[i + 1]] = "true";
00242 i++;
00243 }
00244 else
00245 if (!strcmp(argv[i], "-group") && i < argc - 1)
00246 {
00247 std::string group_name = argv[++i];
00248 i++;
00249 while (i < argc && strcmp(argv[i], "-"))
00250 {
00251 group[group_name].push_back( argv[i] );
00252
00253 i++;
00254 }
00255 }
00256 else
00257 {
00258 while (*args[x])
00259 {
00260 if (!strcmp(argv[i],args[x]))
00261 {
00262 ok = true;
00263
00264 break;
00265 }
00266 else
00267 {
00268 x++;
00269 }
00270 }
00271 if (ok)
00272 {
00273 if (more)
00274 {
00275 config[argv[i]] = argv[i + 1];
00276 i++;
00277 }
00278 else
00279 {
00280 config[argv[i]] = "true";
00281 }
00282 }
00283 else
00284 {
00285 return -1;
00286 }
00287 }
00288 }
00289 std::list<std::pair<std::string, std::string> > vec;
00290 loop(vec, ".", config["-r"] == "true");
00291 char cwd[200];
00292 getcwd(cwd, 200);
00293 for (std::list<std::pair<std::string, std::string> >::iterator it = vec.begin(); it != vec.end(); it++)
00294 {
00295 std::pair<std::string, std::string>& ref = *it;
00296 chdir( ref.first.c_str() );
00297 parse_file( ".", ref.second );
00298 chdir( cwd );
00299 }
00300 if (config["-dot"] == "true")
00301 {
00302 printf("digraph test {\n");
00303 printf("\tURL=\"index.html\"\n");
00304 if (config["-lr"] == "true")
00305 printf(" rankdir=LR;\n");
00306 printf(" node [shape=box style=filled fillcolor=\"#ffffff\" fontsize=9]\n");
00307 add.MakeDot();
00308 for (std::map<std::string, std::list<std::string> >::iterator it = group.begin(); it != group.end(); it++)
00309 {
00310 std::string group_name = it -> first;
00311 printf(" subgraph cluster_%ld {\n",cluster++);
00312 printf(" style=filled;\n");
00313 printf(" fillcolor=lightgrey;\n");
00314 printf(" label=\"Group '%s'\"\n",group_name.c_str());
00315 if (config["-lr"] != "true")
00316 printf(" rankdir=LR;\n");
00317 printf(" node [shape=box style=filled fillcolor=white]\n");
00318 add.MakeDot( group_name );
00319 printf(" }\n");
00320 }
00321
00322 printf("}\n");
00323 }
00324 }
00325
00326