From 35fa410fc753d32f88855c87670db443b3f63a61 Mon Sep 17 00:00:00 2001 From: Peter Marquardt Date: Tue, 18 Jul 2017 11:37:57 +0200 Subject: [PATCH] compiles like a charm --- Makefile | 13 +- README | 94 ---- README.md | 99 ++++ XDu.ad | 18 + xdu.c | 1380 ++++++++++++++++++++++++++--------------------------- xwin.c | 541 +++++++++++---------- 6 files changed, 1087 insertions(+), 1058 deletions(-) delete mode 100644 README create mode 100644 README.md create mode 100644 XDu.ad diff --git a/Makefile b/Makefile index 7db6931..59e8ac5 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,9 @@ -CC=gcc +# -CFLAGS=-Wall -Werror -Wextra -pedantic +CFLAGS= -Wall -Werror -Wextra -pedantic \ + -std=gnu99 -LDFLAGS=-lm -lXaw -lXmu -lXt -lSM -lICE -lXpm -lXext -lX11 +LDFLAGS=-lm -lXaw -lXt -lX11 # gcc -o xdu -O2 -fno-strength-reduce -fno-strict-aliasing -L/usr/lib64 xdu.o xwin.o -lXaw -lXmu -lXt -lSM -lICE -lXpm -lXext -lX11 SRCS = xdu.c xwin.c @@ -15,7 +16,11 @@ xdu: $(OBJS) xwin.o: xwin.c +xdu.o: xdu.c + clean: rm -f xdu xdu.o xwin.o -# +.PHONY: nice +nice: + indent -kr -l0 --no-tabs $(SRCS) diff --git a/README b/README deleted file mode 100644 index 84b306e..0000000 --- a/README +++ /dev/null @@ -1,94 +0,0 @@ -================================================================ -XDU - Display the output of "du" in an X window -================================================================ - -XDU is a program for displaying a graphical tree of disk space -utilization as reported by the UNIX utility "du". You can -navigate up and down in the tree, sort things, and print out -information. See the manual page for details. - -This program can be found by anonymous ftp at - - ftp.arl.mil:pub/xdu-3.0.tar.Z - -and should appear in the X11R6 contrib files. - -================================================================ -Compilation -================================================================ - -Use "xmkmf" to build a Makefile from the Imakefile. -Then "make", "make install", "make install.man". -But if for some reason you can't do that, try: - - cc -o xdu xdu.c xwin.c -lXaw -lXt -lXext -lX11 - -See the XDu.ad file if e.g. you have problems with - the selected font. - -This release was tested against X11R6 patch level 1 on an -SGI running Irix 5.2. It has been tested against X11R5 on -SunOS 4.1.3, SunOS 5.2 (Solaris), SGI Irix 4.0.5, Gould -UTX 2.1. - -================================================================ -Revision History -================================================================ - -Version 3.0 5 Jun 94 - X11R6 contrib release - Popup help window - Now uses Athena widgets, but no menus or buttons yet - -Version 2.1 22 Jul 93 - Fixed a bug in the sorting code where traversal back up a - sorted tree could land you in the wrong parent directory. - -Version 2.0 21 Jul 93 - Added sorting. - Command line options. - More resources. - Better redraw behavior. - Bug fixes (to handle trailing slashes and directories - with no or zero size information). - -Version 1.1 5 Oct 91 - Added resource control - Display of size information - More accurate label positioning - -Version 1.0 4 Sep 91 - First public release - -================================================================ -Remaining Bug? -================================================================ - - On startup on a Sun (but not on an SGI), keyboard input - may not be received by the application until you move the - mouse out of and back into the window. Button presses are - fine. Does anyone know what's going on there? - Mark Evans pointed out a fix - now in the BUG section of - the manual page, but I would still like to hear how/why - this happens. - -================================================================ -Acknowledgements -================================================================ -Thanks for bug reports and code fixes from: - -Casey Leedom -Stephen Gildea -Nelson Minar -Don Tiessen -Gerry.Tomlinson@newcastle.ac.uk -Mark Evans -Juha Takala - -And the many others who told me what they thought about it. - -Send any bugs/comments to: - -Phil Dykstra - -http://info.arl.mil/~phil/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..c5262a9 --- /dev/null +++ b/README.md @@ -0,0 +1,99 @@ +# xdu (patched) - display the output of `du -k` in an X window + +`xdu` is a program for displaying a graphical tree of disk space utilization as reported by the UNIX utility `du`. You can navigate up and down in the tree, sort things, and print out information. See the manual page for details. + +This version has been patched for more functions. +- key `n` : change size display ( bytes, MiB, GiB, TiB ) +- key `p` : print as postscript +- option `-f` : set postscript file name + +This is a *works-for-me* release. + +## compilation + +`make` + +## installation + +`cp` + + +No `autoconf`, `hg`, `docker`, `what-ever`. Never. Ever. This is ~1500 lines of pure C. Get a life! + +See the `XDu.ad` file if e.g. you have problems with the selected font. + + +## usage + +``` +du -k /usr | xdu +``` + +This release was tested against MarIuX. + +## Revision History + +### Version 3.0p6 - Jul 10 2017 +- `githubify` +- code cleanup for fixing bugs +- *works-for-me* Makefile +- `-Wall -Werror -Wextra -pedantic` +- Peter Marquardt, `marquardt_p@molgen.mpg.de` + +### Version 3.0p5 - Feb 16 2012 + +### Version 3.0p4 - Mar 16 2007 + +### Version 3.0p3 - Apr 9 1997 +- new option `-f` and new key `p` +- Marius Tolzmann, `tolzmann@mpimg-berlin-dahlem.mpg.de` + +### Version 3.0p2 - Oct 1 1998 +- added ability to print postscriptfiles Thr Oct 1 12:17 MET DST 1998 by +- Marius Tolzmann, `tolzmann@mpimg-berlin-dahlem.mpg.de` + +### Version 3.0 5 - Jun 1994 +- X11R6 contrib release +- Popup help window +- Now uses Athena widgets, but no menus or buttons yet + +### Version 2.1 22 - Jul 1993 +- Fixed a bug in the sorting code where traversal back up a sorted tree could land you in the wrong parent directory. + +### Version 2.0 21 - Jul 1993 +- Added sorting. +- Command line options. +- More resources. +- Better redraw behavior. +- Bug fixes (to handle trailing slashes and directories with no or zero size information). + +### Version 1.1 5 - Oct 1991 +- Added resource control +- Display of size information +- More accurate label positioning + +### Version 1.0 4 - Sep 1991 +- First public release + +# Acknowledgements + +## xdu-3.0p +Marius Tolzmann +Peter Marquardt + +## xdu-3.0 +Bug reports and code fixes from: + +Casey Leedom `` +Stephen Gildea `` +Nelson Minar `` +Don Tiessen `` +Gerry Tomlinson `Gerry.Tomlinson@newcastle.ac.uk` +Mark Evans `` +Juha Takala `` + +And the many others who told me what they thought about it. + +Originally developed by: + +Phil Dykstra, `` `http://info.arl.mil/~phil/` diff --git a/XDu.ad b/XDu.ad new file mode 100644 index 0000000..b57933d --- /dev/null +++ b/XDu.ad @@ -0,0 +1,18 @@ +! +! XDu Resources +! +! I recommend the "-*-helvetica-bold-r-normal--14-*" font, but if +! you don't have it, or want your server default, then change it +! or comment it out respectively. +! Order choices: first, last, alpha, ralpha, size, rsize +! Color to taste. +! +!XDu*foreground: yellow +!XDu*background: blue4 +!XDu*help*foreground: green +!XDu*help*background: red4 +XDu*window.width: 600 +XDu*window.height: 480 +XDu.font: -misc-fixed-medium-*-*-*-10-*-*-*-*-*-*-* +XDu.ncol: 5 +XDu.psfile: xdu_out.ps diff --git a/xdu.c b/xdu.c index 6b9f5f9..3c21373 100644 --- a/xdu.c +++ b/xdu.c @@ -7,7 +7,7 @@ * Phillip C. Dykstra * * 4 Sep 1991. - * + * * Copyright (c) Phillip C. Dykstra 1991, 1993, 1994 * The X Consortium, and any party obtaining a copy of these files from * the X Consortium, directly or indirectly, is granted, free of charge, a @@ -26,19 +26,26 @@ * added ability to print postscriptfiles Thr Oct 1 12:17 MET DST 1998 by * Marius Tolzmann, tolzmann@mpimg-berlin-dahlem.mpg.de * (new option -f and new key p !!!) + * + * reworked Mon Jul 10 10:55:44 CEST 2017 + * Peter Marquardt, marquardt_p@molgen.mpg.de + * - 'worksforme' Makefile + * - -Wall -Werror -Wextra -pedantic + * */ - + #include #include #include +#include #include "version.h" /*extern char *malloc(), *calloc();*/ -#define MAXDEPTH 80 /* max elements in a path */ -#define MAXNAME 1024 /* max pathname element length */ -#define MAXPATH 4096 /* max total pathname length */ -#define NCOLS 5 /* default number of columns in display */ +#define MAXDEPTH 80 /* max elements in a path */ +#define MAXNAME 1024 /* max pathname element length */ +#define MAXPATH 4096 /* max total pathname length */ +#define NCOLS 5 /* default number of columns in display */ /* What we IMPORT from xwin.c */ extern int xsetup(), xmainloop(), xdrawrect(), xrepaint(); @@ -49,9 +56,7 @@ extern int xsetup(), xmainloop(), xdrawrect(), xrepaint(); int ncols = NCOLS; /* internal routines */ -#ifdef NEED_STRDUP -char *strdup(); -#endif +// char *strdup(); void addtree(); void parse_file(); void parse_entry(); @@ -75,10 +80,10 @@ int order = ORD_DEFAULT; * so that we can "find" it again on key presses. */ struct rect { - int left; - int top; - int width; - int height; + int left; + int top; + int width; + int height; }; /* @@ -86,13 +91,13 @@ struct rect { * Each node in the path tree is linked in with one of these. */ struct node { - char *name; - long long size; /* from here down in the tree */ - long num; /* entry number - for resorting */ - struct rect rect; /* last drawn screen rectangle */ - struct node *peer; /* siblings */ - struct node *child; /* list of children if !NULL */ - struct node *parent; /* backpointer to parent */ + char *name; + long long size; /* from here down in the tree */ + long num; /* entry number - for resorting */ + struct rect rect; /* last drawn screen rectangle */ + struct node *peer; /* siblings */ + struct node *child; /* list of children if !NULL */ + struct node *parent; /* backpointer to parent */ } top; struct node *topp = ⊤ #define NODE_NULL ((struct node *)0) @@ -101,68 +106,64 @@ long nnodes = 0; /* * create a new node with the given name and size info */ -struct node * -makenode(name,size) +struct node *makenode(name, size) char *name; long long size; { - struct node *np; + struct node *np; - np = (struct node *)calloc(1,sizeof(struct node)); - np->name = strdup(name); - np->size = size; - np->num = nnodes; - nnodes++; + np = (struct node *) calloc(1, sizeof(struct node)); + np->name = strdup(name); + np->size = size; + np->num = nnodes; + nnodes++; - return np; + return np; } /* * Return the node (if any) which has a draw rectangle containing * the given x,y point. */ -struct node * -findnode(treep, x, y) -struct node *treep; -int x, y; +struct node *findnode(treep, x, y) +struct node *treep; +int x, y; { - struct node *np; - struct node *np2; + struct node *np; + struct node *np2; - if (treep == NODE_NULL) - return NODE_NULL; + if (treep == NODE_NULL) + return NODE_NULL; - if (x >= treep->rect.left && x < treep->rect.left+treep->rect.width - && y >= treep->rect.top && y < treep->rect.top+treep->rect.height) { - /*printf("found %s\n", treep->name);*/ - return treep; /* found */ - } + if (x >= treep->rect.left && x < treep->rect.left + treep->rect.width && y >= treep->rect.top && y < treep->rect.top + treep->rect.height) { + /*printf("found %s\n", treep->name); */ + return treep; /* found */ + } - /* for each child */ - for (np = treep->child; np != NULL; np = np->peer) { - if ((np2 = findnode(np,x,y)) != NODE_NULL) - return np2; - } - return NODE_NULL; + /* for each child */ + for (np = treep->child; np != NULL; np = np->peer) { + if ((np2 = findnode(np, x, y)) != NODE_NULL) + return np2; + } + return NODE_NULL; } /* * return a count of the number of children of a given node */ -int -numchildren(nodep) +int numchildren(nodep) struct node *nodep; { - int n; + int n; - if (nodep == NODE_NULL) - return 0; + if (nodep == NODE_NULL) + return 0; - n = 0; - for (nodep = nodep->child; nodep != NODE_NULL; nodep=nodep->peer) - n++; + n = 0; + for (nodep = nodep->child; nodep != NODE_NULL; nodep = nodep->peer) + n++; - return n; + return n; } /* @@ -170,22 +171,21 @@ struct node *nodep; * had their sizes initialized. [DPT911113] * * * * This function is recursive * * * */ -long -fix_tree(top) +long fix_tree(top) struct node *top; { - struct node *nd; + struct node *nd; - if (top == NODE_NULL) /* recursion end conditions */ - return 0; - if (top->size >= 0) /* also halt recursion on valid size */ - return top->size; /* (remember: sizes init. to -1) */ + if (top == NODE_NULL) /* recursion end conditions */ + return 0; + if (top->size >= 0) /* also halt recursion on valid size */ + return top->size; /* (remember: sizes init. to -1) */ - top->size = 0; - for (nd = top->child; nd != NODE_NULL; nd = nd->peer) - top->size += fix_tree(nd); + top->size = 0; + for (nd = top->child; nd != NODE_NULL; nd = nd->peer) + top->size += fix_tree(nd); - return top->size; + return top->size; } static char usage[] = "\ @@ -205,114 +205,114 @@ Graphically displays the output of du in an X window\n\ Toolkit options: -fg, -bg, -rv, -display, -geometry, etc.\n\ "; -main(argc,argv) +int main(argc, argv) int argc; char **argv; { - top.name = strdup("[root]"); - top.size = -1; - - xsetup(&argc,argv); - if (argc == 1) { - if (isatty(fileno(stdin))) { - fprintf(stderr, usage); - exit(1); - } else { - parse_file("-"); - } - } else if (argc == 2 && strcmp(argv[1],"-help") != 0) { - parse_file(argv[1]); - } else { - fprintf(stderr, usage); - exit(1); - } - top.size = fix_tree(&top); - - /*dumptree(&top,0);*/ - if (order != ORD_DEFAULT) - sorttree(&top, order); - - topp = ⊤ - /* don't display root if only one child */ - if (numchildren(topp) == 1) - topp = topp->child; - - xmainloop(); - exit(0); -} - -void -parse_file(filename) + top.name = strdup("[root]"); + top.size = -1; + + xsetup(&argc, argv); + if (argc == 1) { + if (isatty(fileno(stdin))) { + fprintf(stderr, usage); + exit(1); + } else { + parse_file("-"); + } + } else if (argc == 2 && strcmp(argv[1], "-help") != 0) { + parse_file(argv[1]); + } else { + fprintf(stderr, usage); + exit(1); + } + top.size = fix_tree(&top); + + /*dumptree(&top,0); */ + if (order != ORD_DEFAULT) + sorttree(&top, order); + + topp = ⊤ + /* don't display root if only one child */ + if (numchildren(topp) == 1) + topp = topp->child; + + xmainloop(); + exit(0); +} + +void parse_file(filename) char *filename; { - char buf[4096]; - char name[4096]; - long long size; - FILE *fp; - char *buff; - - if (strcmp(filename, "-") == 0) { - fp = stdin; - } else { - if ((fp = fopen(filename, "r")) == 0) { - fprintf(stderr, "xdu: can't open \"%s\"\n", filename); - exit(1); - } - } - while (fgets(buf,sizeof(buf),fp) != NULL) { + char buf[4096]; + char name[4096]; + long long size; + FILE *fp; + char *buff; + + if (strcmp(filename, "-") == 0) { + fp = stdin; + } else { + if ((fp = fopen(filename, "r")) == 0) { + fprintf(stderr, "xdu: can't open \"%s\"\n", filename); + exit(1); + } + } + while (fgets(buf, sizeof(buf), fp) != NULL) { /* sscanf(buf, "%lld %s\n", &size, name); */ - sscanf(buf, "%lld", &size); - buff=buf; - while ( (*buff >= '0' && *buff <= '9') || (*buff == ' ' || *buff == '\t' ) ) { - buff++; - } - strncpy(name,buff,strlen(buff)-1); - name[strlen(buff)-1] = '\0'; + sscanf(buf, "%lld", &size); + buff = buf; + while ((*buff >= '0' && *buff <= '9') || (*buff == ' ' || *buff == '\t')) { + buff++; + } + strncpy(name, buff, strlen(buff) - 1); + name[strlen(buff) - 1] = '\0'; /* printf("%d %s\n", size, name); */ - parse_entry(name,size); - } - fclose(fp); + parse_entry(name, size); + } + fclose(fp); } /* bust up a path string and link it into the tree */ void parse_entry(char *name, long long size) { - char *path[MAXDEPTH]; /* break up path into this list */ - char buf[MAXNAME]; /* temp space for path element name */ - int arg, indx; - int length; /* nelson@reed.edu - trailing / fix */ - - if (*name == '/') - name++; /* skip leading / */ - - length = strlen(name); - if ((length > 0) && (name[length-1] == '/')) { - /* strip off trailing / (e.g. GNU du) */ - name[length-1] = 0; - } - - arg = 0; indx = 0; - bzero((char *)path,sizeof(path)); - bzero(buf,sizeof(buf)); - while (*name) { - if (*name == '/') { - buf[indx] = 0; - path[arg++] = strdup(buf); - indx = 0; - if (arg >= MAXDEPTH) - break; - } else { - buf[indx++] = *name; - if (indx >= MAXNAME) - break; - } - name++; - } - buf[indx] = 0; - path[arg++] = strdup(buf); - path[arg] = NULL; - - addtree(&top,path,size); + char *path[MAXDEPTH]; /* break up path into this list */ + char buf[MAXNAME]; /* temp space for path element name */ + int arg, indx; + int length; /* nelson@reed.edu - trailing / fix */ + + if (*name == '/') + name++; /* skip leading / */ + + length = strlen(name); + if ((length > 0) && (name[length - 1] == '/')) { + /* strip off trailing / (e.g. GNU du) */ + name[length - 1] = 0; + } + + arg = 0; + indx = 0; + bzero((char *) path, sizeof(path)); + bzero(buf, sizeof(buf)); + while (*name) { + if (*name == '/') { + buf[indx] = 0; + path[arg++] = strdup(buf); + indx = 0; + if (arg >= MAXDEPTH) + break; + } else { + buf[indx++] = *name; + if (indx >= MAXNAME) + break; + } + name++; + } + buf[indx] = 0; + path[arg++] = strdup(buf); + path[arg] = NULL; + + addtree(&top, path, size); } /* @@ -322,349 +322,338 @@ void parse_entry(char *name, long long size) * 0 if it is a toss up. * 1 if it should go after. */ -int -compare(n1,n2,order) +int compare(n1, n2, order) struct node *n1, *n2; int order; { - int ret; - - switch (order) { - case ORD_SIZE: - if (n2->size>n1->size) { - return 1; - } else if (n2->sizesize) { - return -1; - } else { - return strcmp(n1->name,n2->name); - } - /* not reached */ - case ORD_RSIZE: - if (n1->size>n2->size) { - return 1; - } else if (n1->sizesize) { - return -1; - } else { - return strcmp(n1->name,n2->name); - } - /* not reached */ - case ORD_ALPHA: - return strcmp(n1->name,n2->name); - break; - case ORD_RALPHA: - return strcmp(n2->name,n1->name); - break; - case ORD_FIRST: - /*return -1;*/ - return (n1->num - n2->num); - break; - case ORD_LAST: - /*return 1;*/ - return (n2->num - n1->num); - break; - } - - /* shouldn't get here */ - fprintf(stderr,"xdu: bad insertion order\n"); - return 0; -} - -void -insertchild(nodep,childp,order) -struct node *nodep; /* parent */ -struct node *childp; /* child to be added */ -int order; /* FIRST, LAST, ALPHA, SIZE */ -{ - struct node *np, *np1; - - if (nodep == NODE_NULL || childp == NODE_NULL) - return; - if (childp->peer != NODE_NULL) { - fprintf(stderr, "xdu: can't insert child with peers\n"); - return; - } - - childp->parent = nodep; - if (nodep->child == NODE_NULL) { - /* no children, order doesn't matter */ - nodep->child = childp; - return; - } - /* nodep has at least one child already */ - if (compare(childp,nodep->child,order) < 0) { - /* new first child */ - childp->peer = nodep->child; - nodep->child = childp; - return; - } - np1 = nodep->child; - for (np = np1->peer; np != NODE_NULL; np = np->peer) { - if (compare(childp,np,order) < 0) { - /* insert between np1 and np */ - childp->peer = np; - np1->peer = childp; - return; - } - np1 = np; - } - /* at end, link new child on */ - np1->peer = childp; + switch (order) { + case ORD_SIZE: + if (n2->size > n1->size) { + return 1; + } else if (n2->size < n1->size) { + return -1; + } else { + return strcmp(n1->name, n2->name); + } + /* not reached */ + case ORD_RSIZE: + if (n1->size > n2->size) { + return 1; + } else if (n1->size < n2->size) { + return -1; + } else { + return strcmp(n1->name, n2->name); + } + /* not reached */ + case ORD_ALPHA: + return strcmp(n1->name, n2->name); + break; + case ORD_RALPHA: + return strcmp(n2->name, n1->name); + break; + case ORD_FIRST: + /*return -1; */ + return (n1->num - n2->num); + break; + case ORD_LAST: + /*return 1; */ + return (n2->num - n1->num); + break; + } + + /* shouldn't get here */ + fprintf(stderr, "xdu: bad insertion order\n"); + return 0; +} + +void insertchild(nodep, childp, order) +struct node *nodep; /* parent */ +struct node *childp; /* child to be added */ +int order; /* FIRST, LAST, ALPHA, SIZE */ +{ + struct node *np, *np1; + + if (nodep == NODE_NULL || childp == NODE_NULL) + return; + if (childp->peer != NODE_NULL) { + fprintf(stderr, "xdu: can't insert child with peers\n"); + return; + } + + childp->parent = nodep; + if (nodep->child == NODE_NULL) { + /* no children, order doesn't matter */ + nodep->child = childp; + return; + } + /* nodep has at least one child already */ + if (compare(childp, nodep->child, order) < 0) { + /* new first child */ + childp->peer = nodep->child; + nodep->child = childp; + return; + } + np1 = nodep->child; + for (np = np1->peer; np != NODE_NULL; np = np->peer) { + if (compare(childp, np, order) < 0) { + /* insert between np1 and np */ + childp->peer = np; + np1->peer = childp; + return; + } + np1 = np; + } + /* at end, link new child on */ + np1->peer = childp; } /* add path as a child of top - recursively */ -void -addtree(top, path, size) +void addtree(top, path, size) struct node *top; char *path[]; long long size; { - struct node *np; - - /*printf("addtree(\"%s\",\"%s\",%d)\n", top->name, path[0], size);*/ - - /* check all children for a match */ - for (np = top->child; np != NULL; np = np->peer) { - if (strcmp(path[0],np->name) == 0) { - /* name matches */ - if (path[1] == NULL) { - /* end of the chain, save size */ - np->size = size; - return; - } - /* recurse */ - addtree(np,&path[1],size); - return; - } - } - /* no child matched, add a new child */ - np = makenode(path[0],-1); - insertchild(top,np,order); - - if (path[1] == NULL) { - /* end of the chain, save size */ - np->size = size; - return; - } - /* recurse */ - addtree(np,&path[1],size); - return; + struct node *np; + + /*printf("addtree(\"%s\",\"%s\",%d)\n", top->name, path[0], size); */ + + /* check all children for a match */ + for (np = top->child; np != NULL; np = np->peer) { + if (strcmp(path[0], np->name) == 0) { + /* name matches */ + if (path[1] == NULL) { + /* end of the chain, save size */ + np->size = size; + return; + } + /* recurse */ + addtree(np, &path[1], size); + return; + } + } + /* no child matched, add a new child */ + np = makenode(path[0], -1); + insertchild(top, np, order); + + if (path[1] == NULL) { + /* end of the chain, save size */ + np->size = size; + return; + } + /* recurse */ + addtree(np, &path[1], size); + return; } /* debug tree print */ -void -dumptree(np,level) +void dumptree(np, level) struct node *np; int level; { - int i; - struct node *subnp; + int i; + struct node *subnp; - for (i = 0; i < level; i++) - printf(" "); + for (i = 0; i < level; i++) + printf(" "); - printf("%s %d\n", np->name, np->size); - for (subnp = np->child; subnp != NULL; subnp = subnp->peer) { - dumptree(subnp,level+1); - } + printf("%s %lld\n", np->name, np->size); + for (subnp = np->child; subnp != NULL; subnp = subnp->peer) { + dumptree(subnp, level + 1); + } } -void -sorttree(np, order) +void sorttree(np, order) struct node *np; int order; { - struct node *subnp; - struct node *np0, *np1, *np2, *np3; - - /* sort the trees of each of this nodes children */ - for (subnp = np->child; subnp != NODE_NULL; subnp = subnp->peer) { - sorttree(subnp, order); - } - /* then put the given nodes children in order */ - np0 = np; /* np0 points to node before np1 */ - for (np1 = np->child; np1 != NODE_NULL; np1 = np1->peer) { - np2 = np1; /* np2 points to node before np3 */ - for (np3 = np1->peer; np3 != NODE_NULL; np3 = np3->peer) { - if (compare(np3,np1,order) < 0) { - /* swap links */ - if (np0 == np) - np0->child = np3; - else - np0->peer = np3; - np2->peer = np3->peer; - np3->peer = np1; - - /* adjust pointers */ - np1 = np3; - np3 = np2; - } - np2 = np3; - } - np0 = np1; - } + struct node *subnp; + struct node *np0, *np1, *np2, *np3; + + /* sort the trees of each of this nodes children */ + for (subnp = np->child; subnp != NODE_NULL; subnp = subnp->peer) { + sorttree(subnp, order); + } + /* then put the given nodes children in order */ + np0 = np; /* np0 points to node before np1 */ + for (np1 = np->child; np1 != NODE_NULL; np1 = np1->peer) { + np2 = np1; /* np2 points to node before np3 */ + for (np3 = np1->peer; np3 != NODE_NULL; np3 = np3->peer) { + if (compare(np3, np1, order) < 0) { + /* swap links */ + if (np0 == np) + np0->child = np3; + else + np0->peer = np3; + np2->peer = np3->peer; + np3->peer = np1; + + /* adjust pointers */ + np1 = np3; + np3 = np2; + } + np2 = np3; + } + np0 = np1; + } +} + +/* + * Draws all children of a node within the given rectangle. + * Recurses on children. + */ +void drawchildren(nodep, rect) +struct node *nodep; /* node whose children we should draw */ +struct rect rect; /* rectangle to draw all children in */ +{ + long long totalsize; + int totalheight; + struct node *np; + double fractsize; + int height; + int top; + long long size; + + /*printf("Drawing children of \"%s\", %d\n", nodep->name, nodep->size); */ + /*printf("In [%d,%d,%d,%d]\n", rect.left,rect.top,rect.width,rect.height); */ + + top = rect.top; + size = 0; + + + totalheight = rect.height; + totalsize = nodep->size; + if (totalsize == 0) { + /* total the sizes of the children */ + totalsize = 0; + for (np = nodep->child; np != NULL; np = np->peer) + totalsize += np->size; + nodep->size = totalsize; + } + + /* for each child */ + for (np = nodep->child; np != NULL; np = np->peer) { + fractsize = totalsize ? np->size / (double) totalsize : 0; + height = fractsize * totalheight + 0.5; + + { + struct rect subrect; + /* printf("%s, drawrect[%d,%d,%d,%d]\n", np->name, + rect.left,top,rect.width,height); */ + xdrawrect(np->name, np->size, rect.left, top, rect.width, height); + + /* save current screen rectangle for lookups */ + np->rect.left = rect.left; + np->rect.top = top; + np->rect.width = rect.width; + np->rect.height = height; + + + /* draw children in subrectangle */ + subrect.left = rect.left + rect.width; + subrect.top = top; + subrect.width = rect.width; + subrect.height = height; + drawchildren(np, subrect); + + size += np->size; + top = rect.top + (totalsize ? (double) size / totalsize * rect.height + 0.5 : 0); + } + } } /* * Draws a node in the given rectangle, and all of its children * to the "right" of the given rectangle. */ -drawnode(nodep, rect) -struct node *nodep; /* node whose children we should draw */ -struct rect rect; /* rectangle to draw all children in */ +void drawnode(nodep, rect) +struct node *nodep; /* node whose children we should draw */ +struct rect rect; /* rectangle to draw all children in */ { - struct rect subrect; + struct rect subrect; - /*printf("Drawing \"%s\" %d\n", nodep->name, nodep->size);*/ + /*printf("Drawing \"%s\" %d\n", nodep->name, nodep->size); */ - xdrawrect(nodep->name, nodep->size, - rect.left,rect.top,rect.width,rect.height); + xdrawrect(nodep->name, nodep->size, rect.left, rect.top, rect.width, rect.height); - /* save current screen rectangle for lookups */ - nodep->rect.left = rect.left; - nodep->rect.top = rect.top; - nodep->rect.width = rect.width; - nodep->rect.height = rect.height; + /* save current screen rectangle for lookups */ + nodep->rect.left = rect.left; + nodep->rect.top = rect.top; + nodep->rect.width = rect.width; + nodep->rect.height = rect.height; - /* draw children in subrectangle */ - subrect.left = rect.left+rect.width; - subrect.top = rect.top; - subrect.width = rect.width; - subrect.height = rect.height; - drawchildren(nodep, subrect); + /* draw children in subrectangle */ + subrect.left = rect.left + rect.width; + subrect.top = rect.top; + subrect.width = rect.width; + subrect.height = rect.height; + drawchildren(nodep, subrect); } -/* - * Draws all children of a node within the given rectangle. - * Recurses on children. - */ -drawchildren(nodep, rect) -struct node *nodep; /* node whose children we should draw */ -struct rect rect; /* rectangle to draw all children in */ -{ - long long totalsize; - int totalheight; - struct node *np; - double fractsize; - int height; - int top; - long long size; - - /*printf("Drawing children of \"%s\", %d\n", nodep->name, nodep->size);*/ - /*printf("In [%d,%d,%d,%d]\n", rect.left,rect.top,rect.width,rect.height);*/ - - top = rect.top; - size = 0; - - - totalheight = rect.height; - totalsize = nodep->size; - if (totalsize == 0) { - /* total the sizes of the children */ - totalsize = 0; - for (np = nodep->child; np != NULL; np = np->peer) - totalsize += np->size; - nodep->size = totalsize; - } - - /* for each child */ - for (np = nodep->child; np != NULL; np = np->peer) { - fractsize = totalsize ? np->size / (double)totalsize : 0; - height = fractsize * totalheight + 0.5; - - { - struct rect subrect; - /* printf("%s, drawrect[%d,%d,%d,%d]\n", np->name, - rect.left,top,rect.width,height); */ - xdrawrect(np->name, np->size, - rect.left,top,rect.width,height); - - /* save current screen rectangle for lookups */ - np->rect.left = rect.left; - np->rect.top = top; - np->rect.width = rect.width; - np->rect.height = height; - - - /* draw children in subrectangle */ - subrect.left = rect.left+rect.width; - subrect.top = top; - subrect.width = rect.width; - subrect.height = height; - drawchildren(np, subrect); - - size+=np->size; - top=rect.top+(totalsize ? (double)size/totalsize*rect.height+0.5 : 0); - } - } -} /* * clear the rectangle information of a given node * and all of its decendents */ -void -clearrects(nodep) -struct node *nodep; +void clearrects(nodep) +struct node *nodep; { - struct node *np; + struct node *np; - if (nodep == NODE_NULL) - return; + if (nodep == NODE_NULL) + return; - nodep->rect.left = 0; - nodep->rect.top = 0; - nodep->rect.width = 0; - nodep->rect.height = 0; + nodep->rect.left = 0; + nodep->rect.top = 0; + nodep->rect.width = 0; + nodep->rect.height = 0; - /* for each child */ - for (np = nodep->child; np != NULL; np = np->peer) { - clearrects(np); - } + /* for each child */ + for (np = nodep->child; np != NULL; np = np->peer) { + clearrects(np); + } } -pwd() +void pwd(void) { - struct node *np; - struct node *stack[MAXDEPTH]; - int num = 0; - struct node *rootp; - char path[MAXPATH]; + struct node *np; + struct node *stack[MAXDEPTH]; + int num = 0; + struct node *rootp; + char path[MAXPATH]; - rootp = ⊤ - if (numchildren(rootp) == 1) - rootp = rootp->child; + rootp = ⊤ + if (numchildren(rootp) == 1) + rootp = rootp->child; - np = topp; - while (np != NODE_NULL) { - stack[num++] = np; - if (np == rootp) - break; - np = np->parent; - } + np = topp; + while (np != NODE_NULL) { + stack[num++] = np; + if (np == rootp) + break; + np = np->parent; + } - path[0] = '\0'; - while (--num >= 0) { - strcat(path,stack[num]->name); - if (num != 0) - strcat(path,"/"); - } - printf("%s %lld (%.2f%%)\n", path, topp->size, - 100.0*topp->size/rootp->size); + path[0] = '\0'; + while (--num >= 0) { + strcat(path, stack[num]->name); + if (num != 0) + strcat(path, "/"); + } + printf("%s %lld (%.2f%%)\n", path, topp->size, 100.0 * topp->size / rootp->size); } #ifdef NEED_STRDUP -char * -strdup(s) +char *strdup(s) char *s; { - int n; - char *cp; + int n; + char *cp; - n = strlen(s); - cp = malloc(n+1); - strcpy(cp,s); + n = strlen(s); + cp = malloc(n + 1); + strcpy(cp, s); - return cp; + return cp; } #endif @@ -672,112 +661,112 @@ char *s; void press(int x, int y) { - struct node *np; + struct node *np; - /*printf("press(%d,%d)...\n",x,y);*/ - np = findnode(&top,x,y); - /*printf("Found \"%s\"\n", np?np->name:"(null)");*/ - if (np == topp) { - /* already top, go up if possible */ - if (np->parent != &top || numchildren(&top) != 1) - np = np->parent; - /*printf("Already top, parent = \"%s\"\n", np?np->name:"(null)");*/ - } - if (np != NODE_NULL) { - topp = np; - xrepaint(); - } + /*printf("press(%d,%d)...\n",x,y); */ + np = findnode(&top, x, y); + /*printf("Found \"%s\"\n", np?np->name:"(null)"); */ + if (np == topp) { + /* already top, go up if possible */ + if (np->parent != &top || numchildren(&top) != 1) + np = np->parent; + /*printf("Already top, parent = \"%s\"\n", np?np->name:"(null)"); */ + } + if (np != NODE_NULL) { + topp = np; + xrepaint(); + } } void reset(void) { - topp = ⊤ - if (numchildren(topp) == 1) - topp = topp->child; - xrepaint(); + topp = ⊤ + if (numchildren(topp) == 1) + topp = topp->child; + xrepaint(); } -void repaint(int width,int height) +void repaint(int width, int height) { - struct rect rect; + struct rect rect; - /* define a rectangle to draw into */ - rect.top = 0; - rect.left = 0; - rect.width = width/ncols; - rect.height = height; + /* define a rectangle to draw into */ + rect.top = 0; + rect.left = 0; + rect.width = width / ncols; + rect.height = height; - clearrects(&top); /* clear current rectangle info */ - drawnode(topp,rect); /* draw tree into given rectangle */ + clearrects(&top); /* clear current rectangle info */ + drawnode(topp, rect); /* draw tree into given rectangle */ #if 0 - pwd(); /* display current path */ + pwd(); /* display current path */ #endif } void setorder(char *op) { - if (strcmp(op, "size") == 0) { - order = ORD_SIZE; - } else if (strcmp(op, "rsize") == 0) { - order = ORD_RSIZE; - } else if (strcmp(op, "alpha") == 0) { - order = ORD_ALPHA; - } else if (strcmp(op, "ralpha") == 0) { - order = ORD_RALPHA; - } else if (strcmp(op, "first") == 0) { - order = ORD_FIRST; - } else if (strcmp(op, "last") == 0) { - order = ORD_LAST; - } else if (strcmp(op, "reverse") == 0) { - switch (order) { - case ORD_ALPHA: - order = ORD_RALPHA; - break; - case ORD_RALPHA: - order = ORD_ALPHA; - break; - case ORD_SIZE: - order = ORD_RSIZE; - break; - case ORD_RSIZE: - order = ORD_SIZE; - break; - case ORD_FIRST: - order = ORD_LAST; - break; - case ORD_LAST: - order = ORD_FIRST; - break; - } - } else { - fprintf(stderr, "xdu: bad order \"%s\"\n", op); - } -} - -void reorder(char *op) /* order name */ -{ - setorder(op); - sorttree(topp, order); - xrepaint(); + if (strcmp(op, "size") == 0) { + order = ORD_SIZE; + } else if (strcmp(op, "rsize") == 0) { + order = ORD_RSIZE; + } else if (strcmp(op, "alpha") == 0) { + order = ORD_ALPHA; + } else if (strcmp(op, "ralpha") == 0) { + order = ORD_RALPHA; + } else if (strcmp(op, "first") == 0) { + order = ORD_FIRST; + } else if (strcmp(op, "last") == 0) { + order = ORD_LAST; + } else if (strcmp(op, "reverse") == 0) { + switch (order) { + case ORD_ALPHA: + order = ORD_RALPHA; + break; + case ORD_RALPHA: + order = ORD_ALPHA; + break; + case ORD_SIZE: + order = ORD_RSIZE; + break; + case ORD_RSIZE: + order = ORD_SIZE; + break; + case ORD_FIRST: + order = ORD_LAST; + break; + case ORD_LAST: + order = ORD_FIRST; + break; + } + } else { + fprintf(stderr, "xdu: bad order \"%s\"\n", op); + } +} + +void reorder(char *op) +{ /* order name */ + setorder(op); + sorttree(topp, order); + xrepaint(); } void nodeinfo(void) { - struct node *np; + struct node *np; - /* display current root path */ - pwd(); + /* display current root path */ + pwd(); - /* display each child of this node */ - for (np = topp->child; np != NULL; np = np->peer) { - printf("%-12lld %s\n", np->size, np->name); - } + /* display each child of this node */ + for (np = topp->child; np != NULL; np = np->peer) { + printf("%-12lld %s\n", np->size, np->name); + } } void helpinfo(void) { - fprintf(stdout, "\n\ + fprintf(stdout, "\n\ XDU Version %s - Keyboard Commands\n\ a sort alphabetically\n\ n sort numerically (largest first)\n\ @@ -792,203 +781,174 @@ XDU Version %s - Keyboard Commands\n\ ", XDU_VERSION); } -void fprintpsstart(FILE *fp) -{ - fprintf(fp, - "%%!\n" - "%%%%BoundingBox: 26 693 85 808\n" - "%%%%Title: xdu output\n" - "%%%%Orientation: Portrait\n" - "%%%%Pages: 1\n" - "%%%%DocumentFonts: (atend)\n" - "%%%%EndComments\n" - "%%%%BeginProlog\n\n" - "/xdudict 2 dict def\n" - "xdudict begin\n\n" - "end\n\n" - "%%%%EndProlog\n" - "%%%%Page: 1 1\n\n" - "xdudict begin\n" - "/xdusavedpage save def\n\n" - "1 setmiterlimit\n" - "1 setlinewidth\n" - "0 setgray\n" - "72 0 mul 72 11.60 mul translate\n" - "72 128 div 100.000 mul 100 div dup neg scale\n" - "gsave\n" - "/xduorigctm matrix currentmatrix def\n\n" - ); -} - -void fprintpsend(FILE *fp) -{ - fprintf(fp, - "grestore\n" - "xdusavedpage restore\n" - "end\n" - "showpage\n" - "\n" - "%%%%Trailer\n" - "%%%%DocumentFonts: fixed\n" - "%%%%EOF\n" - ); -} - -void fprintpsbox(FILE *fp, int x1, int y1, int x2, int y2) -{ - fprintf(fp, - "%%BOX\n" - "0 setgray\n" - "gsave\n" - " 10 setmiterlimit\n" - " gsave\n" - " newpath\n" - " %i %i moveto %i %i lineto %i %i lineto %i %i lineto\n" - " closepath\n" - " stroke\n" - " grestore\n" - "grestore\n" - "\n", - x1,y1,x2+x1,y1,x2+x1,y2+y1,x1,y2+y1 - ); -} - -void fprintpstext(FILE *fp, int x, int y, char *s) -{ - fprintf(fp, - "%%TEXT\n" - "0 setgray\n" - "/fixed findfont [10 0 0 -10 0 0] makefont setfont\n" - " gsave\n" - " %i %i moveto (%s) show\n" - " grestore\n" - "\n", - x,y,s - ); -} - -void savepschildren(FILE *fp, struct node *nodep, struct rect rect, int showsize) -{ - long long totalsize; - int totalheight, height, top,size; - struct node *np; - char *name, label[1024]; - struct rect subrect; - - top = rect.top; - size = 0; - totalheight = rect.height; - totalsize = nodep->size; - - if(totalsize == 0) { - for(np=nodep->child;np!=NULL;np=np->peer) totalsize += np->size; - nodep->size = totalsize; - } - - for(np=nodep->child;np!=NULL;np=np->peer) { - height = (totalsize ? (np->size/(double)totalsize) : 0) * totalheight + 0.5; - +void fprintpsstart(FILE * fp) +{ + fprintf(fp, "%%!\n" "%%%%BoundingBox: 26 693 85 808\n" "%%%%Title: xdu output\n" "%%%%Orientation: Portrait\n" "%%%%Pages: 1\n" "%%%%DocumentFonts: (atend)\n" "%%%%EndComments\n" "%%%%BeginProlog\n\n" "/xdudict 2 dict def\n" "xdudict begin\n\n" "end\n\n" "%%%%EndProlog\n" "%%%%Page: 1 1\n\n" "xdudict begin\n" "/xdusavedpage save def\n\n" "1 setmiterlimit\n" "1 setlinewidth\n" "0 setgray\n" "72 0 mul 72 11.60 mul translate\n" "72 128 div 100.000 mul 100 div dup neg scale\n" "gsave\n" "/xduorigctm matrix currentmatrix def\n\n"); +} + +void fprintpsend(FILE * fp) +{ + fprintf(fp, "grestore\n" "xdusavedpage restore\n" "end\n" "showpage\n" "\n" "%%%%Trailer\n" "%%%%DocumentFonts: fixed\n" "%%%%EOF\n"); +} + +void fprintpsbox(FILE * fp, int x1, int y1, int x2, int y2) +{ + fprintf(fp, "%%BOX\n" "0 setgray\n" "gsave\n" " 10 setmiterlimit\n" " gsave\n" " newpath\n" " %i %i moveto %i %i lineto %i %i lineto %i %i lineto\n" " closepath\n" " stroke\n" " grestore\n" "grestore\n" "\n", x1, y1, x2 + x1, y1, x2 + x1, y2 + y1, x1, y2 + y1); +} + +void fprintpstext(FILE * fp, int x, int y, char *s) +{ + fprintf(fp, "%%TEXT\n" "0 setgray\n" "/fixed findfont [10 0 0 -10 0 0] makefont setfont\n" " gsave\n" " %i %i moveto (%s) show\n" " grestore\n" "\n", x, y, s); +} + +void savepschildren(FILE * fp, struct node *nodep, struct rect rect, int showsize) +{ + long long totalsize; + int totalheight, height, top, size; + struct node *np; + char *name, label[1024]; + struct rect subrect; + + top = rect.top; + size = 0; + totalheight = rect.height; + totalsize = nodep->size; + + if (totalsize == 0) { + for (np = nodep->child; np != NULL; np = np->peer) + totalsize += np->size; + nodep->size = totalsize; + } + + for (np = nodep->child; np != NULL; np = np->peer) { + height = (totalsize ? (np->size / (double) totalsize) : 0) * totalheight + 0.5; + + switch (showsize) { + case 1: + sprintf(label, "%s \\(%lldk\\)", np->name, np->size); + name = label; + break; + case 2: + sprintf(label, "%s \\(%.2fM\\)", np->name, (double) np->size / (double) 1024); + name = label; + break; + case 3: + sprintf(label, "%s \\(%.2fG\\)", np->name, (double) np->size / (double) (1024 * 1024)); + name = label; + break; + case 4: + sprintf(label, "%s \\(%.2fT\\)", np->name, (double) np->size / (double) (1024 * 1024 * 1024)); + name = label; + break; + default: + printf("arghhhhh!"); + break; + } + + fprintpsbox(fp, rect.left, top, rect.width, height); + + if (height > 10) + fprintpstext(fp, rect.left + 4, top + (height) / 2.0 + 3.0, name); + + subrect.left = rect.left + rect.width; + subrect.top = top; + subrect.width = rect.width; + subrect.height = height; + + savepschildren(fp, np, subrect, showsize); + + size += np->size; + top = rect.top + (totalsize ? (double) size / (double) totalsize * rect.height + 0.5 : 0); + } +} + +void savepsnode(FILE * fp, struct node *nodep, struct rect rect, int showsize) +{ + struct rect subrect; + char label[1024], *name; + switch (showsize) { - case 1: sprintf(label,"%s \\(%lldk\\)", np->name, np->size);name = label;break; - case 2: sprintf(label,"%s \\(%.2fM\\)", np->name, (double)np->size / (double)1024);name = label;break; - case 3: sprintf(label,"%s \\(%.2fG\\)", np->name, (double)np->size / (double)(1024*1024));name = label;break; - case 4: sprintf(label,"%s \\(%.2fT\\)", np->name, (double)np->size / (double)(1024*1024*1024));name = label;break; - default: printf("arghhhhh!"); - break; - } - - fprintpsbox(fp, rect.left, top, rect.width, height); - - if(height>10) - fprintpstext(fp, rect.left+4, top+(height)/2.0+3.0, name); - - subrect.left = rect.left+rect.width; - subrect.top = top; - subrect.width = rect.width; - subrect.height = height; - - savepschildren(fp, np, subrect, showsize); - - size += np->size; - top = rect.top+(totalsize?(double)size/(double)totalsize*rect.height+0.5:0); - } -} - -void savepsnode(FILE *fp, struct node *nodep, struct rect rect, int showsize) -{ - struct rect subrect; - char label[1024], *name; - - switch (showsize) { - case 1: sprintf(label,"%s \\(%lldk\\)", nodep->name, nodep->size);name = label;break; - case 2: sprintf(label,"%s \\(%.2fM\\)", nodep->name, (double)nodep->size / (double)1024);name = label;break; - case 3: sprintf(label,"%s \\(%.2fG\\)", nodep->name, (double)nodep->size / (double)(1024*1024));name = label;break; - case 4: sprintf(label,"%s \\(%.2fT\\)", nodep->name, (double)nodep->size / (double)(1024*1024*1024));name = label;break; - default: - break; - } - - fprintpsbox(fp, rect.left, rect.top, rect.width, rect.height); - fprintpstext(fp, rect.left+4, rect.top+(rect.height-rect.top)/2, name); - - subrect.left = rect.left+rect.width; - subrect.top = rect.top; - subrect.width = rect.width; - subrect.height = rect.height; - savepschildren(fp, nodep,subrect, showsize); - + case 1: + sprintf(label, "%s \\(%lldk\\)", nodep->name, nodep->size); + name = label; + break; + case 2: + sprintf(label, "%s \\(%.2fM\\)", nodep->name, (double) nodep->size / (double) 1024); + name = label; + break; + case 3: + sprintf(label, "%s \\(%.2fG\\)", nodep->name, (double) nodep->size / (double) (1024 * 1024)); + name = label; + break; + case 4: + sprintf(label, "%s \\(%.2fT\\)", nodep->name, (double) nodep->size / (double) (1024 * 1024 * 1024)); + name = label; + break; + default: + break; + } + + fprintpsbox(fp, rect.left, rect.top, rect.width, rect.height); + fprintpstext(fp, rect.left + 4, rect.top + (rect.height - rect.top) / 2, name); + + subrect.left = rect.left + rect.width; + subrect.top = rect.top; + subrect.width = rect.width; + subrect.height = rect.height; + savepschildren(fp, nodep, subrect, showsize); + } void savetops(char *fname, int showsize) { - FILE *fp; - struct rect rect; - - if(fp=fopen(fname, "w")) { - fprintpsstart(fp); - - rect.top = 40; - rect.left = 40; - rect.width = 960/ncols; - rect.height = 1400; - - savepsnode(fp, topp, rect, showsize); - - fprintpsend(fp); - fclose(fp); - } + FILE *fp; + struct rect rect; + + if ((fp = fopen(fname, "w")) != NULL) { + fprintpsstart(fp); + + rect.top = 40; + rect.left = 40; + rect.width = 960 / ncols; + rect.height = 1400; + + savepsnode(fp, topp, rect, showsize); + + fprintpsend(fp); + fclose(fp); + } } void uponechild(void) { - struct node *np, *parent=NULL; - - np = topp; - if(np->parent != &top || numchildren(&top) != 1) { - parent=np->parent; - } - if(parent!=NODE_NULL) { - np=parent->child; - if(topp!=np) { - for(;np->peer;np=np->peer) { - if(np->peer==topp) { - topp=np; - xrepaint(); - return; - } - } - } - } + struct node *np, *parent = NULL; + + np = topp; + if (np->parent != &top || numchildren(&top) != 1) { + parent = np->parent; + } + if (parent != NODE_NULL) { + np = parent->child; + if (topp != np) { + for (; np->peer; np = np->peer) { + if (np->peer == topp) { + topp = np; + xrepaint(); + return; + } + } + } + } } void downonechild(void) { - if(topp->peer!=NODE_NULL) { - topp=topp->peer; - xrepaint(); - } + if (topp->peer != NODE_NULL) { + topp = topp->peer; + xrepaint(); + } } diff --git a/xwin.c b/xwin.c index 38e6589..62607c4 100644 --- a/xwin.c +++ b/xwin.c @@ -6,7 +6,7 @@ * Phillip C. Dykstra * * 4 Sep 1991. - * + * * Copyright (c) Phillip C. Dykstra 1991, 1993, 1994 * The X Consortium, and any party obtaining a copy of these files from * the X Consortium, directly or indirectly, is granted, free of charge, a @@ -31,7 +31,7 @@ #include #ifndef X_NOT_STDC_ENV -#include /* for exit() */ +#include /* for exit() */ #endif /* IMPORTS: routines that this module vectors out to */ @@ -45,68 +45,73 @@ extern int setorder(); extern int nodeinfo(); extern int helpinfo(); extern int ncols; +extern void savetops(char *, int); /* EXPORTS: routines that this module exports outside */ extern int xsetup(); extern int xmainloop(); -extern int xclear(); -extern int xrepaint(); -extern int xrepaint_noclear(); -extern int xdrawrect(); +extern void xclear(); +extern void xrepaint(); +extern void xrepaint_noclear(); +extern void xdrawrect(); /* internal routines */ static void help_popup(); static void help_popdown(); static String fallback_resources[] = { -"*window.width: 600", -"*window.height: 480", -"*help.width: 500", -"*help.height: 330", -"*order: first", -"*psfile: xdu_out.ps", -NULL + "*window.width: 600", + "*window.height: 480", + "*help.width: 500", + "*help.height: 330", + "*order: first", + "*psfile: xdu_out.ps", + NULL }; /* Application Resources */ typedef struct { - Pixel foreground; - Pixel background; - XFontStruct *font; - int ncol; - int showsize; - char *order; - char *psfilename; + Pixel foreground; + Pixel background; + XFontStruct *font; + int ncol; + int showsize; + char *order; + char *psfilename; } res_data, *res_data_ptr; static res_data res; static XtResource application_resources[] = { - { XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), - XtOffset(res_data_ptr,foreground), XtRString, XtDefaultForeground}, - { XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel), - XtOffset(res_data_ptr,background), XtRString, XtDefaultBackground}, - { XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), - XtOffset(res_data_ptr,font), XtRString, XtDefaultFont }, - { "ncol", "Ncol", XtRInt, sizeof(int), - XtOffset(res_data_ptr,ncol), XtRString, "5"}, - { "showsize", "ShowSize", XtRInt, sizeof(int), - XtOffset(res_data_ptr,showsize), XtRString, "1"}, - { "order", "Order", XtRString, sizeof(String), - XtOffset(res_data_ptr,order), XtRString, "first"}, - { "psfile", "PSFile", XtRString, sizeof(String), - XtOffset(res_data_ptr,psfilename), XtRString, "xdu_out.ps"} + {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), + XtOffset(res_data_ptr, foreground), XtRString, XtDefaultForeground} + , + {XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel), + XtOffset(res_data_ptr, background), XtRString, XtDefaultBackground} + , + {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), + XtOffset(res_data_ptr, font), XtRString, XtDefaultFont} + , + {"ncol", "Ncol", XtRInt, sizeof(int), + XtOffset(res_data_ptr, ncol), XtRString, "5"}, + {"showsize", "ShowSize", XtRInt, sizeof(int), + XtOffset(res_data_ptr, showsize), XtRString, "1"}, + {"order", "Order", XtRString, sizeof(String), + XtOffset(res_data_ptr, order), XtRString, "first"} + , + {"psfile", "PSFile", XtRString, sizeof(String), + XtOffset(res_data_ptr, psfilename), XtRString, "xdu_out.ps"} }; /* Command Line Options */ static XrmOptionDescRec options[] = { - {"-c", "*ncol", XrmoptionSepArg, NULL}, - {"-f", "*psfile", XrmoptionSepArg, NULL}, - {"+s", "*showsize", XrmoptionNoArg, "1"}, - {"-s", "*showsize", XrmoptionNoArg, "0"}, - {"-n", "*order", XrmoptionNoArg, "size"}, - {"-rn", "*order", XrmoptionNoArg, "rsize"}, - {"-a", "*order", XrmoptionNoArg, "alpha"}, - {"-ra", "*order", XrmoptionNoArg, "ralpha"} + {"-c", "*ncol", XrmoptionSepArg, NULL}, + {"-f", "*psfile", XrmoptionSepArg, NULL}, + {"+s", "*showsize", XrmoptionNoArg, "1"}, + {"-s", "*showsize", XrmoptionNoArg, "0"}, + {"-n", "*order", XrmoptionNoArg, "size"}, + {"-rn", "*order", XrmoptionNoArg, "rsize"}, + {"-a", "*order", XrmoptionNoArg, "alpha"}, + {"-ra", "*order", XrmoptionNoArg, "ralpha"} }; /* action routines */ @@ -124,18 +129,18 @@ static void a_help(); static void a_removehelp(); static XtActionsRec actionsTable[] = { - { "reset", a_reset }, - { "goto", a_goto }, - { "quit", a_quit }, - { "reorder", a_reorder }, - { "size", a_size }, - { "ncol", a_ncol }, - { "saveps", a_saveps }, - { "uponechild", a_up }, - { "downonechild", a_down }, - { "info", a_info }, - { "help", a_help }, - { "RemoveHelp", a_removehelp } + {"reset", a_reset}, + {"goto", a_goto}, + {"quit", a_quit}, + {"reorder", a_reorder}, + {"size", a_size}, + {"ncol", a_ncol}, + {"saveps", a_saveps}, + {"uponechild", a_up}, + {"downonechild", a_down}, + {"info", a_info}, + {"help", a_help}, + {"RemoveHelp", a_removehelp} }; static char defaultTranslations[] = "\ @@ -169,6 +174,19 @@ static char defaultTranslations[] = "\ : reset()\n\ "; +#define UNUSED1(x) (void)(x) +#define UNUSED2(x,y) (void)(x),(void)(y) +#define UNUSED3(x,y,z) (void)(x),(void)(y),(void)(z) +#define UNUSED4(a,x,y,z) (void)(a),(void)(x),(void)(y),(void)(z) +#define UNUSED5(a,b,x,y,z) (void)(a),(void)(b),(void)(x),(void)(y),(void)(z) + +#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5, N,...) N +#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1) + +#define ALL_UNUSED_IMPL_(nargs) UNUSED ## nargs +#define ALL_UNUSED_IMPL(nargs) ALL_UNUSED_IMPL_(nargs) +#define UNUSED(...) ALL_UNUSED_IMPL( VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__ ) + /* action routines */ static void a_quit(w, event, params, num_params) @@ -177,8 +195,9 @@ XEvent *event; String *params; Cardinal *num_params; { - XtDestroyApplicationContext(XtWidgetToApplicationContext(w)); - exit(0); + UNUSED(event, params, num_params); + XtDestroyApplicationContext(XtWidgetToApplicationContext(w)); + exit(0); } static void a_goto(w, event, params, num_params) @@ -187,7 +206,8 @@ XEvent *event; String *params; Cardinal *num_params; { - press(event->xbutton.x, event->xbutton.y); + UNUSED(w, params, num_params); + press(event->xbutton.x, event->xbutton.y); } static void a_reset(w, event, params, num_params) @@ -196,7 +216,8 @@ XEvent *event; String *params; Cardinal *num_params; { - reset(); + UNUSED(w, event, params, num_params); + reset(); } static void a_reorder(w, event, params, num_params) @@ -205,11 +226,12 @@ XEvent *event; String *params; Cardinal *num_params; { - if (*num_params != 1) { - fprintf(stderr, "xdu: bad number of params to reorder action\n"); - } else { - reorder(*params); - } + UNUSED(w, event); + if (*num_params != 1) { + fprintf(stderr, "xdu: bad number of params to reorder action\n"); + } else { + reorder(*params); + } } static void a_size(w, event, params, num_params) @@ -218,26 +240,31 @@ XEvent *event; String *params; Cardinal *num_params; { - res.showsize++; - if (res.showsize>=5) res.showsize = 0; - xrepaint(); + UNUSED(w, event, params, num_params); + res.showsize++; + if (res.showsize >= 5) + res.showsize = 0; + xrepaint(); } -static void a_saveps(Widget w, XEvent *e, String *params, Cardinal *num_params) +static void a_saveps(Widget w, XEvent * e, String * params, Cardinal * num_params) { - fprintf(stderr,"saving as postscript to file: %s ..",res.psfilename); - savetops(res.psfilename, res.showsize); - fprintf(stderr,"saved !\n"); + UNUSED(w, e, params, num_params); + fprintf(stderr, "saving as postscript to file: %s ..", res.psfilename); + savetops(res.psfilename, res.showsize); + fprintf(stderr, "saved !\n"); } -static void a_up(Widget w, XEvent *e, String *params, Cardinal *num_params) +static void a_up(Widget w, XEvent * e, String * params, Cardinal * num_params) { - uponechild(); + UNUSED(w, e, params, num_params); + uponechild(); } -static void a_down(Widget w, XEvent *e, String *params, Cardinal *num_params) +static void a_down(Widget w, XEvent * e, String * params, Cardinal * num_params) { - downonechild(); + UNUSED(w, e, params, num_params); + downonechild(); } static void a_ncol(w, event, params, num_params) @@ -246,19 +273,20 @@ XEvent *event; String *params; Cardinal *num_params; { - int n; - - if (*num_params != 1) { - fprintf(stderr, "xdu: bad number of params to ncol action\n"); - return; - } - n = atoi(*params); - if (n < 1 || n > 1000) { - fprintf(stderr, "xdu: bad value to ncol action\n"); - return; - } - ncols = res.ncol = n; - xrepaint(); + UNUSED(w, event); + int n; + + if (*num_params != 1) { + fprintf(stderr, "xdu: bad number of params to ncol action\n"); + return; + } + n = atoi(*params); + if (n < 1 || n > 1000) { + fprintf(stderr, "xdu: bad value to ncol action\n"); + return; + } + ncols = res.ncol = n; + xrepaint(); } static void a_info(w, event, params, num_params) @@ -267,7 +295,8 @@ XEvent *event; String *params; Cardinal *num_params; { - nodeinfo(); + UNUSED(w, event, params, num_params); + nodeinfo(); } static void a_help(w, event, params, num_params) @@ -276,8 +305,9 @@ XEvent *event; String *params; Cardinal *num_params; { - /*helpinfo();*/ - help_popup(); + UNUSED(w, event, params, num_params); + /*helpinfo(); */ + help_popup(); } static void a_removehelp(w, event, params, num_params) @@ -286,7 +316,8 @@ XEvent *event; String *params; Cardinal *num_params; { - help_popdown(); + UNUSED(w, event, params, num_params); + help_popdown(); } /* callback routines */ @@ -297,8 +328,9 @@ XtPointer data; XEvent *event; Boolean *continue_to_dispatch; { - /*printf("Resize\n");*/ - xrepaint(); + UNUSED(w, data, event, continue_to_dispatch); + /*printf("Resize\n"); */ + xrepaint(); } static void c_repaint(w, data, event, continue_to_dispatch) @@ -307,186 +339,196 @@ XtPointer data; XEvent *event; Boolean *continue_to_dispatch; { - /*printf("Expose\n");*/ - xrepaint_noclear(); + UNUSED(w, data, event, continue_to_dispatch); + /*printf("Expose\n"); */ + xrepaint_noclear(); } /* X Window related variables */ -static Cursor WorkingCursor; static Display *dpy; static int screen; static Visual *vis; static Window win; static GC gc; -static GC cleargc; static XtAppContext app_con; Widget toplevel; /* External Functions */ -int -xsetup(argcp, argv) +int xsetup(argcp, argv) int *argcp; char **argv; { - XtTranslations trans_table; - Widget w; - XGCValues gcv; - int n; - Arg args[5]; - - /* Create the top level Widget */ - n = 0; - XtSetArg(args[n], XtNtitle, "XDU Disk Usage Display ('h' for help)\n"); n++; - toplevel = XtAppInitialize(&app_con, "XDu", - options, XtNumber(options), - argcp, argv, - fallback_resources, args, n); - - XtGetApplicationResources(toplevel, (XtPointer)&res, - application_resources, XtNumber(application_resources), - NULL, 0 ); - - XtAppAddActions(app_con, actionsTable, XtNumber(actionsTable)); - trans_table = XtParseTranslationTable(defaultTranslations); - - /* Create a simple Label class widget to draw in */ - n = 0; - XtSetArg(args[n], XtNlabel, ""); n++; - w = XtCreateManagedWidget("window", labelWidgetClass, toplevel, - args, n); - - /* events */ - XtAddEventHandler(w, ExposureMask, False, c_repaint, NULL); - XtAddEventHandler(w, StructureNotifyMask, False, c_resize, NULL); - XtAugmentTranslations(w, trans_table); - - XtRealizeWidget(toplevel); - - /* We need these for the raw Xlib calls */ - win = XtWindow(w); - dpy = XtDisplay(w); - screen = DefaultScreen(dpy); - vis = DefaultVisual(dpy,screen); - - gcv.foreground = res.foreground; - gcv.background = res.background; - gcv.font = res.font->fid; - gc = XCreateGC(dpy, win, (GCFont|GCForeground|GCBackground), &gcv); - - setorder(res.order); - ncols = res.ncol; - return(1); + XtTranslations trans_table; + Widget w; + XGCValues gcv; + int n; + Arg args[5]; + + /* Create the top level Widget */ + n = 0; + XtSetArg(args[n], XtNtitle, "XDU Disk Usage Display ('h' for help)\n"); + n++; + toplevel = XtAppInitialize(&app_con, "XDu", options, XtNumber(options), argcp, argv, fallback_resources, args, n); + + XtGetApplicationResources(toplevel, (XtPointer) & res, application_resources, XtNumber(application_resources), NULL, 0); + + XtAppAddActions(app_con, actionsTable, XtNumber(actionsTable)); + trans_table = XtParseTranslationTable(defaultTranslations); + + /* Create a simple Label class widget to draw in */ + n = 0; + XtSetArg(args[n], XtNlabel, ""); + n++; + w = XtCreateManagedWidget("window", labelWidgetClass, toplevel, args, n); + + /* events */ + XtAddEventHandler(w, ExposureMask, False, c_repaint, NULL); + XtAddEventHandler(w, StructureNotifyMask, False, c_resize, NULL); + XtAugmentTranslations(w, trans_table); + + XtRealizeWidget(toplevel); + + /* We need these for the raw Xlib calls */ + win = XtWindow(w); + dpy = XtDisplay(w); + screen = DefaultScreen(dpy); + vis = DefaultVisual(dpy, screen); + + gcv.foreground = res.foreground; + gcv.background = res.background; + gcv.font = res.font->fid; + gc = XCreateGC(dpy, win, (GCFont | GCForeground | GCBackground), &gcv); + + setorder(res.order); + ncols = res.ncol; + return (1); } -xmainloop() +int xmainloop() { - XtAppMainLoop(app_con); - return(0); + XtAppMainLoop(app_con); + return (0); } -xclear() +void xclear() { - XClearWindow(dpy, win); + XClearWindow(dpy, win); } -xrepaint() +void xrepaint() { - XWindowAttributes xwa; + XWindowAttributes xwa; - XClearWindow(dpy, win); - XGetWindowAttributes(dpy, win, &xwa); - repaint(xwa.width, xwa.height); + XClearWindow(dpy, win); + XGetWindowAttributes(dpy, win, &xwa); + repaint(xwa.width, xwa.height); } -xrepaint_noclear() +void xrepaint_noclear() { - XWindowAttributes xwa; + XWindowAttributes xwa; - XGetWindowAttributes(dpy, win, &xwa); - repaint(xwa.width, xwa.height); + XGetWindowAttributes(dpy, win, &xwa); + repaint(xwa.width, xwa.height); } -xdrawrect(name, size, x, y, width, height) +void xdrawrect(name, size, x, y, width, height) char *name; long long size; int x, y, width, height; { - int textx, texty; - char label[1024]; - XCharStruct overall; - int ascent, descent, direction; - int cheight; - - /*printf("draw(%d,%d,%d,%d)\n", x, y, width, height );*/ - XDrawRectangle(dpy, win, gc, x, y, width, height); - - switch (res.showsize) { - case 1: sprintf(label,"%s (%lldk)", name, size);name = label;break; - case 2: sprintf(label,"%s (%.2fM)", name, (double)size / (double)1024);name = label;break; - case 3: sprintf(label,"%s (%.2fG)", name, (double)size / (double)(1024*1024));name = label;break; - case 4: sprintf(label,"%s (%.2fT)", name, (double)size / (double)(1024*1024*1024));name = label;break; - default: - break; - } - - XTextExtents(res.font, name, strlen(name), &direction, - &ascent, &descent, &overall); - cheight = overall.ascent + overall.descent; - if (height < (cheight + 2)) - return; - - /* print label */ - textx = x + 4; - texty = y + height/2.0 + (overall.ascent - overall.descent)/2.0 + 1.5; - XDrawString(dpy, win, gc, textx, texty, name, strlen(name)); + int textx, texty; + char label[1024]; + XCharStruct overall; + int ascent, descent, direction; + int cheight; + + /*printf("draw(%d,%d,%d,%d)\n", x, y, width, height ); */ + XDrawRectangle(dpy, win, gc, x, y, width, height); + + switch (res.showsize) { + case 1: + sprintf(label, "%s (%lldk)", name, size); + name = label; + break; + case 2: + sprintf(label, "%s (%.2fM)", name, (double) size / (double) 1024); + name = label; + break; + case 3: + sprintf(label, "%s (%.2fG)", name, (double) size / (double) (1024 * 1024)); + name = label; + break; + case 4: + sprintf(label, "%s (%.2fT)", name, (double) size / (double) (1024 * 1024 * 1024)); + name = label; + break; + default: + break; + } + + XTextExtents(res.font, name, strlen(name), &direction, &ascent, &descent, &overall); + cheight = overall.ascent + overall.descent; + if (height < (cheight + 2)) + return; + + /* print label */ + textx = x + 4; + texty = y + height / 2.0 + (overall.ascent - overall.descent) / 2.0 + 1.5; + XDrawString(dpy, win, gc, textx, texty, name, strlen(name)); } static Widget popup; -static void -help_popup() +static void help_popup() { - Widget form, text, src; - Arg args[15]; - int n; - Atom wm_delete_window; - XtTranslations trans_table; - - if (popup != NULL) { - XtPopup(popup, XtGrabNone); - return; - } - - /* popup shell */ - n = 0; - XtSetArg(args[n], XtNtitle, "XDU Help"); n++; - popup = XtCreatePopupShell("helpPopup", transientShellWidgetClass, - toplevel, args, n); - - /* form container */ - n = 0; - XtSetArg(args[n], XtNborderWidth, 0); n++; - XtSetArg(args[n], XtNdefaultDistance, 0); n++; - form = XtCreateManagedWidget("form", formWidgetClass, - popup, args, n); - - /* text widget in form */ - n = 0; - XtSetArg(args[n], XtNborderWidth, 0); n++; - XtSetArg(args[n], XtNresize, XawtextResizeBoth); n++; - /* fallback resources weren't working here on the Sun */ - XtSetArg(args[n], XtNwidth, 500); n++; - XtSetArg(args[n], XtNheight, 330); n++; - text = XtCreateManagedWidget("help", asciiTextWidgetClass, - form, args, n); - - /* create text source */ - n = 0; - XtSetArg(args[n], XtNtype, XawAsciiString); n++; - XtSetArg(args[n], XtNeditType, XawtextRead); n++; - XtSetArg(args[n], XtNstring, "\ + Widget form, text, src; + Arg args[15]; + int n; + Atom wm_delete_window; + XtTranslations trans_table; + + if (popup != NULL) { + XtPopup(popup, XtGrabNone); + return; + } + + /* popup shell */ + n = 0; + XtSetArg(args[n], XtNtitle, "XDU Help"); + n++; + popup = XtCreatePopupShell("helpPopup", transientShellWidgetClass, toplevel, args, n); + + /* form container */ + n = 0; + XtSetArg(args[n], XtNborderWidth, 0); + n++; + XtSetArg(args[n], XtNdefaultDistance, 0); + n++; + form = XtCreateManagedWidget("form", formWidgetClass, popup, args, n); + + /* text widget in form */ + n = 0; + XtSetArg(args[n], XtNborderWidth, 0); + n++; + XtSetArg(args[n], XtNresize, XawtextResizeBoth); + n++; + /* fallback resources weren't working here on the Sun */ + XtSetArg(args[n], XtNwidth, 500); + n++; + XtSetArg(args[n], XtNheight, 330); + n++; + text = XtCreateManagedWidget("help", asciiTextWidgetClass, form, args, n); + + /* create text source */ + n = 0; + XtSetArg(args[n], XtNtype, XawAsciiString); + n++; + XtSetArg(args[n], XtNeditType, XawtextRead); + n++; + XtSetArg(args[n], XtNstring, "\ XDU Version 3.0 - Phil Dykstra \n\ \n\ Keyboard Commands\n\ @@ -510,26 +552,25 @@ Mouse Commands\n\ Left Goto node (goto parent if leftmost box)\n\ Middle Back to root\n\ Right Quit\n\ -"); n++; - src = XtCreateWidget("textSource", asciiSrcObjectClass, - text, args, n); - /* set text source */ - XawTextSetSource(text, src, 0); - - XtRealizeWidget(popup); - XtPopup(popup, XtGrabNone); - - trans_table = XtParseTranslationTable("Q: RemoveHelp()"); - XtAugmentTranslations(form, trans_table); - - /* Set up ICCCM delete window */ - wm_delete_window = XInternAtom(XtDisplay(popup), "WM_DELETE_WINDOW", False); - XtOverrideTranslations(popup, XtParseTranslationTable("WM_PROTOCOLS: RemoveHelp()")); - XSetWMProtocols(XtDisplay(popup), XtWindow(popup), &wm_delete_window, 1); +"); + n++; + src = XtCreateWidget("textSource", asciiSrcObjectClass, text, args, n); + /* set text source */ + XawTextSetSource(text, src, 0); + + XtRealizeWidget(popup); + XtPopup(popup, XtGrabNone); + + trans_table = XtParseTranslationTable("Q: RemoveHelp()"); + XtAugmentTranslations(form, trans_table); + + /* Set up ICCCM delete window */ + wm_delete_window = XInternAtom(XtDisplay(popup), "WM_DELETE_WINDOW", False); + XtOverrideTranslations(popup, XtParseTranslationTable("WM_PROTOCOLS: RemoveHelp()")); + XSetWMProtocols(XtDisplay(popup), XtWindow(popup), &wm_delete_window, 1); } -static void -help_popdown() +static void help_popdown() { - XtPopdown(popup); + XtPopdown(popup); }