morpheus-base

morpheus base system
git clone git://git.2f30.org/morpheus-base.git
Log | Files | Refs

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 }