aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Neukirchen <chneukirchen@gmail.com>2016-08-04 18:59:46 +0200
committerChristian Neukirchen <chneukirchen@gmail.com>2016-08-04 18:59:46 +0200
commitf628a10ff6c8e359036984c0a37a9cd1d3784914 (patch)
treec37ce1663c96c484400281265a62d22f2d1335df
parent688dd618180b5801a0ec7382b3745f4699a14f9b (diff)
downloadmblaze-f628a10ff6c8e359036984c0a37a9cd1d3784914.tar.gz
mscan: use format strings
-rw-r--r--mscan.c254
1 files changed, 197 insertions, 57 deletions
diff --git a/mscan.c b/mscan.c
index 6bc7d4c..4023910 100644
--- a/mscan.c
+++ b/mscan.c
@@ -29,6 +29,8 @@ static int Iflag;
static int nflag;
static int curyear;
static int curyday;
+static char default_fflag[] = "%c%m %-3n %10d %17f %t %2i%s";
+static char *fflag = default_fflag;
void
u8putstr(FILE *out, char *s, ssize_t l, int pad)
@@ -95,11 +97,63 @@ numline(char *file)
printf("%s\n", file);
}
+static char *
+fmt_date(struct message *msg, int w, int iso)
+{
+ static char date[32];
+ char *v;
+
+ if (!msg)
+ return "";
+
+ if ((v = blaze822_hdr(msg, "date"))) {
+ time_t t = blaze822_date(v);
+ if (t != -1) {
+ struct tm *tm;
+ tm = localtime(&t);
+
+ if (iso && w >= 19)
+ strftime(date, sizeof date, "%Y-%m-%d %H:%M:%S", tm);
+ else if (iso || tm->tm_year != curyear)
+ strftime(date, sizeof date, "%Y-%m-%d", tm);
+ else if (tm->tm_yday != curyday)
+ strftime(date, sizeof date, "%a %b %e", tm);
+ else
+ strftime(date, sizeof date, "%a %H:%M", tm);
+ } else {
+ strcpy(date, "(invalid)");
+ }
+ } else {
+ strcpy(date, "(unknown)");
+ // mtime perhaps?
+ }
+
+ return date;
+}
+
+static void
+print_human(intmax_t i)
+{
+ double d = i / 1024.0;
+ const char *u = "\0\0M\0G\0T\0P\0E\0Z\0Y\0";
+ while (d >= 1024) {
+ u += 2;
+ d /= 1024.0;
+ }
+
+ if (d < 1.0)
+ printf("%4.2f", d);
+ else if (!*u)
+ printf("%4.0f", d);
+ else if (d < 10.0)
+ printf("%3.1f%s", d, u);
+ else
+ printf("%3.0f%s", d, u);
+}
+
void
oneline(char *file)
{
- int metawidth = 38;
-
if (!init) {
// delay loading of the seq until we need to scan the first
// file, in case someone in the pipe updated the map before
@@ -114,69 +168,41 @@ oneline(char *file)
indent++;
file++;
}
- indent *= 2;
char *e = file + strlen(file) - 1;
while (file < e && (*e == ' ' || *e == '\t'))
*e-- = 0;
struct message *msg = blaze822(file);
- if (!msg) {
- int p = cols-metawidth-3-indent;
- printf("%*.*s\\_ %*.*s\n", -metawidth - indent, metawidth + indent, "",
- -p, p, file);
- return;
- }
+ if (!msg)
+ goto nomsg;
char flag1, flag2, flag3;
- char *f = strstr(file, ":2,");
- if (!f)
- f = "";
+ char *flags = strstr(file, ":2,");
+ if (!flags)
+ flags = "";
+ else
+ flags += 3;
if (cur && strcmp(cur, file) == 0)
flag1 = '>';
- else if (!strchr(f, 'S'))
+ else if (!strchr(flags, 'S'))
flag1 = '.';
- else if (strchr(f, 'T'))
+ else if (strchr(flags, 'T'))
flag1 = 'x';
else
flag1 = ' ';
- if (strchr(f, 'F'))
+ if (strchr(flags, 'F'))
flag2 = '*';
- else if (strchr(f, 'R'))
+ else if (strchr(flags, 'R'))
flag2 = '-';
else
flag2 = ' ';
- char date[32];
char *v;
- if ((v = blaze822_hdr(msg, "date"))) {
- time_t t = blaze822_date(v);
- if (t != -1) {
- struct tm *tm;
- tm = localtime(&t);
-
- if (Iflag > 1) {
- strftime(date, sizeof date,
- "%Y-%m-%d %H:%M:%S", tm);
- metawidth += 9;
- } else if (Iflag || tm->tm_year != curyear)
- strftime(date, sizeof date, "%Y-%m-%d", tm);
- else if (tm->tm_yday != curyday)
- strftime(date, sizeof date, "%a %b %e", tm);
- else
- strftime(date, sizeof date, "%a %H:%M", tm);
- } else {
- strcpy(date, "(invalid)");
- }
- } else {
- strcpy(date, "(unknown)");
- // mtime perhaps?
- }
-
flag3 = ' ';
if (alias_idx) {
if ((v = blaze822_hdr(msg, "to")) && itsme(v))
@@ -217,21 +243,134 @@ oneline(char *file)
blaze822_decode_rfc2047(subjdec, subj, sizeof subjdec - 1, "UTF-8");
long lineno = blaze822_seq_find(file);
- if (lineno)
- printf("%c%c %-3ld %-10s ", flag1, flag2, lineno, date);
- else
- printf("%c%c %-10s ", flag1, flag2, date);
- u8putstr(stdout, fromdec, 16, 1);
- printf(" %c ", flag3);
- int z;
- if (indent > 18) {
- printf("..%2d.. ", indent/2);
- indent = 20;
- } else {
- for (z = 0; z < indent; z++)
- printf(" ");
+
+ if (0) {
+nomsg:
+ flag1 = flag2 = flag3 = ' ';
+ *fromdec = 0;
+ snprintf(subjdec, sizeof subjdec, "\\_ %s", file);
+ lineno = 0;
}
- u8putstr(stdout, subjdec, cols-metawidth-indent, 0);
+
+ int wleft = cols;
+
+ char *f;
+ for (f = fflag; *f; f++) {
+ if (*f != '%') {
+ putchar(*f);
+ wleft--;
+ continue;
+ }
+ f++;
+
+ int w = 0;
+ if ((*f >= '0' && *f <= '9') || *f == '-') {
+ errno = 0;
+ char *e;
+ w = strtol(f, &e, 10);
+ if (errno != 0)
+ w = 0;
+ else
+ f = e;
+ }
+
+ if (!*f)
+ break;
+
+ switch(*f) {
+ case '%':
+ putchar('%');
+ wleft--;
+ break;
+ case 'c':
+ putchar(flag1);
+ wleft--;
+ break;
+ case 'm':
+ putchar(flag2);
+ wleft--;
+ break;
+ case 'M':
+ if (!w) w = -3;
+ wleft -= printf("%.*s", w, flags);
+ break;
+ case 'n':
+ if (lineno)
+ printf("%*ld", w, lineno);
+ else
+ printf("%*s", w, "");
+ wleft -= w > 0 ? w : -w;
+ break;
+ case 'd':
+ case 'D':
+ if (!w) w = 10;
+ wleft -= printf("%*s", w,
+ fmt_date(msg, w, Iflag || *f == 'D'));
+ break;
+ case 'f':
+ u8putstr(stdout, fromdec, w ? w : 16, 1);
+ wleft -= w > 0 ? w : -w;
+ break;
+ case 't':
+ putchar(flag3);
+ wleft--;
+ break;
+ case 'i':
+ {
+ int z;
+ if (!w)
+ w = 1;
+
+ if (indent >= 10) {
+ wleft -= printf("..%2d..", indent);
+ indent = 10 - 6/w;
+ }
+
+ for (z = 0; z < w*indent; z++)
+ putchar(' ');
+ wleft -= w*indent;
+ }
+ break;
+ case 's':
+ if (!w) w = wleft;
+ u8putstr(stdout, subjdec, wleft, 0);
+ wleft -= w;
+ break;
+ case 'b':
+ {
+ struct stat st;
+ if (stat(file, &st) != 0)
+ st.st_size = 0;
+ print_human(st.st_size);
+ wleft -= 5;
+ }
+ break;
+ case 'F':
+ {
+ if (!w) w = 10;
+ char *e = file + strlen(file);
+ while (file < e && *e != '/')
+ e--;
+ e--;
+ while (file < e && *e != '/')
+ e--;
+ char *b = e - 1;
+ while (file < b && *b != '/')
+ b--;
+ if (*b == '/')
+ b++;
+ if (*b == '.')
+ b++;
+ wleft -= printf("%*.*s", w, e-b, b);
+ }
+ break;
+ default:
+ putchar('%');
+ putchar(*f);
+ wleft -=2;
+ }
+ }
+
printf("\n");
blaze822_free(msg);
@@ -241,12 +380,13 @@ int
main(int argc, char *argv[])
{
int c;
- while ((c = getopt(argc, argv, "In")) != -1)
+ while ((c = getopt(argc, argv, "If:n")) != -1)
switch(c) {
case 'I': Iflag++; break;
+ case 'f': fflag = optarg; break;
case 'n': nflag = 1; break;
default:
- fprintf(stderr, "Usage: mscan [-n] [-I] [msgs...]\n");
+ fprintf(stderr, "Usage: mscan [-n] [-f format] [-I] [msgs...]\n");
exit(1);
}