mscan: use format strings

pull/2/head
Christian Neukirchen 8 years ago
parent 688dd61818
commit f628a10ff6

@ -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);
}

Loading…
Cancel
Save