forked from ThomasMertes/seed7
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbigfiles.sd7
128 lines (118 loc) · 4.85 KB
/
bigfiles.sd7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
(********************************************************************)
(* *)
(* bigfiles.sd7 Utility to search for big files. *)
(* Copyright (C) 2016 Thomas Mertes *)
(* *)
(* This program is free software; you can redistribute it and/or *)
(* modify it under the terms of the GNU General Public License as *)
(* published by the Free Software Foundation; either version 2 of *)
(* the License, or (at your option) any later version. *)
(* *)
(* This program is distributed in the hope that it will be useful, *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)
(* GNU General Public License for more details. *)
(* *)
(* You should have received a copy of the GNU General Public *)
(* License along with this program; if not, write to the *)
(* Free Software Foundation, Inc., 51 Franklin Street, *)
(* Fifth Floor, Boston, MA 02110-1301, USA. *)
(* *)
(********************************************************************)
$ include "seed7_05.s7i";
include "osfiles.s7i";
include "console.s7i";
const type: sizeMapType is hash [string] bigInteger;
const type: pathsWithLengthHash is hash [bigInteger] array string;
const func bigInteger: searchDir (in string: dirPath, inout sizeMapType: fileSizeMap,
inout sizeMapType: dirSizeMap) is func
result
var bigInteger: dirSize is 0_;
local
var array string: dirElements is 0 times "";
var string: fileName is "";
var string: filePath is "";
var bigInteger: fileSize is 0_;
begin
block
dirElements := readDir(dirPath);
exception
catch FILE_ERROR:
writeln(" *** Cannot read directory " <& dirPath);
end block;
for fileName range dirElements do
if dirPath = "/" then
filePath := "/" & fileName;
else
filePath := dirPath & "/" & fileName;
end if;
case fileTypeSL(filePath) of
when {FILE_REGULAR}:
fileSize := bigFileSize(filePath);
dirSize +:= fileSize;
fileSizeMap @:= [filePath] fileSize;
when {FILE_DIR}:
dirSize +:= searchDir(filePath, fileSizeMap, dirSizeMap);
when {FILE_SYMLINK}:
noop; # Ignore symbolic link.
end case;
end for;
dirSizeMap @:= [dirPath] dirSize;
end func;
const proc: showResults (in sizeMapType: sizeMap, in integer: lines) is func
local
var pathsWithLengthHash: pathsWithLength is pathsWithLengthHash.value;
var array bigInteger: lengthList is 0 times 0_;
var integer: lengthIndex is 0;
var bigInteger: length is 0_;
var string: path is "";
var integer: count is 0;
begin
pathsWithLength := flip(sizeMap);
lengthList := sort(keys(pathsWithLength));
for lengthIndex range maxIdx(lengthList) downto minIdx(lengthList) until count >= lines do
length := lengthList[lengthIndex];
if length in pathsWithLength then
for path range pathsWithLength[length] until count >= lines do
writeln(length lpad 14 <& ": " <& path);
incr(count);
end for;
end if;
end for;
end func;
const proc: main is func
local
var string: dirPath is "";
var integer: lines is 10;
var sizeMapType: fileSizeMap is sizeMapType.value;
var sizeMapType: dirSizeMap is sizeMapType.value;
begin
OUT := STD_CONSOLE;
if length(argv(PROGRAM)) < 1 then
writeln("Bigfiles Version 1.0 - Utility to search for big files.");
writeln("Copyright (C) 2016 Thomas Mertes");
writeln("This is free software; see the source for copying conditions. There is NO");
writeln("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
writeln("Bigfiles is written in the Seed7 programming language");
writeln("Homepage: http://seed7.sourceforge.net");
writeln;
writeln("usage: bigfiles directory [lines]");
writeln;
else
dirPath := convDosPath(argv(PROGRAM)[1]);
if length(argv(PROGRAM)) >= 2 then
block
lines := integer(argv(PROGRAM)[2]);
exception
catch RANGE_ERROR:
writeln(" ***** Number of lines not numeric. " <& lines <& " used instead.");
end block;
end if;
ignore(searchDir(dirPath, fileSizeMap, dirSizeMap));
writeln("Big files:");
showResults(fileSizeMap, lines);
writeln;
writeln("Big directories:");
showResults(dirSizeMap, lines);
end if;
end func;