commit - 4d8e470cd10c08b876c3e336e9b0cf7fd4886b4d
commit + 7c38b724e9cf37eda0a682776bf255a2fecca043
blob - 52ac4241cf3ded520b6b444b6c6b3f43c09a3784
blob + e0ad28be6592c25705e73fb742e3679d95679e26
--- ChangeLog.md
+++ ChangeLog.md
- Use err(3) instead of die()
- Use opendev(3) instead of open(2)
- Sort drives by name
+- Dynamic padding of output
### Removed
- Options:
blob - 084ec3cda9ac1b0305f463d7195f892c976d7abf
blob + efe7acbfe3aedd6f35039740dc8261d1e4961759
--- README.md
+++ README.md
- [x] `lsblk sd0`
- [ ] `lsblk sd0a`
- [ ] `lsblk -f duid,size`
-- [ ] Don't use manual padding.
+- [x] Don't use manual padding.
- [ ] Support disks that have more than 2 letters, like `vnd0`
- [x] Sort drives by name
- [ ] Add an option to make the output script-friendly (like -c for CSV).
blob - ca98c5850b44dfca7a1c2ae4c5d66f80a9431e72
blob + 6ea37c84af0cea4280740df6659015248522108c
--- lsblk.c
+++ lsblk.c
#define _XOPEN_SOURCE 700
#define _BSD_SOURCE 1
#define DKTYPENAMES
+#define WSDEBUG 0
#include <stddef.h>
#include <dev/biovar.h>
#include <sys/cdefs.h>
const char *raidstatus; // If this is a RAID device
};
-static void print_header (int fields)
+struct padding {
+ int name;
+ /* duid = 8 */
+ /* size = 4 */
+ /* used = 4 */
+ /* free = 4 */
+ int type;
+ int comment;
+};
+
+static void print_header (int fields, const struct padding *p)
{
if (fields & FIELD_NAME)
- printf ("%-7s ", "NAME");
+ printf ("%-*s ", p->name, "NAME");
if (fields & FIELD_DUID)
printf ("%-18s ", "DUID");
printf ("%-4s ", "FREE");
if (fields & FIELD_TYPE)
- printf ("%-8s ", "TYPE");
+ printf ("%-*s ", p->type, "TYPE");
if (fields & FIELD_COMMENT)
- printf ("COMMENT ");
+ printf ("%-*s ", p->comment, "COMMENT");
+#if WSDEBUG
+ putchar ('X');
+#endif
+
putchar ('\n');
}
}
}
-static void print_disk (const struct my_diskinfo *disk, int fields, int options, const char *raidstatus);
+static void print_disk (const struct my_diskinfo *, int, int, const char *, const struct padding *);
static void print_part (
const struct my_diskinfo *disk,
const struct my_partinfo *part,
int fields,
int options,
- bool last
+ bool last,
+ const struct padding *p
) {
if (fields & FIELD_NAME) {
const char *prefix = (options & OPT_NOUNICODE) ? " " : (last ? "└─" : "├─");
- printf ("%s%s%c ", prefix, disk->name, part->letter);
+ printf (
+ "%s%s%c%-*s ",
+ prefix,
+ disk->name,
+ part->letter,
+ p->name - 2 - (int)strlen (disk->name) - 1,
+ ""
+ );
}
if (fields & FIELD_DUID) {
}
if (fields & FIELD_TYPE)
- printf ("%-8.16s ", part->fstype);
+ printf ("%-*s ", p->type, part->fstype);
- if (fields & FIELD_COMMENT && part->mount)
- printf ("%s ", part->mount);
+ if (fields & FIELD_COMMENT)
+ printf ("%-*s ", p->comment, part->mount ? part->mount : "");
+#if WSDEBUG
+ putchar ('X');
+#endif
+
putchar ('\n');
if (part->sub) {
- printf ("│ └─");
- print_disk (part->sub, fields, options, part->raidstatus);
+ print_disk (part->sub, fields, options, part->raidstatus, p);
}
}
-static void print_disk (const struct my_diskinfo *disk, int fields, int options, const char *raidstatus)
-{
+static void print_disk (
+ const struct my_diskinfo *disk,
+ int fields,
+ int options,
+ const char *raidstatus,
+ const struct padding *p
+) {
if (fields & FIELD_NAME) {
- printf ("%s ", disk->name);
- if (!raidstatus)
- printf (" ");
+ const char *prefix = raidstatus ? "│ └─" : "";
+
+ printf (
+ "%s%-*s ",
+ prefix,
+ p->name - (int)strlen (prefix),
+ disk->name
+ );
}
if (fields & FIELD_DUID) {
if (fields & FIELD_FREE)
print_size (disk->size - disk->used);
- // Pad only upto 8 characters because most disk types are <=8 bytes long.
if (fields & FIELD_TYPE)
- printf ("%-8.16s ", disk->type);
+ printf ("%-*.16s ", p->type, disk->type);
if (fields & FIELD_COMMENT) {
if (raidstatus) {
- printf ("%s ", raidstatus);
+ printf ("%-*s ", p->comment, raidstatus);
} else if (disk->raidstatus) {
- printf ("%.16s (%s) ", disk->label, disk->raidstatus);
+ printf (
+ "%.16s (%s)%*s ",
+ disk->label,
+ disk->raidstatus,
+ p->comment - (int)strnlen (disk->label, sizeof disk->label) - (int)strlen (disk->raidstatus) - 3,
+ ""
+ );
} else {
- printf ("%.16s ", disk->label);
+ printf ("%-*.16s ", p->comment, disk->label);
}
}
+#if WSDEBUG
+ putchar ('X');
+#endif
+
putchar ('\n');
if (!raidstatus) {
for (uint8_t i = 0; i < disk->num_parts; ++i)
- print_part (disk, &disk->parts[i], fields, options, i == (disk->num_parts - 1));
+ print_part (disk, &disk->parts[i], fields, options, i == (disk->num_parts - 1), p);
}
}
return 1;
}
+static void pad_update (int *pad, int newval)
+{
+ if (newval > *pad)
+ *pad = newval;
+}
+
+static void pad_disk (struct padding *p, const struct my_diskinfo *disk)
+{
+ size_t len_disk;
+ int comment;
+
+ len_disk = strnlen (disk->name, sizeof disk->name);
+ comment = strnlen (disk->label, sizeof disk->label);
+ if (disk->raidstatus)
+ comment += strlen (disk->raidstatus) + 3;
+
+ pad_update (&p->name, len_disk);
+ pad_update (&p->type, strnlen (disk->type, sizeof disk->type));
+ pad_update (&p->comment, comment);
+
+ for (int i = 0; i < disk->num_parts; ++i) {
+ const struct my_partinfo *part = &disk->parts[i];
+
+ pad_update (&p->name, len_disk + 3);
+ pad_update (&p->type, strlen (part->fstype));
+
+ if (part->sub) {
+ pad_update (&p->name, strnlen (part->sub->name, sizeof part->sub->name) + 4);
+ pad_update (&p->comment, strlen (part->raidstatus));
+ } else if (part->mount) {
+ pad_update (&p->comment, strlen (part->mount));
+ }
+ }
+}
+
+
static int compare_disk (const void *p1, const void *p2)
{
const struct my_diskinfo *d1 = p1;
}
}
+ struct padding p = {
+ .name = strlen ("NAME"),
+ .type = strlen ("TYPE"),
+ .comment = strlen ("COMMENT"),
+ };
+
+ for (size_t i = 0; i < num_disks; ++i)
+ pad_disk (&p, &disks[i]);
+
if (!(options & OPT_NOHEADER))
- print_header (fields);
+ print_header (fields, &p);
for (size_t i = 0; i < num_disks; ++i) {
- print_disk (&disks[i], fields, options, false);
+ print_disk (&disks[i], fields, options, NULL, &p);
}
return 0;