00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #if HAVE_DIRENT_H
00020 # include <dirent.h>
00021 #else
00022 # define dirent direct
00023 # if HAVE_SYS_NDIR_H
00024 # include <sys/ndir.h>
00025 # endif
00026 # if HAVE_SYS_DIR_H
00027 # include <sys/dir.h>
00028 # endif
00029 # if HAVE_NDIR_H
00030 # include <ndir.h>
00031 # endif
00032 #endif
00033
00034
00035 #define DOT_OR_DOTDOT(Basename) \
00036 (Basename[0] == '.' && (Basename[1] == '\0' \
00037 || (Basename[1] == '.' && Basename[2] == '\0')))
00038
00039 #define xstrdup strdup
00040 #define xrealloc realloc
00041
00042
00043
00044
00045 #ifndef HAVE_STRUCT_STAT_ST_BLOCKS
00046 # define ST_BLKSIZE(statbuf) DEV_BSIZE
00047 # if defined(_POSIX_SOURCE) || !defined(BSIZE)
00048 # define ST_NBLOCKS(statbuf) \
00049 (S_ISREG ((statbuf).st_mode) \
00050 || S_ISDIR ((statbuf).st_mode) \
00051 ? (statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0) : 0)
00052 # else
00053 # define ST_NBLOCKS(statbuf) \
00054 (S_ISREG ((statbuf).st_mode) \
00055 || S_ISDIR ((statbuf).st_mode) \
00056 ? st_blocks ((statbuf).st_size) : 0)
00057 # endif
00058 #else
00059
00060 # define ST_BLKSIZE(statbuf) ((statbuf).st_blksize > 0 \
00061 ? (statbuf).st_blksize : DEV_BSIZE)
00062 # if defined(hpux) || defined(__hpux__) || defined(__hpux)
00063
00064
00065 # define ST_NBLOCKSIZE 1024
00066 # else
00067 # if defined(_AIX) && defined(_I386)
00068
00069 # define ST_NBLOCKSIZE (4 * 1024)
00070 # else
00071 # if defined(_CRAY)
00072 # define ST_NBLOCKS(statbuf) \
00073 (S_ISREG ((statbuf).st_mode) \
00074 || S_ISDIR ((statbuf).st_mode) \
00075 ? (statbuf).st_blocks * ST_BLKSIZE(statbuf)/ST_NBLOCKSIZE : 0)
00076 # endif
00077 # endif
00078 # endif
00079 #endif
00080
00081 #ifndef ST_NBLOCKS
00082 # define ST_NBLOCKS(statbuf) \
00083 (S_ISREG ((statbuf).st_mode) \
00084 || S_ISDIR ((statbuf).st_mode) \
00085 ? (statbuf).st_blocks : 0)
00086 #endif
00087
00088 #ifndef ST_NBLOCKSIZE
00089 # define ST_NBLOCKSIZE 512
00090 #endif
00091
00092 #ifndef O_DIRECTORY
00093 # define O_DIRECTORY 0
00094 #endif
00095
00096 #if CLOSEDIR_VOID
00097
00098 # define CLOSEDIR(d) (closedir (d), 0)
00099 #else
00100 # define CLOSEDIR(d) closedir (d)
00101 #endif
00102
00103 #if STDC_HEADERS || (!defined (isascii) && !HAVE_ISASCII)
00104 # define IN_CTYPE_DOMAIN(c) 1
00105 #else
00106 # define IN_CTYPE_DOMAIN(c) isascii(c)
00107 #endif
00108
00109 #define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
00110
00111 using std::cout;
00112 using std::endl;
00113
00114 using SigC::slot;
00115
00119 struct String
00120 {
00121 unsigned alloc;
00122 unsigned length;
00123 char *text;
00124 };
00125 typedef struct String String;
00126
00132 class DirTree
00133 {
00134 private:
00135 struct exclude_st *exclude;
00136 String *path;
00137 int (*xstat) (const char *, struct stat *buf);
00138 int exit_status;
00139 uintmax_t tot_size;
00140 struct htab *htab;
00141
00142
00143
00144
00145
00146
00147
00148
00149 void hash_init (unsigned int modulus, unsigned int entry_tab_size);
00150 int hash_insert2 (struct htab *ht, ino_t ino, dev_t dev);
00151 int hash_insert (ino_t ino, dev_t dev);
00152 void hash_reset (void);
00153
00154 uintmax_t count_entry (const char *ent, int top, dev_t last_dev, int depth,
00155 EnTree *target);
00156 uintmax_t propogate_up(uintmax_t size, EnTree *target);
00157
00158 void init();
00159 Watcher<DirTree> *my_watch;
00160 public:
00162 bool opt_count_all;
00163 bool opt_dereference_arguments;
00165 bool opt_one_file_system;
00166 bool opt_separate_dirs;
00168 bool opt_all;
00170 bool up_immediate;
00172 int max_depth;
00173
00174 DirTree();
00175 void calc_EnTree(const char *target, EnTree *my_tree);
00176 void set_watcher(Watcher<DirTree> &my_watch);
00177 };
00178
00179
00183 class TreeView: public ImageMap, public Watcher<DirTree>,
00184 public RegionWatcher<EntryRect>
00185 {
00186 private:
00187 std::auto_ptr<EnTree> my_tree;
00188 EnTree const *cur_tree;
00189 bool firsttime;
00190 uintmax_t oldsize;
00191 DirTree treeGen;
00192 std::auto_ptr<Drawer> dwr;
00193 std::auto_ptr<ColorPicker> cpick;
00194 bool drawing;
00195
00196 public:
00197 RecTransform rt;
00198 TreeView(gint x_size = 0, gint y_size = 0);
00199
00200 EnTree const &get_EnTree() const;
00201
00202 void set_EnTree(EnTree const &newcur);
00203
00204 EnTree const &get_top_EnTree() const;
00205
00206 void modified(DirTree const &moddir);
00207
00208 void EnTree_rect(EnTree const *curent, bool vertical, gint x, gint y,
00209 gint width, gint height);
00210
00211 void draw_rect();
00212
00213 bool isReady();
00214
00215 void test_tree();
00216
00217 void setDrawer(Drawer *d)
00218 {
00219 dwr.reset(d);
00220 }
00221
00222 void set_cpick(ColorPicker *cp)
00223 {
00224 cpick.reset(cp);
00225 }
00226
00227 Drawer *getDrawer()
00228 {
00229 return dwr.get();
00230 }
00231
00232 gint expose_event_impl(GdkEventExpose*);
00233
00234 gint delayed_calc();
00235
00236 bool clicked(EntryRect const *, int button);
00237 virtual bool region_hover(EntryRect ®ion)
00238 {
00239 me_modified();
00240
00241 return true;
00242 }
00243 };
00244
00245
00246 #define INITIAL_HASH_MODULE 100
00247
00248
00249 #define INITIAL_ENTRY_TAB_SIZE 70
00250
00251
00252 #define INITIAL_PATH_SIZE 100
00253
00254 #include "commandbutton.h"
00258 class MainWindow: public Gtk::Window, public Watcher<ImageMap>
00259 {
00260 private:
00261 Gtk::Button child_button;
00262 Gtk::Button next_button;
00263 Gtk::Button prev_button;
00264 Gtk::Button parent_button;
00265 Gtk::Label curdir;
00266 Gtk::VBox packer;
00267 Gtk::HBox buttons;
00268 Gtk::HBox hbox;
00269 Gtk::HBox buttonslabel;
00270 TreeView tview;
00271 CommandButton rbutton;
00272 CommandButton colorbutton;
00273 void nav(EnTree &en_new)
00274 {
00275
00276 tview.set_EnTree(en_new);
00277 }
00278 void nav_child()
00279 {
00280 EnTree *child=tview.get_EnTree().child;
00281 if (child!=NULL) nav(*child);
00282 }
00283 void nav_next()
00284 {
00285 EnTree *next=tview.get_EnTree().next;
00286 if (next!=NULL) nav(*next);
00287 }
00288 void nav_prev()
00289 {
00290 EnTree *prev=tview.get_EnTree().prev;
00291 if (prev!=NULL) nav(*prev);
00292 }
00293 void nav_parent()
00294 {
00295 if (! tview.isReady()) return;
00296
00297 EnTree *parent=tview.get_EnTree().parent;
00298 if (parent!=NULL) nav(*parent);
00299 }
00300 void setInfo(EnTree const &cur, EnTree const &top);
00301
00302 public:
00303 MainWindow();
00304 virtual int delete_event_impl(GdkEventAny *event);
00305 void modified(const ImageMap &);
00306 gint delayed_calc()
00307 {
00308 return false;
00309 }
00310 };
00311
00312 struct entry
00313 {
00314 ino_t ino;
00315 dev_t dev;
00316 struct entry *coll_link;
00317 };
00318
00319 struct htab
00320 {
00321 unsigned modulus;
00322 struct entry *entry_tab;
00323 unsigned entry_tab_size;
00324 unsigned first_free_entry;
00325 struct entry *hash[1];
00326 };
00327
00328