strings.c - sbase - suckless unix tools
 (HTM) git clone git://git.suckless.org/sbase
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       strings.c (1708B)
       ---
            1 /* See LICENSE file for copyright and license details. */
            2 #include <limits.h>
            3 #include <stdio.h>
            4 #include <stdlib.h>
            5 #include <string.h>
            6 
            7 #include "utf.h"
            8 #include "util.h"
            9 
           10 static char *format = "";
           11 
           12 static void
           13 strings(FILE *fp, const char *fname, size_t min)
           14 {
           15         Rune r, *rbuf;
           16         size_t i, bread;
           17         off_t off;
           18 
           19         rbuf = ereallocarray(NULL, min, sizeof(*rbuf));
           20 
           21         for (off = 0, i = 0; (bread = efgetrune(&r, fp, fname)); ) {
           22                 off += bread;
           23                 if (r == Runeerror)
           24                         continue;
           25                 if (!isprintrune(r)) {
           26                         if (i == min)
           27                                 putchar('\n');
           28                         i = 0;
           29                         continue;
           30                 }
           31                 if (i == min) {
           32                         efputrune(&r, stdout, "<stdout>");
           33                         continue;
           34                 }
           35                 rbuf[i++] = r;
           36                 if (i < min)
           37                         continue;
           38                 printf(format, (long)off - i);
           39                 for (i = 0; i < min; i++)
           40                         efputrune(rbuf + i, stdout, "<stdout>");
           41         }
           42         free(rbuf);
           43 }
           44 
           45 static void
           46 usage(void)
           47 {
           48         eprintf("usage: %s [-a] [-n num] [-t format] [file ...]\n", argv0);
           49 }
           50 
           51 int
           52 main(int argc, char *argv[])
           53 {
           54         FILE *fp;
           55         size_t min = 4;
           56         int ret = 0;
           57         char f;
           58 
           59         ARGBEGIN {
           60         case 'a':
           61                 break;
           62         case 'n':
           63                 min = estrtonum(EARGF(usage()), 1, LLONG_MAX);
           64                 break;
           65         case 't':
           66                 format = estrdup("%8l#: ");
           67                 f = *EARGF(usage());
           68                 if (f == 'd' || f == 'o' || f == 'x')
           69                         format[3] = f;
           70                 else
           71                         usage();
           72                 break;
           73         default:
           74                 usage();
           75         } ARGEND
           76 
           77         if (!argc) {
           78                 strings(stdin, "<stdin>", min);
           79         } else {
           80                 for (; *argv; argc--, argv++) {
           81                         if (!strcmp(*argv, "-")) {
           82                                 *argv = "<stdin>";
           83                                 fp = stdin;
           84                         } else if (!(fp = fopen(*argv, "r"))) {
           85                                 weprintf("fopen %s:", *argv);
           86                                 ret = 1;
           87                                 continue;
           88                         }
           89                         strings(fp, *argv, min);
           90                         if (fp != stdin && fshut(fp, *argv))
           91                                 ret = 1;
           92                 }
           93         }
           94 
           95         ret |= fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>");
           96 
           97         return ret;
           98 }