#include #include #include typedef char *(Stamper)(vlong); typedef vlong (Parser)(char **); typedef struct Unit { char *name; Stamper *stamp; Parser *parse; } Unit; Stamper isostamp, ascstamp, nsstamp, μsstamp, msstamp, sstamp; Parser parsens, parseμs, parsems, parses; Unit utab[] = { {"iso", isostamp}, {"asc", ascstamp}, {"ns", nsstamp, parsens}, {"μs", μsstamp, parseμs}, {"ms", msstamp, parsems}, {"s", sstamp, parses}, }; Unit * ulookup(char *s) { int i; for(i=0; i < nelem(utab); i++) { if(strcmp(s, utab[i].name) == 0) return utab+i; } return nil; } char * skipspace(char *s) { return s + strspn(s, " "); } char * isostamp(vlong ns) { char *p; p = isotime(localtime(ns / (int)1e9)); p[26] = '\0'; return p; } char * ascstamp(vlong ns) { char *p; p = asctime(localtime(ns / (int)1e9)); p[28] = '\0'; return p; } char * nsstamp(vlong ns) { static char p[32]; sprint(p, "%lld", ns); return p; } vlong parsens(char **s) { vlong ns; ns = strtoll(*s, s, 0); *s = skipspace(*s); return ns; } char * μsstamp(vlong ns) { static char p[32]; sprint(p, "%lld", ns / (int)1e3); return p; } vlong parseμs(char **s) { vlong ns; ns = strtoll(*s, s, 0) * (int)1e3; *s = skipspace(*s); return ns; } char * msstamp(vlong ns) { static char p[32]; sprint(p, "%lld", ns / (int)1e6); return p; } vlong parsems(char **s) { vlong ns; ns = strtoll(*s, s, 0) * (int)1e6; *s = skipspace(*s); return ns; } char * sstamp(vlong ns) { static char p[32]; sprint(p, "%lld", ns / (int)1e9); return p; } vlong parses(char **s) { vlong ns; ns = strtoll(*s, s, 0) * (int)1e9; *s = skipspace(*s); return ns; } vlong parsenull(char **) { return nsec(); } void usage(void) { fprint(2, "usage: %s [-c fromunit] unit [file]\n", argv0); exits("usage"); } void main(int argc, char **argv) { Unit *fromunit, *tounit; Stamper *stamp; Parser *parse; int fd; Biobuf bin; char *line; fromunit = nil; ARGBEGIN { case 'c': { char *s = EARGF(usage()); if((fromunit = ulookup(s)) == nil) sysfatal("invalid unit: %s", s); } break; default: usage(); } ARGEND if(argc < 1) usage(); if((tounit = ulookup(*argv)) == nil) sysfatal("invalid unit: %s", *argv); argc--; argv++; if((stamp = tounit->stamp) == nil) sysfatal("can't output %s", tounit->name); if(fromunit == nil) parse = parsenull; else if((parse = fromunit->parse) == nil) sysfatal("can't parse %s", fromunit->name); switch(argc) { case 0: fd = 0; break; case 1: if((fd = open(argv[0], OREAD)) < 0) sysfatal("open %s: %r", argv[0]); break; default: usage(); SET(fd); } Binit(&bin, fd, OREAD); while((line = Brdline(&bin, '\n')) != nil) { line[Blinelen(&bin) - 1] = '\0'; if(print("%s %s\n", stamp(parse(&line)), line) < 0) sysfatal("print: %r"); } exits(nil); }