/* "TAB" written by Leor Zolman command format: A>TAB oldfile newfile This program takes a text file and converts sequences of spaces into tabs wherever possible. There shouldn't be any control characters within the file, except for carriage returns and linefeeds, or things will get all screwed up. Also, there shouldn't be any double quotes (") within the file except as string delimiters; i.e, tabify shouldn't be used on itself because of the quote in this sentence and the double quotes enclosed within single quotes further down in the file. The input file isn't altered; the result is a new file named by the second argument. The most common use of this program is to tabify text files which you've loaded in over the phone from a computer system (like UNIX) that tends to turn all tabs into spaces for 300 baud DECwriters. 24/Jun/84 Adapted BDS C version for DR C compiler, added better improved file opening module and usage message, broke TAB code off into its own function, tidied up a few minor bugs. Bill Bolton, Software Tools RCPM, Australia */ #include #define VERS 1 /* main version number */ #define REVISION 0 /* sub version number */ #define CPMEOF 0x1A /* CP/M-86 end of file marker */ #define ERROR 0 /* Normal file error condition */ #define FERROR -1 /* Flush file error */ /* Argument vector indices */ #define FROM_FILE 1 #define TO_FILE 2 main(argc,argv) int argc; char *argv[]; { FILE *fdin,*fdout; printf("\nReplaces multiple spaces with TABs, CP/M-86 Version %d.%d\n",VERS,REVISION); printf("Software Tools\n"); if( argc != 3 ) usage(); else { if( (fdin = fopen(argv[FROM_FILE],"r")) == ERROR){ printf("\nCannot find file %s\n",argv[FROM_FILE]); usage(); } else { if( (fdout = fopen(argv[TO_FILE],"w")) == ERROR ) printf("\nCan't open %s\n",argv[TO_FILE]); else { printf("\nWorking\n"); tabify(fdin,fdout); } } } exit(); } tabify(fdin,fdout) FILE *fdin; /* the input file buffer */ FILE *fdout; /* the output file buffer */ { int space, column, i; int c; space = column = 0; do { c = getc(fdin); if (c == FERROR) { putc(CPMEOF,fdout); break; } switch(c) { case 0x0d: putc1(c,fdout); space = 0; column = 0; break; case 0x0a: putc1(c,fdout); column = 0; space = 0; break; case ' ': column++; space++; if (!(column % 8)) { if (space > 1) putc1('\t',fdout); else putc1(' ',fdout); space = 0; } break; case '\t': space = 0; column += (8 - (column % 8)); putc1('\t',fdout); break; case '"': for (i = 0; i < space; i++) putc1(' ',fdout); putc1('"',fdout); do { c = getc(fdin); if (c == FERROR) { printf("Quote error.\n"); exit(); } putc1(c,fdout); } while (c != '"'); do { c = getc(fdin); putc1(c,fdout); } while (c != 0x0a); column = 0; space = 0; break; case CPMEOF: putc(CPMEOF,fdout); break; default: for (i = 0; i < space; i++){ putc1(' ',fdout); } space = 0; column++; putc1 (c,fdout); } } while (c != CPMEOF); fclose(fdin); if (fclose(fdout) == FERROR) exit(puts("\nOutput file close error\n")); } putc1(c,buf) char c; { /* putchar(c); */ if (putc(c,buf) < 0) { printf("\n\nTAB : disk write error."); exit(); } } usage() { printf("\nUsage:\n\n"); printf("\tTAB d:file1 d:file2\n\n"); printf("Where:\n"); printf("\tfile1 = source file, (* and ? not allowed)\n"); printf("\tfile2 = destination file, (* and ? not allowed)\n"); printf("\td: = optional drive identifier\n\n"); printf("i.e.\tTAB A:FOOBAR.TXT B:FUBAR.DOC\n"); } /* End of TAB */