Header And Logo

PostgreSQL
| The world's most advanced open source database.

entab.c

Go to the documentation of this file.
00001 /*
00002 **      entab.c         - add tabs to a text file
00003 **      by Bruce Momjian ([email protected])
00004 **
00005 ** src/tools/entab/entab.c
00006 **
00007 **  version 1.3
00008 **
00009 **      tabsize = 4
00010 **
00011 */
00012 
00013 #include <stdio.h>
00014 #include <stdlib.h>
00015 #include <string.h>
00016 #include <stdarg.h>
00017 #include <unistd.h>
00018 
00019 #if defined(WIN32) || defined(__CYGWIN__)
00020 #define PG_BINARY_R "rb"
00021 #else
00022 #define PG_BINARY_R "r"
00023 #endif
00024 
00025 #define NUL             '\0'
00026 
00027 #ifndef TRUE
00028 #define TRUE    1
00029 #endif
00030 #ifndef FALSE
00031 #define FALSE   0
00032 #endif
00033 
00034 void        halt();
00035 
00036 extern char *optarg;
00037 extern int  optind;
00038 
00039 int
00040 main(int argc, char **argv)
00041 {
00042     int         tab_size = 8,
00043                 min_spaces = 2,
00044                 protect_quotes = FALSE,
00045                 del_tabs = FALSE,
00046                 clip_lines = FALSE,
00047                 prv_spaces,
00048                 col_in_tab,
00049                 escaped,
00050                 nxt_spaces;
00051     char        in_line[BUFSIZ],
00052                 out_line[BUFSIZ],
00053                *src,
00054                *dst,
00055                 quote_char,
00056                *cp;
00057     int         ch;
00058     FILE       *in_file;
00059 
00060     if ((cp = strrchr(argv[0], '/')) != NULL)
00061         ++cp;
00062     else
00063         cp = argv[0];
00064     if (strcmp(cp, "detab") == 0)
00065         del_tabs = 1;
00066 
00067     while ((ch = getopt(argc, argv, "cdhqs:t:")) != -1)
00068         switch (ch)
00069         {
00070             case 'c':
00071                 clip_lines = TRUE;
00072                 break;
00073             case 'd':
00074                 del_tabs = TRUE;
00075                 break;
00076             case 'q':
00077                 protect_quotes = TRUE;
00078                 break;
00079             case 's':
00080                 min_spaces = atoi(optarg);
00081                 break;
00082             case 't':
00083                 tab_size = atoi(optarg);
00084                 break;
00085             case 'h':
00086             case '?':
00087                 halt("USAGE: %s [ -cdqst ] [file ...]\n\
00088     -c (clip trailing whitespace)\n\
00089     -d (delete tabs)\n\
00090     -q (protect quotes)\n\
00091     -s minimum_spaces\n\
00092     -t tab_width\n",
00093                      cp);
00094         }
00095 
00096     argv += optind;
00097     argc -= optind;
00098 
00099     do
00100     {
00101         if (argc < 1)
00102             in_file = stdin;
00103         else
00104         {
00105             if ((in_file = fopen(*argv, PG_BINARY_R)) == NULL)
00106                 halt("PERROR:  Cannot open file %s\n", argv[0]);
00107             argv++;
00108         }
00109 
00110         escaped = FALSE;
00111 
00112         while (fgets(in_line, sizeof(in_line), in_file) != NULL)
00113         {
00114             col_in_tab = 0;
00115             prv_spaces = 0;
00116             src = in_line;      /* points to current processed char */
00117             dst = out_line;     /* points to next unallocated char */
00118             if (escaped == FALSE)
00119                 quote_char = ' ';
00120             escaped = FALSE;
00121 
00122             while (*src != NUL)
00123             {
00124                 col_in_tab++;
00125                 if (quote_char == ' ' && (*src == ' ' || *src == '\t'))
00126                 {
00127                     if (*src == '\t')
00128                     {
00129                         prv_spaces += tab_size - col_in_tab + 1;
00130                         col_in_tab = tab_size;
00131                     }
00132                     else
00133                         prv_spaces++;
00134 
00135                     if (col_in_tab == tab_size)
00136                     {
00137                         /*
00138                          * Is the next character going to be a tab? Needed to
00139                          * do tab replacement in current spot if next char is
00140                          * going to be a tab, ignoring min_spaces
00141                          */
00142                         nxt_spaces = 0;
00143                         while (1)
00144                         {
00145                             if (*(src + nxt_spaces + 1) == NUL ||
00146                                 (*(src + nxt_spaces + 1) != ' ' &&
00147                                  *(src + nxt_spaces + 1) != '\t'))
00148                                 break;
00149                             if (*(src + nxt_spaces + 1) == ' ')
00150                                 ++nxt_spaces;
00151                             if (*(src + nxt_spaces + 1) == '\t' ||
00152                                 nxt_spaces == tab_size)
00153                             {
00154                                 nxt_spaces = tab_size;
00155                                 break;
00156                             }
00157                         }
00158                         if ((prv_spaces >= min_spaces ||
00159                              nxt_spaces == tab_size) &&
00160                             del_tabs == FALSE)
00161                         {
00162                             *(dst++) = '\t';
00163                             prv_spaces = 0;
00164                         }
00165                         else
00166                         {
00167                             for (; prv_spaces > 0; prv_spaces--)
00168                                 *(dst++) = ' ';
00169                         }
00170                     }
00171                 }
00172                 else
00173                 {
00174                     for (; prv_spaces > 0; prv_spaces--)
00175                         *(dst++) = ' ';
00176                     if (*src == '\t')   /* only when in quote */
00177                         col_in_tab = 0;
00178                     if (*src == '\b')
00179                         col_in_tab -= 2;
00180                     if (escaped == FALSE && protect_quotes == TRUE)
00181                     {
00182                         if (*src == '\\')
00183                             escaped = TRUE;
00184                         if (*src == '"' || *src == '\'')
00185                         {
00186                             if (quote_char == ' ')
00187                                 quote_char = *src;
00188                             else if (*src == quote_char)
00189                                 quote_char = ' ';
00190                         }
00191                     }
00192                     else if (*src != '\r' && *src != '\n')
00193                         escaped = FALSE;
00194 
00195                     if ((*src == '\r' || *src == '\n') &&
00196                         quote_char == ' ' &&
00197                         clip_lines == TRUE &&
00198                         escaped == FALSE)
00199                     {
00200                         while (dst > out_line &&
00201                                (*(dst - 1) == ' ' || *(dst - 1) == '\t'))
00202                             dst--;
00203                         prv_spaces = 0;
00204                     }
00205                     *(dst++) = *src;
00206                 }
00207                 col_in_tab %= tab_size;
00208                 ++src;
00209             }
00210             /* for cases where the last line of file has no newline */
00211             if (clip_lines == TRUE && escaped == FALSE)
00212             {
00213                 while (dst > out_line &&
00214                        (*(dst - 1) == ' ' || *(dst - 1) == '\t'))
00215                     dst--;
00216                 prv_spaces = 0;
00217             }
00218             for (; prv_spaces > 0; prv_spaces--)
00219                 *(dst++) = ' ';
00220             *dst = NUL;
00221             if (fputs(out_line, stdout) == EOF)
00222                 halt("PERROR:  Error writing output.\n");
00223         }
00224     } while (--argc > 0);
00225     return 0;
00226 }