Added missing cap.
[AROS.git] / workbench / c / Avail.c
blob924fa6c3d9236b860921f4b8997695f844bcf470
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Avail CLI command
6 Lang: English
7 */
9 /******************************************************************************
12 NAME
14 Avail [CHIP | FAST | TOTAL | FLUSH] [H | HUMAN]
16 SYNOPSIS
18 CHIP/S, FAST/S, TOTAL/S, FLUSH/S, H=HUMAN/S
20 LOCATION
24 FUNCTION
26 Give a summary of the memory usage and availability in the system.
27 To free up unused memory that still may be allocated (libraries,
28 devices, fonts and such present in memory but whcih are currently
29 not in use), use the FLUSH option.
31 INPUTS
33 CHIP -- show only "chip" memory
34 FAST -- show only "fast" memory
35 TOTAL -- show information on memory regardless of type
36 FLUSH -- remove unnecessary things residing in memory
37 HUMAN -- display more human-readable values (gigabytes as "G",
38 megabytes as "M", kilobytes as "K")
40 RESULT
42 NOTES
44 "Chip" and "fast" memory are associated with the Amiga computer
45 and may not be applicable on your hardware platform.
47 EXAMPLE
49 BUGS
51 SEE ALSO
53 INTERNALS
55 HISTORY
57 ******************************************************************************/
59 #include <exec/execbase.h>
60 #include <exec/memory.h>
61 #include <proto/exec.h>
62 #include <dos/dos.h>
63 #include <proto/dos.h>
64 #include <utility/tagitem.h>
65 #include <string.h>
67 const TEXT version[] = "$VER: Avail 42.1 (8.12.2007)\n";
70 #define ARG_TEMPLATE "CHIP/S,FAST/S,TOTAL/S,FLUSH/S,H=HUMAN/S"
72 enum
74 ARG_CHIP = 0,
75 ARG_FAST,
76 ARG_TOTAL,
77 ARG_FLUSH,
78 ARG_HUMAN,
79 NOOFARGS
82 LONG printm(CONST_STRPTR head, ULONG *array, LONG num);
84 int __nocommandline = 1;
86 BOOL aHuman;
88 int main(void)
90 IPTR args[NOOFARGS] = { (IPTR)FALSE,
91 (IPTR)FALSE,
92 (IPTR)FALSE,
93 (IPTR)FALSE,
94 (IPTR)FALSE };
95 struct RDArgs *rda;
96 LONG error = 0;
97 BOOL bPrintErr = TRUE;
98 rda = ReadArgs(ARG_TEMPLATE, args, NULL);
100 if (rda != NULL)
102 UWORD typeCount = 0;
103 BOOL aChip = (BOOL)args[ARG_CHIP];
104 BOOL aFast = (BOOL)args[ARG_FAST];
105 BOOL aTotal = (BOOL)args[ARG_TOTAL];
106 BOOL aFlush = (BOOL)args[ARG_FLUSH];
107 aHuman = (BOOL)args[ARG_HUMAN];
109 if (aChip)
111 typeCount++;
113 if (aFast)
115 typeCount++;
117 if (aTotal)
119 typeCount++;
122 ULONG chip[4], fast[4], total[4];
124 if (typeCount > 1)
126 FPuts(Output(), "Only one of CHIP, FAST or TOTAL allowed\n");
127 bPrintErr = FALSE;
128 FreeArgs(rda);
130 return RETURN_FAIL;
132 else
134 if (aFlush)
136 APTR Mem;
138 Mem = AllocMem(0x7ffffff0, MEMF_PUBLIC);
139 if (Mem)
140 FreeMem(Mem, 0x7ffffff0);
143 if(aChip)
146 chip[0] = AvailMem(MEMF_CHIP);
148 if (printm(NULL, chip, 1) < 0)
150 error = RETURN_ERROR;
153 else if(aFast)
155 fast[0] = AvailMem(MEMF_FAST);
157 if (printm(NULL, fast, 1) < 0)
159 error = RETURN_ERROR;
162 else if (aTotal)
164 total[0] = AvailMem(MEMF_ANY);
166 if (printm(NULL, total, 1) < 0)
168 error = RETURN_ERROR;
171 else
173 Forbid();
175 chip[0] = AvailMem(MEMF_CHIP);
176 chip[2] = AvailMem(MEMF_CHIP | MEMF_TOTAL);
177 chip[3] = AvailMem(MEMF_CHIP | MEMF_LARGEST);
178 chip[1] = chip[2] - chip[0];
179 fast[0] = AvailMem(MEMF_FAST);
180 fast[2] = AvailMem(MEMF_FAST | MEMF_TOTAL);
181 fast[3] = AvailMem(MEMF_FAST | MEMF_LARGEST);
182 fast[1] = fast[2] - fast[0];
183 total[0] = AvailMem(MEMF_ANY);
184 total[2] = AvailMem(MEMF_ANY | MEMF_TOTAL);
185 total[3] = AvailMem(MEMF_ANY | MEMF_LARGEST);
186 total[1] = total[2] - total[0];
188 Permit();
190 if (PutStr("Type Available In-Use Maximum Largest\n") < 0 ||
191 printm("chip", chip, 4) < 0 ||
192 printm("fast", fast, 4) < 0 ||
193 printm("total", total, 4) < 0)
195 error = RETURN_ERROR;
200 FreeArgs(rda);
202 else
204 error = RETURN_FAIL;
207 if(error != RETURN_OK && bPrintErr)
209 PrintFault(IoErr(), "Avail");
212 return error;
215 static
216 void fmtlarge(UBYTE *buf, ULONG num)
218 UQUAD d;
219 UBYTE ch;
220 struct
222 ULONG val;
223 LONG dec;
224 } array =
226 num,
230 if (num >= 1073741824)
232 array.val = num >> 30;
233 d = ((UQUAD)num * 10 + 536870912) / 1073741824;
234 array.dec = d % 10;
235 ch = 'G';
237 else if (num >= 1048576)
239 array.val = num >> 20;
240 d = ((UQUAD)num * 10 + 524288) / 1048576;
241 array.dec = d % 10;
242 ch = 'M';
244 else if (num >= 1024)
246 array.val = num >> 10;
247 d = (num * 10 + 512) / 1024;
248 array.dec = d % 10;
249 ch = 'K';
251 else
253 array.val = num;
254 array.dec = 0;
255 d = 0;
256 ch = 'B';
259 if (!array.dec && (d > array.val * 10))
261 array.val++;
264 RawDoFmt(array.dec ? "%lu.%lu" : "%lu", &array, NULL, buf);
265 while (*buf) { buf++; }
266 *buf++ = ch;
267 *buf = '\0';
270 LONG printm(CONST_STRPTR head, ULONG *array, LONG num)
272 LONG res = -1;
273 CONST_STRPTR fmt;
274 UBYTE buf[10];
276 if (head)
278 LONG len = 16 - strlen(head);
279 RawDoFmt(aHuman ? "%%%lds" : "%%%ldlu", &len, NULL, buf);
280 fmt = buf;
281 PutStr(head);
283 else
285 fmt = aHuman ? "%9s" : "%9lu";
288 if (aHuman)
290 if (num == 1)
292 fmtlarge(buf, *array);
293 res = PutStr(buf);
295 else
297 while (num--)
299 UBYTE tmp[10];
301 fmtlarge(tmp, *array);
302 res = Printf(fmt, (IPTR) tmp);
303 if (res < 0)
304 break;
306 fmt = " %9s";
307 array++;
311 else
313 if (num == 1)
315 res = VPrintf("%lu", (IPTR *)array);
317 else
319 while (num--)
321 res = VPrintf(fmt, (IPTR *)array);
322 if (res < 0)
323 break;
325 fmt = " %9lu";
326 array++;
330 PutStr("\n");
332 return res;