diff --git a/src/Makefile.am b/src/Makefile.am index 8d349eccd596b19df9f76e1372e8d38cbbebbb89..585780b86e55768d76f4c4cb8fb7bf49871e7bd3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ bin_PROGRAMS = ncdu -ncdu_SOURCES = browser.c calc.c main.c util.c exclude.c help.c delete.c +ncdu_SOURCES = calc.c exclude.c main.c util.c -noinst_HEADERS = calc.h exclude.h ncdu.h +noinst_HEADERS = calc.h exclude.h util.h ncdu.h diff --git a/src/calc.c b/src/calc.c index d77634a85a2e88493f26501a7d750dae6c4cced9..08122acccee1554ccce9b04236b9d42cc8b2998f 100644 --- a/src/calc.c +++ b/src/calc.c @@ -26,6 +26,7 @@ #include "ncdu.h" #include "calc.h" #include "exclude.h" +#include "util.h" struct state_calc stcalc; @@ -278,8 +279,8 @@ void calc_draw_progress() { nccreate(10, 60, dat == NULL ? "Calculating..." : "Recalculating..."); ncprint(2, 2, "Total items: %-8d size: %s", - stcalc.parent->items, cropsize(stcalc.parent->size)); - ncprint(3, 2, "Current dir: %s", cropdir(stcalc.cur, 43)); + stcalc.parent->items, formatsize(stcalc.parent->size, sflags & SF_SI)); + ncprint(3, 2, "Current dir: %s", cropstr(stcalc.cur, 43)); ncaddstr(8, 43, "Press q to quit"); /* show warning if we couldn't open a dir */ @@ -287,7 +288,7 @@ void calc_draw_progress() { attron(A_BOLD); ncaddstr(5, 2, "Warning:"); attroff(A_BOLD); - ncprint(5, 11, "could not open %-32s", cropdir(stcalc.lasterr, 32)); + ncprint(5, 11, "could not open %-32s", cropstr(stcalc.lasterr, 32)); ncaddstr(6, 3, "some directory sizes may not be correct"); } @@ -315,8 +316,8 @@ void calc_draw_error(char *cur, char *msg) { ncaddstr(2, 2, "Error:"); attroff(A_BOLD); - ncprint(2, 9, "could not open %s", cropdir(cur, 34)); - ncprint(3, 4, "%s", cropdir(msg, 52)); + ncprint(2, 9, "could not open %s", cropstr(cur, 34)); + ncprint(3, 4, "%s", cropstr(msg, 52)); ncaddstr(5, 30, "press any key to continue..."); } diff --git a/src/main.c b/src/main.c index 043d474795c733fe3e45a05c809a4b36f94c7434..bcddfa351f26fecae1af7dbe4b89cd36bb33130c 100644 --- a/src/main.c +++ b/src/main.c @@ -25,13 +25,11 @@ #include "ncdu.h" #include "exclude.h" +#include "util.h" /* check ncdu.h what these are for */ struct dir *dat; -int winrows, wincols; -char sdir[PATH_MAX]; int sflags, bflags, sdelay, bgraph; -int subwinc, subwinr; int pstate; @@ -52,7 +50,8 @@ int input_handle(int wait) { screen_draw(); while((ch = getch()) != ERR) { if(ch == KEY_RESIZE) { - ncresize(); + if(ncresize((sflags & SF_IGNS ? 0 : 17), (sflags * SF_IGNS ? 0 : 60))) + sflags |= SF_IGNS; screen_draw(); continue; } @@ -141,7 +140,8 @@ int main(int argc, char **argv) { noecho(); curs_set(0); keypad(stdscr, TRUE); - ncresize(); + if(ncresize((sflags & SF_IGNS ? 0 : 17), (sflags * SF_IGNS ? 0 : 60))) + sflags |= SF_IGNS; while(pstate != ST_QUIT) { if(pstate == ST_CALC) diff --git a/src/ncdu.h b/src/ncdu.h index a17b6efce4cd1844396dfbdb8c482084d379050e..382472943869bd1370c854d5ae856848a68524d9 100644 --- a/src/ncdu.h +++ b/src/ncdu.h @@ -23,6 +23,8 @@ */ +#ifndef _ncdu_h +#define _ncdu_h #include "config.h" @@ -82,10 +84,6 @@ # define S_ISLNK(x) (x & S_IFLNK) #endif -/* check nccreate in util.c for more info on these defines */ -#define ncaddstr(r, c, s) mvaddstr(subwinr+(r), subwinc+(c), s) -#define ncaddch(r, c, s) mvaddch(subwinr+(r), subwinc+(c), s) -#define ncmove(r, c) move(subwinr+(r), subwinc+(c)) /* @@ -146,13 +144,8 @@ struct dir { */ /* main directory data */ extern struct dir *dat; -/* updated when window is resized */ -extern int winrows, wincols; /* global settings */ -extern char sdir[PATH_MAX]; extern int sflags, bflags, sdelay, bgraph; -/* used for creating windows */ -extern int subwinr, subwinc; /* program state */ extern int pstate; @@ -162,15 +155,6 @@ extern int pstate; */ /* main.c */ int input_handle(int); -/* util.c */ -char *cropdir(const char *, int); -char *cropsize(const off_t); -char *fullsize(const off_t); -void ncresize(void); -void nccreate(int, int, char *); -void ncprint(int, int, char *, ...); -struct dir *freedir(struct dir *); -char *getpath(struct dir *, char *); /* browser.c */ void drawBrowser(int); void showBrowser(void); @@ -178,3 +162,6 @@ void showBrowser(void); void showHelp(void); /* delete.c */ struct dir *showDelete(struct dir *); + + +#endif diff --git a/src/util.c b/src/util.c index 6521800c65f1ea2a492adbd65a11e8573691677d..f218381e709f35d784226baa1d76f116669dd0b5 100644 --- a/src/util.c +++ b/src/util.c @@ -23,36 +23,44 @@ */ -#include "ncdu.h" +#include "util.h" -char cropsizedat[8]; +#include <string.h> +#include <stdlib.h> +#include <ncurses.h> + +int winrows, wincols; +int subwinr, subwinc; + +char cropstrdat[4096]; +char formatsizedat[8]; char fullsizedat[20]; /* max: 999.999.999.999.999 */ -char cropdirdat[4096]; -char *cropdir(const char *from, int s) { + +char *cropstr(const char *from, int s) { int i, j, o = strlen(from); if(o < s) { - strcpy(cropdirdat, from); - return(cropdirdat); + strcpy(cropstrdat, from); + return cropstrdat; } j=s/2-3; for(i=0; i<j; i++) - cropdirdat[i] = from[i]; - cropdirdat[i] = '.'; - cropdirdat[++i] = '.'; - cropdirdat[++i] = '.'; + cropstrdat[i] = from[i]; + cropstrdat[i] = '.'; + cropstrdat[++i] = '.'; + cropstrdat[++i] = '.'; j=o-s; while(++i<s) - cropdirdat[i] = from[j+i]; - cropdirdat[s] = '\0'; - return(cropdirdat); + cropstrdat[i] = from[j+i]; + cropstrdat[s] = '\0'; + return cropstrdat; } -/* return value is always xxx.xXB = 8 bytes (including \0) */ -char *cropsize(const off_t from) { + +char *formatsize(const off_t from, int si) { float r = from; char c = ' '; - if(sflags & SF_SI) { + if(si) { if(r < 1000.0f) { } else if(r < 1000e3f) { c = 'k'; r/=1000.0f; } else if(r < 1000e6f) { c = 'M'; r/=1000e3f; } @@ -65,25 +73,24 @@ char *cropsize(const off_t from) { else if(r < 1023e9f) { c = 'G'; r/=1073741824.0f; } else { c = 'T'; r/=1099511627776.0f; } } - sprintf(cropsizedat, "%5.1f%cB", r, c); - return(cropsizedat); + sprintf(formatsizedat, "%5.1f%cB", r, c); + return formatsizedat; } -/* returns integer as a string with thousand seperators - BUG: Uses a dot as seperator, ignores current locale */ + char *fullsize(const off_t from) { char tmp[20]; off_t n = from; int i, j; - /* the K&R method - more portable than sprintf with %lld */ + /* the K&R method - more portable than sprintf with %lld */ i = 0; do { tmp[i++] = n % 10 + '0'; } while((n /= 10) > 0); tmp[i] = '\0'; - /* reverse and add thousand seperators */ + /* reverse and add thousand seperators */ j = 0; while(i--) { fullsizedat[j++] = tmp[i]; @@ -92,19 +99,19 @@ char *fullsize(const off_t from) { } fullsizedat[j] = '\0'; - return(fullsizedat); + return fullsizedat; } -void ncresize(void) { +int ncresize(int minrows, int mincols) { int ch; + getmaxyx(stdscr, winrows, wincols); - while(!(sflags & SF_IGNS) && (winrows < 17 || wincols < 60)) { + while((minrows && winrows < minrows) || (mincols && wincols < mincols)) { erase(); mvaddstr(0, 0, "Warning: terminal too small,"); mvaddstr(1, 1, "please either resize your terminal,"); mvaddstr(2, 1, "press i to ignore, or press q to quit."); - touchwin(stdscr); refresh(); nodelay(stdscr, 0); ch = getch(); @@ -116,36 +123,24 @@ void ncresize(void) { exit(0); } if(ch == 'i') - sflags |= SF_IGNS; + return 1; } erase(); + return 0; } -/* Instead of using several ncurses windows, we only draw to stdscr. - * the functions nccreate, ncprint and the macros ncaddstr and ncaddch - * mimic the behaviour of ncurses windows. - * This works better than using ncurses windows when all windows are - * created in the correct order: it paints directly on stdscr, so - * wrefresh, wnoutrefresh and other window-specific functions are not - * necessary. - * Also, this method doesn't require any window objects, as you can - * only create one window at a time. - * - * This function creates a new window in the center of the screen - * with a border and a title. -*/ void nccreate(int height, int width, char *title) { int i; subwinr = winrows/2-height/2; subwinc = wincols/2-width/2; - /* clear window */ + /* clear window */ for(i=0; i<height; i++) mvhline(subwinr+i, subwinc, ' ', width); - /* box() only works around curses windows, so create our own */ + /* box() only works around curses windows, so create our own */ move(subwinr, subwinc); addch(ACS_ULCORNER); for(i=0; i<width-2; i++) @@ -161,7 +156,7 @@ void nccreate(int height, int width, char *title) { mvvline(subwinr+1, subwinc, ACS_VLINE, height-2); mvvline(subwinr+1, subwinc+width-1, ACS_VLINE, height-2); - /* title */ + /* title */ attron(A_BOLD); mvaddstr(subwinr, subwinc+4, title); attroff(A_BOLD); @@ -177,7 +172,6 @@ void ncprint(int r, int c, char *fmt, ...) { } - void freedir_rec(struct dir *dr) { struct dir *tmp, *tmp2; tmp2 = dr; @@ -189,11 +183,11 @@ void freedir_rec(struct dir *dr) { } } -/* remove a file/directory from the in-memory map */ + struct dir *freedir(struct dir *dr) { struct dir *tmp, *cur; - /* update sizes of parent directories */ + /* update sizes of parent directories */ tmp = dr; while((tmp = tmp->parent) != NULL) { tmp->size -= dr->size; @@ -201,25 +195,25 @@ struct dir *freedir(struct dir *dr) { tmp->items -= dr->items+1; } - /* free dr->sub recursive */ + /* free dr->sub recursive */ if(dr->sub) freedir_rec(dr->sub); - /* update references */ + /* update references */ cur = NULL; if(dr->parent) { - /* item is at the top of the dir, refer to next item */ + /* item is at the top of the dir, refer to next item */ if(dr->parent->sub == dr) { dr->parent->sub = dr->next; cur = dr->next; } - /* else, get the previous item and update it's "next"-reference */ + /* else, get the previous item and update it's "next"-reference */ else for(tmp = dr->parent->sub; tmp != NULL; tmp = tmp->next) if(tmp->next == dr) { tmp->next = dr->next; cur = tmp; } - /* no previous item, refer to parent dir */ + /* no previous item, refer to parent dir */ if(cur == NULL && dr->parent->parent) cur = dr->parent; } @@ -232,6 +226,7 @@ struct dir *freedir(struct dir *dr) { return(cur); } + char *getpath(struct dir *cur, char *to) { struct dir *d, *list[100]; int c = 0; @@ -248,3 +243,4 @@ char *getpath(struct dir *cur, char *to) { return to; } + diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000000000000000000000000000000000000..f2b4c1ba3ff3bd8a2cb341197eca9b88d2cbdb65 --- /dev/null +++ b/src/util.h @@ -0,0 +1,80 @@ +/* ncdu - NCurses Disk Usage + + Copyright (c) 2007-2009 Yoran Heling + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +#ifndef _util_h +#define _util_h + +#include "ncdu.h" + +/* updated when window is resized */ +extern int winrows, wincols; + +/* used by the nc* functions and macros */ +extern int subwinr, subwinc; + + +/* Instead of using several ncurses windows, we only draw to stdscr. + * the functions nccreate, ncprint and the macros ncaddstr and ncaddch + * mimic the behaviour of ncurses windows. + * This works better than using ncurses windows when all windows are + * created in the correct order: it paints directly on stdscr, so + * wrefresh, wnoutrefresh and other window-specific functions are not + * necessary. + * Also, this method doesn't require any window objects, as you can + * only create one window at a time. +*/ + +/* updates winrows, wincols, and displays a warning when the terminal + * is smaller than the specified minimum size. */ +int ncresize(int, int); + +/* creates a new centered window with border */ +void nccreate(int, int, char *); + +/* printf something somewhere in the last created window */ +void ncprint(int, int, char *, ...); + +/* same as the w* functions of ncurses */ +#define ncaddstr(r, c, s) mvaddstr(subwinr+(r), subwinc+(c), s) +#define ncaddch(r, c, s) mvaddch(subwinr+(r), subwinc+(c), s) +#define ncmove(r, c) move(subwinr+(r), subwinc+(c)) + +/* crops a string into the specified length */ +char *cropstr(const char *, int); + +/* formats size in the form of xxx.xXB */ +char *formatsize(const off_t, int); + +/* int2string with thousand separators */ +char *fullsize(const off_t); + +/* recursively free()s a directory tree */ +struct dir *freedir(struct dir *); + +/* generates full path from a dir item */ +char *getpath(struct dir *, char *); + +#endif +