Jim Meyering <[EMAIL PROTECTED]> wrote: > Thanks for the patch. FTR (for the record), a second version which does some "magic" to obtain the block-size argument and append it to the output.
I don't think, it'll be of much use now, but archiving doesn't hurt. Steven Schubiger diff --git a/src/df.c b/src/df.c index f0fdcd7..c9a84a2 100644 --- a/src/df.c +++ b/src/df.c @@ -118,10 +118,34 @@ enum SYNC_OPTION }; +/* If true, output disk "usage" summary. */ +static bool summarize_total; + +/* The summary container. */ +struct summary_total +{ + unsigned long blocks; + unsigned long used; + unsigned long avail; + int spacing; + int width; + int adjustment; +} summary; + +/* The buffer containing the readable disk-usage stats. */ +char *buf_readable[3]; + +/* If true, block-size argument provided. */ +static bool block_size; + +/* The block-size description. */ +char *suffix = NULL; + static struct option const long_options[] = { {"all", no_argument, NULL, 'a'}, {"block-size", required_argument, NULL, 'B'}, + {"total", no_argument, NULL, 'c' }, {"inodes", no_argument, NULL, 'i'}, {"human-readable", no_argument, NULL, 'h'}, {"si", no_argument, NULL, 'H'}, @@ -226,6 +250,15 @@ excluded_fstype (const char *fstype) return false; } +static int +integer_length (unsigned long num) +{ + int length = 1; + while ((num /= 10) >= 1) + length++; + return length; +} + /* Like human_readable (N, BUF, human_output_opts, INPUT_UNITS, OUTPUT_UNITS), except: @@ -265,7 +298,7 @@ df_readable (bool negative, uintmax_t n, char *buf, static void show_dev (char const *disk, char const *mount_point, char const *stat_file, char const *fstype, - bool me_dummy, bool me_remote) + bool me_dummy, bool me_remote, bool show_summary) { struct fs_usage fsu; char buf[3][LONGEST_HUMAN_READABLE + 2]; @@ -282,6 +315,9 @@ show_dev (char const *disk, char const *mount_point, bool negate_used; double pct = -1; + if (show_summary) + goto output_stats; + if (me_remote & show_local_fs) return; @@ -326,18 +362,33 @@ show_dev (char const *disk, char const *mount_point, size_t disk_name_len = strlen (disk); size_t fstype_len = strlen (fstype); if (disk_name_len + fstype_len < 18) - printf ("%s%*s ", disk, 18 - (int) disk_name_len, fstype); + { + printf ("%s%*s ", disk, 18 - (int) disk_name_len, fstype); + summary.spacing = disk_name_len + (18 - (int) disk_name_len + 2); + } else if (!posix_format) - printf ("%s\n%18s ", disk, fstype); + { + printf ("%s\n%18s ", disk, fstype); + summary.spacing = 20; + } else - printf ("%s %s", disk, fstype); + { + printf ("%s %s", disk, fstype); + summary.spacing = disk_name_len + 1 + fstype_len; + } } else { if (strlen (disk) > 20 && !posix_format) - printf ("%s\n%20s", disk, ""); + { + printf ("%s\n%20s", disk, ""); + summary.spacing = 20; + } else - printf ("%-20s", disk); + { + printf ("%-20s", disk); + summary.spacing = 20; + } } if (inode_format) @@ -375,6 +426,7 @@ show_dev (char const *disk, char const *mount_point, negate_available = (fsu.fsu_bavail_top_bit_set & (available != UINTMAX_MAX)); available_to_root = fsu.fsu_bfree; + } used = UINTMAX_MAX; @@ -385,14 +437,50 @@ show_dev (char const *disk, char const *mount_point, negate_used = (total < available_to_root); } - printf (" %*s %*s %*s ", - width + col1_adjustment, - df_readable (false, total, - buf[0], input_units, output_units), - width, df_readable (negate_used, used, - buf[1], input_units, output_units), - width, df_readable (negate_available, available, - buf[2], input_units, output_units)); + buf_readable[0] = (char *) df_readable (false, total, buf[0], input_units, output_units); + buf_readable[1] = (char *) df_readable (negate_used, used, buf[1], input_units, output_units); + buf_readable[2] = (char *) df_readable (negate_available, available, buf[2], input_units, output_units); + + output_stats: + if (!show_summary) + { + printf (" %*s %*s %*s ", + width + col1_adjustment, buf_readable[0], + width, buf_readable[1], + width, buf_readable[2]); + if (summarize_total) + { + summary.blocks += (unsigned long) atol (buf_readable[0]); + summary.used += (unsigned long) atol (buf_readable[1]); + summary.avail += (unsigned long) atol (buf_readable[2]); + summary.width = width; + summary.adjustment = col1_adjustment; + } + if (block_size) + { + if (suffix == NULL) + { + suffix = buf_readable[0]; + while (isdigit (*suffix++)); + suffix--; + } + } + else + { + if (suffix == NULL) + suffix = ""; + } + } + else + { + printf ("%*s %*s%lu%s %*s%lu%s %*s%lu%s ", + summary.spacing, "", + (summary.width + summary.adjustment) - integer_length (summary.blocks) - strlen (suffix), "", summary.blocks, suffix, + summary.width - integer_length (summary.used) - strlen (suffix), "", summary.used, suffix, + summary.width - integer_length (summary.avail) - strlen (suffix), "", summary.avail, suffix); + putchar ('\n'); + return; + } if (used == UINTMAX_MAX || available == UINTMAX_MAX) ; @@ -552,7 +640,7 @@ show_disk (char const *disk) { show_dev (best_match->me_devname, best_match->me_mountdir, NULL, best_match->me_type, best_match->me_dummy, - best_match->me_remote); + best_match->me_remote, false); return true; } @@ -656,7 +744,7 @@ show_point (const char *point, const struct stat *statp) if (best_match) show_dev (best_match->me_devname, best_match->me_mountdir, point, - best_match->me_type, best_match->me_dummy, best_match->me_remote); + best_match->me_type, best_match->me_dummy, best_match->me_remote, false); else { /* We couldn't find the mount entry corresponding to POINT. Go ahead and @@ -667,7 +755,7 @@ show_point (const char *point, const struct stat *statp) char *mp = find_mount_point (point, statp); if (mp) { - show_dev (NULL, mp, NULL, NULL, false, false); + show_dev (NULL, mp, NULL, NULL, false, false, false); free (mp); } } @@ -696,7 +784,13 @@ show_all_entries (void) for (me = mount_list; me; me = me->me_next) show_dev (me->me_devname, me->me_mountdir, NULL, me->me_type, - me->me_dummy, me->me_remote); + me->me_dummy, me->me_remote, false); +} + +static void +show_summary (void) +{ + show_dev (NULL, NULL, NULL, NULL, NULL, NULL, true); } /* Add FSTYPE to the list of file system types to display. */ @@ -745,6 +839,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\ fputs (_("\ -a, --all include dummy file systems\n\ -B, --block-size=SIZE use SIZE-byte blocks\n\ + -c, --total summarize disk usage\n\ -h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G)\n\ -H, --si likewise, but use powers of 1000 not 1024\n\ "), stdout); @@ -786,11 +881,13 @@ main (int argc, char **argv) atexit (close_stdout); + block_size = false; fs_select_list = NULL; fs_exclude_list = NULL; inode_format = false; show_all_fs = false; show_listed_fs = false; + summarize_total = false; human_output_opts = -1; print_type = false; file_systems_processed = false; @@ -800,7 +897,7 @@ main (int argc, char **argv) for (;;) { int oi = -1; - int c = getopt_long (argc, argv, "aB:iF:hHklmPTt:vx:", long_options, + int c = getopt_long (argc, argv, "aB:ciF:hHklmPTt:vx:", long_options, &oi); if (c == -1) break; @@ -817,7 +914,11 @@ main (int argc, char **argv) if (e != LONGINT_OK) xstrtol_fatal (e, oi, c, long_options, optarg); } + block_size = true; break; + case 'c': + summarize_total = true; + break; case 'i': inode_format = true; break; @@ -964,5 +1065,8 @@ main (int argc, char **argv) if (! file_systems_processed) error (EXIT_FAILURE, 0, _("no file systems processed")); + if (summarize_total) + show_summary (); + exit (exit_status); } _______________________________________________ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils