home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / TOOLS2.ZIP / RETAB.C < prev    next >
Text File  |  1987-08-18  |  6KB  |  207 lines

  1. /*
  2.     HEADER:        CUG000.00;
  3.     TITLE:        Entab/Detab/Strip Combo;
  4.     DATE:        05/17/1987;
  5.     DESCRIPTION:    "Strips upper-order bits, detabifies, then entabifies a
  6.             text file.  Old and new tab increments can differ.  If
  7.             new increment is 1, no entabification occurs.";
  8.     VERSION:    0.0;
  9.     KEYWORDS:    Tab, Tabs, Tab Expansion, Tab Utility, Tabify, Untab,
  10.             Detab, Detab Utility;
  11.     FILENAME:    RETAB.C;
  12.     COMPILERS:    vanilla;
  13.     AUTHORS:    W. C. Colley III;
  14. */
  15.  
  16. /*
  17.              Tab Size Readjustment Program
  18.  
  19.            Copyright (c) 1987 William C. Colley, III
  20.  
  21. This program combines the functions of an ENTAB program and a DETAB program
  22. in the same program.  Combining the two allows a simple means of retabifying
  23. a program.  For example, let's say you edit a C program with your editor set
  24. for a tab increment of 4.  Now, you TYPE this file on the console and you find
  25. that it laps over the right edge of the screen because your terminal expands
  26. tabs with a tab increment of 8.     What you really would like to do is delete
  27. some of the tabs so that your program will TYPE just like it looked inside the
  28. editor.     The following command will do just that:
  29.  
  30.     RETAB -O4 -N8 oldfile newfile
  31.  
  32. In the above command line, the two file names must be in order, but the -
  33. options can be spread around anywhere.    In fact, the - options are optional.
  34. Their default values are set by a pair of #defines below.  The -O option
  35. specifies the tab increment that the old file was created with.     The -N option
  36. specifies the desired tab increment of the new file.
  37.  
  38. Note that or -N1 causes no entabification.  Thus, the following command will
  39. detabify a file:
  40.  
  41.     RETAB -O8 -N1 oldfile newfile
  42.  
  43. Also note that if the old file contains no tabs, there will be no
  44. detabification.     Thus, the following command will entabify a detabified file:
  45.  
  46.     RETAB -N8 oldfile newfile
  47.  
  48. Blanks and tabs in quoted strings are left alone.  The C conventions regarding
  49. character constants like '"' and character strings like "Here\'s a \"quote\"."
  50. are supported.
  51. */
  52.  
  53. #include <stdio.h>
  54.  
  55. /*  Uncomment the following #defines if you are using an AZTEC C compiler:  */
  56.  
  57. /*
  58. #define getc(x)        agetc(x)
  59. #define putc(x,y)   aputc(x,y)
  60. */
  61.  
  62. /*  User-adjustable default values:                        */
  63.  
  64. #define OLDTABS        4        /*    Default old tab increment.            */
  65. #define NEWTABS        8        /*    Default new tab increment.            */
  66.  
  67. #define NORMAL        0        /*    Normal state.                    */
  68. #define QUOTE        1        /*    Quoted string skip state.            */
  69. #define BLANK        2        /*    Blank parsing state.                */
  70.  
  71. int main(argc,argv)
  72. int argc;
  73. char **argv;
  74. {
  75.     int del, i, j, atoi();
  76.     FILE *old, *new;
  77.     static char *oldfile = NULL, *newfile = NULL;
  78.     static int err = 0, oldtabs = OLDTABS, newtabs = NEWTABS;
  79.     static int blnks = 0, col = 0, lit = 0, state = NORMAL;
  80.  
  81.     while (--argc) {
  82.     if (**++argv == '-') {
  83.         switch (i = *(*argv + 1)) {
  84.         case 'n':
  85.         case 'N':   if ((i = atoi(*argv + 2)) < 1) {
  86.                 printf("ERROR:  New tab increment < 1\n\n");
  87.                 err = !0;
  88.                 }
  89.                 else newtabs = i;
  90.                 break;
  91.  
  92.         case 'o':
  93.         case 'O':   if ((i = atoi(*argv + 2)) < 1) {
  94.                 printf("ERROR:  Old tab increment < 1\n\n");
  95.                 err = !0;
  96.                 }
  97.                 else oldtabs = i;
  98.                 break;
  99.  
  100.         default:    printf("ERROR:  Illegal option %s\n\n",*argv);
  101.                 err = !0;  break;
  102.         }
  103.     }
  104.     else if (!oldfile) oldfile = *argv;
  105.     else if (!newfile) newfile = *argv;
  106.     else {
  107.         printf("ERROR:  Extra filename %s\n\n",*argv);
  108.         err = !0;
  109.     }
  110.     }
  111.     if (!oldfile || !newfile) {
  112.     printf("Usage:\tRETAB { -Onn } { -Nnn } oldfile newfile\n\n");
  113.     err = !0;
  114.     }
  115.     else if (!(old = fopen(oldfile,"r"))) {
  116.     printf("ERROR:  Cannot find file %s\n\n",oldfile);
  117.     err = !0;
  118.     }
  119.     else {
  120.     if (!(new = fopen(newfile,"w"))) {
  121.         printf("ERROR:  Cannot create file %s\n\n",newfile);
  122.         err = !0;
  123.     }
  124.     else {
  125.         while ((i = getc(old)) != EOF) {
  126.         i &= 0177;
  127.         switch (state) {
  128.             case NORMAL:    switch (i) {
  129.                     case '\n':  col = 0;  putc('\n',new);
  130.                             break;
  131.  
  132.                     case '\t':  blnks = oldtabs -
  133.                             col % oldtabs;
  134.                             state = BLANK;  break;
  135.  
  136.                     case ' ':   blnks = 1;    state = BLANK;
  137.                             break;
  138.  
  139.                     case '\'':  del = '\'';     goto quote1;
  140.  
  141.                     case '"':   del = '"';
  142. quote1:                            if (!lit) state = QUOTE;
  143.  
  144.                     default:    ++col;  putc(i,new);
  145.                             break;
  146.                     }
  147.                     break;
  148.  
  149.             case QUOTE:        switch (i) {
  150.                     case '\n':  if (!lit) state = NORMAL;
  151.                             col = 0;  break;
  152.  
  153.                     case '\t':  col += newtabs -
  154.                             col % newtabs;
  155.                             break;
  156.  
  157.                     case '\'':
  158.                     case '"':   if (!lit && i == del)
  159.                             state = NORMAL;
  160.  
  161.                     default:    ++col;  break;
  162.                     }
  163.                     putc(i,new);  break;
  164.  
  165.             case BLANK:        switch (i) {
  166.                     case '\t':  blnks += oldtabs - (col +
  167.                             blnks) % oldtabs;
  168.                             break;
  169.  
  170.                     case ' ':   ++blnks;  break;
  171.  
  172.                     case '"':   del = '"';    goto quote2;
  173.  
  174.                     case '\'':  del = '\'';
  175. quote2:                            state = QUOTE;  goto entab;
  176.  
  177.                     default:    state = NORMAL;
  178. entab:                            if (blnks > 1 &&
  179.                             newtabs > 1)
  180.                             while ((j = newtabs -
  181.                                 col % newtabs)
  182.                                 <= blnks) {
  183.                                 col += j;
  184.                                 blnks -= j;
  185.                                 putc('\t',new);
  186.                             }
  187.                             for (; blnks; --blnks) {
  188.                             ++col;    putc(' ',new);
  189.                             }
  190.                             if (i == '\n') col = 0;
  191.                             else ++col;
  192.                             putc(i,new);  break;
  193.                     }
  194.                     break;
  195.         }
  196.         lit = !lit && i == '\\';
  197.         }
  198.         if (ferror(new) || fclose(new)) {
  199.         printf("ERROR:  Disk full\n\n");
  200.         err = !0;
  201.         }
  202.     }
  203.     fclose(old);
  204.     }
  205.     return err;
  206. }
  207.