/* * entab file */ /*)BUILD $(TKBOPTIONS) = { TASK = ...ENT } */ #ifdef DOCUMENTATION title entab Replace blanks by tabs and blanks index Replace blanks by tabs and blanks synopsis .s.nf entab [-t] infile outfile .s.f description Copies input to output, replacing sequences of blanks and tabs by the minimum number of tabs and blanks required to give the same visual effect. Trailing blank/tabs are removed. overstrikes are handled. If -t is given, a single blank will be output as if valid. For example, if the string: 1234567 8 is given, the program will output a space following the '7'. If -t is given, the program will output a . diagnostics None author Martin Minow (Taken from Kernighan and Plauger, Software Tools) bugs Tabs occur every eight column only. On VMS, a file produced when an explicit output file spec is provided will be in "C format" (STREAM_LF records). If you use redirection, the output will be variable-length records with implied carriage control - which is more easily dealt with in many cases. #endif #include #define BLANK ' ' #define TAB '\t' #define RETURN '\r' #define NEWLINE '\n' #define FALSE 0 #define TRUE 1 int tflag = FALSE; main(argc, argv) char *argv[]; { register int c; register int col; register int newcol; int lastc; #ifdef vms argc = getredirection(argc,argv); #endif col = FALSE; /* TRUE if input redirected */ for (c = 1; c < argc; c++) { if (argv[c][0] == '-') { if (tolower(argv[c][1]) == 't') tflag++; else { fprintf(stderr, "Unknown option \"%s\"\n", argv[c]); } } else { if (!col) { freopen(argv[c], "r", stdin); col++; } else { freopen(argv[c], "w", stdout); } } } c = EOF; col = 0; /* Tab stops at 0, 8, 16, ... */ for (;;) { newcol = col; for (;;) { lastc = c; switch (c = getchar()) { case BLANK: newcol++; continue; case TAB: newcol = nexttabstop(newcol); continue; default: break; /* Exits for loop */ } break; /* Neither BLANK nor TAB */ } if (c == EOF) { if (newcol > 0) { putchar(NEWLINE); } break; } else if (c == RETURN || c == NEWLINE) { col = 0; putchar(c); } else { /* * If -t was not given and the last character was * a blank and there's just one blank, don't do * a tab here. */ if (tflag || lastc == TAB || (col + 1) < newcol) { while (nexttabstop(col) <= newcol) { putchar(TAB); col = nexttabstop(col); } } while (col < newcol) { putchar(BLANK); col++; } putchar(c); col++; } } } nexttabstop(col) register int col; /* * Return the next tab stop after col (col == 1 -> 8) */ { return (col + (8 - (col & 7))); }