codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
#include <windows.h> #include <stdio.h> #include <assert.h> /* #define DEBUG */ #if defined(DEBUG) #include "xmalloc.h" #define ERROR_COUNT 8 void *zmalloc(size_t n, int id) { void *p; static int count = 0; if (count++ >= ERROR_COUNT) return 0; #undef ERROR_COUNT p = xmalloc(n, id); return p; } void zfree(void *p, int id) { xfree(p, id); } #else #define zmalloc(x, y) malloc(x) #define zfree(x, y) free(x) #define xmallocdump() #endif #define ID_NODE 1001 #define FILEPATH 1002 #define MASKPATH 1003 #define TREEDATA 1004 /********************************************/ /* for CP932/Shift-JIS */ int isHasSecondByte(int c) { if (c >= 0x81 && c <= 0x9f) return 1; if (c >= 0xe0 && c <= 0xfc) return 1; return 0; } int getLastChar(char *path) { int rc; char *p; int flagHasSecondByte; for (p = path, flagHasSecondByte = 0; *p; p++) { if (!flagHasSecondByte) { rc = (rc << 8) & *p; flagHasSecondByte = 0; } else { /* is SecondByte */ flagHasSecondByte = isHasSecondByte(*p); rc = *p; } } return rc; } /********************************************/ struct node { void *data; int c; struct node *left, *right; }; void *push(struct node **root, void *data, int (*cmp)(void *, void *)) { struct node *p; if (!*root) { if ((p = zmalloc(sizeof(struct node), ID_NODE)) == NULL) { fprintf(stderr, "push: cannot allocate enough memory.(struct node), aborted\n"); return 0; } p->data = data; p->left = p->right = NULL; *root = p; return data; } if ((*cmp)(data, (*root)->data) < 0) { return push(&((*root)->left), data, cmp); } else { return push(&((*root)->right), data, cmp); } } void *pop(struct node **root) { struct node *p; void *data; if (*root == NULL) { return NULL; } if ((*root)->left) { data = pop(&((*root)->left)); return data; } p = *root; data = p->data; *root = p->right; zfree(p, ID_NODE); return data; } /*--------------------------------------------------------------------*/ char *mallocStrCat(char *s1, char *s2, int id) { int n1, n2; char *c; n1 = strlen(s1); n2 = strlen(s2); if ((c = zmalloc(n1 + n2 + 1, id)) == 0) return 0; strcpy(c, s1); strcpy(c + n1, s2); return c; } char *mallocPathCat(char *dir, char *file, int id) { char *s1, *s2; int last; last = getLastChar(dir); if (last != '\\') { s1 = mallocStrCat(dir, "\\", id); if (s1 == 0) return 0; } else { s1 = dir; } s2 = mallocStrCat(s1, file, id); zfree(s1, id); if (s2 == 0) return 0; return s2; } char *mallocReplicaPath(char *path, int id) { char *rc; if ((rc = zmalloc(strlen(path) + 1, id)) != 0) strcpy(rc, path); return rc; } /*--------------------------------------------------------------------*/ struct filedata { unsigned int size; char *filename; }; int comp(struct filedata *a, struct filedata *b) { if (a->size > b->size) return -1; if (a->size < b->size) return 1; assert(a->size == b->size); return strcmp(a->filename, b->filename); } /*--------------------------------------------------------------------*/ int task_digging(struct node **root, char *searchpath) { HANDLE hFileDigging; WIN32_FIND_DATA systemFindData; char *searchmask, *t; char *nextPath; struct filedata *filedataSizeName; hFileDigging = INVALID_HANDLE_VALUE; filedataSizeName = 0; searchmask = nextPath = 0; searchmask = mallocReplicaPath(searchpath, MASKPATH); if (searchmask == 0) { fprintf(stderr, "task_digging: memory full.<1>\n"); goto error_handler; } if ((t = mallocPathCat(searchmask, "*.*", MASKPATH)) == 0) { fprintf(stderr, "task_digging: memory full.<2>\n"); goto error_handler; } zfree(searchmask, MASKPATH); searchmask = t; if ((hFileDigging = FindFirstFile(searchmask, &systemFindData)) == INVALID_HANDLE_VALUE) { fprintf(stderr, "task_digging: returned invalid handle. <3>\n"); goto error_handler; } do { if (strcmp(systemFindData.cFileName, ".") == 0) continue; if (strcmp(systemFindData.cFileName, "..") == 0) continue; nextPath = mallocReplicaPath(searchpath, FILEPATH); if (nextPath == 0) { fprintf(stderr, "task_digging: memory full.<4>\n"); goto error_handler; } if ((t = mallocPathCat(nextPath, systemFindData.cFileName, FILEPATH)) == 0) { fprintf(stderr, "task_digging: memory full.<5>\n"); goto error_handler; } zfree(nextPath, FILEPATH); nextPath = t; /* directory */ if (systemFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (!task_digging(root, nextPath)) { fprintf(stderr, "task_digging: recursion failure. <6>, pos: %s\n", nextPath); goto error_handler; } zfree(nextPath, FILEPATH); } else { /* file */ if ((filedataSizeName = zmalloc(sizeof(struct filedata), TREEDATA)) == 0) { fprintf(stderr, "task_digging: pos:%s/%s, recursion failure.<7>\n", searchpath, nextPath); goto error_handler; } filedataSizeName->size = systemFindData.nFileSizeLow; filedataSizeName->filename = nextPath; if (push(root, filedataSizeName, (int (*)(void *, void *))comp) == 0) { fprintf(stderr, "task_digging: pos:%s/%s, recursion failure.<8>\n", searchpath, nextPath); goto error_handler; } filedataSizeName = 0; nextPath = 0; } } while (FindNextFile(hFileDigging, &systemFindData)); zfree(searchmask, MASKPATH); FindClose(hFileDigging); return 1; error_handler: zfree(searchmask, MASKPATH); zfree(nextPath, FILEPATH); zfree(filedataSizeName, TREEDATA); FindClose(hFileDigging); return 0; } #define OUTPUT_FILE_NUM 100 void task_vomitting(struct node **root, int init_n) { struct filedata *p; int n; n = init_n; while ((p = pop(root)) != 0) { if (n < OUTPUT_FILE_NUM) { printf("%9d: %s\n", p->size, p->filename); n++; } zfree(p->filename, FILEPATH); zfree(p, TREEDATA); } } /*--------------------------------------------------------------------*/ int task_main(char *dir) { struct node *root; char *searchpath; int err; root = 0; searchpath = 0; err = 0; if ((searchpath = zmalloc(strlen(dir) + 1, FILEPATH)) == 0) goto error_handler; strcpy(searchpath, dir); if (!task_digging(&root, searchpath)) err = 1; putchar('\n'); task_vomitting(&root, 0); zfree(searchpath, FILEPATH); if (!err) return 1; error_handler: fprintf(stderr, "task_main: terminated with abnomality<9>\n"); return 0; } int main(int argc, char *argv[]) { if (argc == 2) { if(!task_main(argv[1])) goto error; } else { error: fprintf(stderr, "usage: %s <dir>\n", argv[0]); xmallocdump(); return 1; } xmallocdump(); return 0; } /* end */
Private
[
?
]
Run code
Submit