commit 7c38b724e9cf37eda0a682776bf255a2fecca043 from: Benjamin Stürz date: Mon May 15 21:47:59 2023 UTC Dynamic padding commit - 4d8e470cd10c08b876c3e336e9b0cf7fd4886b4d commit + 7c38b724e9cf37eda0a682776bf255a2fecca043 blob - 52ac4241cf3ded520b6b444b6c6b3f43c09a3784 blob + e0ad28be6592c25705e73fb742e3679d95679e26 --- ChangeLog.md +++ ChangeLog.md @@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](http - 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 @@ -21,7 +21,7 @@ doas make unroot - [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 @@ -16,6 +16,7 @@ #define _XOPEN_SOURCE 700 #define _BSD_SOURCE 1 #define DKTYPENAMES +#define WSDEBUG 0 #include #include #include @@ -161,10 +162,20 @@ struct my_diskinfo { 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"); @@ -179,11 +190,15 @@ static void print_header (int fields) 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'); } @@ -194,17 +209,25 @@ static void print_duid (const u_char *duid) } } -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) { @@ -232,25 +255,38 @@ static void print_part ( } 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) { @@ -267,25 +303,34 @@ static void print_disk (const struct my_diskinfo *disk 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); } } @@ -482,6 +527,42 @@ static int usage (void) 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; @@ -577,11 +658,20 @@ int main (int argc, char *argv[]) } } + 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;