plan9fox/sys/src/cmd/strings.c

102 lines
1.4 KiB
C

#include <u.h>
#include <libc.h>
#include <bio.h>
Biobuf fin;
Biobuf fout;
void stringit(int);
int isprint(Rune);
int minspan = 6; /* Min characters in string (default) */
Rune *span;
static void
usage(void)
{
fprint(2, "usage: %s [-m min] [file...]\n", argv0);
exits("usage");
}
void
main(int argc, char **argv)
{
int i, fd;
ARGBEGIN{
case 'm':
minspan = atoi(EARGF(usage()));
if(minspan <= 0)
usage();
break;
default:
usage();
break;
}ARGEND
span = malloc(sizeof(Rune)*(minspan+1));
if(span == nil)
sysfatal("out of memory");
Binit(&fout, 1, OWRITE);
if(argc < 1) {
stringit(0);
exits(0);
}
for(i = 0; i < argc; i++) {
if(argc > 1){
Bprint(&fout, "%s:\n", argv[i]);
Bflush(&fout);
}
if((fd = open(argv[i], OREAD)) < 0){
perror("open");
continue;
}
stringit(fd);
close(fd);
}
exits(0);
}
void
stringit(int fd)
{
Rune *sp;
long c;
Binit(&fin, fd, OREAD);
sp = span;
while((c = Bgetrune(&fin)) >= 0) {
if(isprint(c)) {
if(sp == nil){
Bputrune(&fout, c);
continue;
}
*sp++ = c;
if((sp-span) < minspan)
continue;
*sp = 0;
Bprint(&fout, "%8lld: %S", Boffset(&fin)-minspan, span);
sp = nil;
} else {
if(sp == nil)
Bputrune(&fout, '\n');
sp = span;
}
}
if(sp == nil)
Bputrune(&fout, '\n');
Bterm(&fin);
}
int
isprint(Rune r)
{
if (r != Runeerror)
if ((r >= ' ' && r < 0x7F) || r > 0xA0)
return 1;
return 0;
}