expand.c (1497B)
1 /* See LICENSE file for copyright and license details. */ 2 #include <stdio.h> 3 #include <stdlib.h> 4 5 #include "utf.h" 6 #include "util.h" 7 8 static int expand(const char *, FILE *, int); 9 10 static int iflag = 0; 11 12 static void 13 usage(void) 14 { 15 eprintf("usage: %s [-i] [-t n] [file...]\n", argv0); 16 } 17 18 int 19 main(int argc, char *argv[]) 20 { 21 FILE *fp; 22 int tabstop = 8; 23 int ret = 0; 24 25 ARGBEGIN { 26 case 'i': 27 iflag = 1; 28 break; 29 case 't': 30 tabstop = estrtol(EARGF(usage()), 0); 31 if (!tabstop) 32 eprintf("tab size cannot be zero\n"); 33 break; 34 default: 35 usage(); 36 } ARGEND; 37 38 if (argc == 0) { 39 expand("<stdin>", stdin, tabstop); 40 } else { 41 for (; argc > 0; argc--, argv++) { 42 if (!(fp = fopen(argv[0], "r"))) { 43 weprintf("fopen %s:", argv[0]); 44 ret = 1; 45 continue; 46 } 47 expand(argv[0], fp, tabstop); 48 fclose(fp); 49 } 50 } 51 return ret; 52 } 53 54 static int 55 expand(const char *file, FILE *fp, int tabstop) 56 { 57 int col = 0; 58 Rune r; 59 int bol = 1; 60 61 for (;;) { 62 if (!readrune(file, fp, &r)) 63 break; 64 65 switch (r) { 66 case '\t': 67 if (bol || !iflag) { 68 do { 69 col++; 70 putchar(' '); 71 } while (col % tabstop); 72 } else { 73 putchar('\t'); 74 col += tabstop - col % tabstop; 75 } 76 break; 77 case '\b': 78 if (col) 79 col--; 80 bol = 0; 81 writerune("<stdout>", stdout, &r); 82 break; 83 case '\n': 84 col = 0; 85 bol = 1; 86 writerune("<stdout>", stdout, &r); 87 break; 88 default: 89 col++; 90 if (r != ' ') 91 bol = 0; 92 writerune("<stdout>", stdout, &r); 93 break; 94 } 95 } 96 97 return 0; 98 }