Fix obsolete comment regarding FSM truncation.
[PostgreSQL.git] / src / tools / entab / entab.c
blobd377b3a919587a45c854831cde41cb5f1e379f04
1 /*
2 ** entab.c - add tabs to a text file
3 ** by Bruce Momjian (root@candle.pha.pa.us)
4 **
5 ** $PostgreSQL$
6 **
7 ** version 1.3
8 **
9 ** tabsize = 4
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <stdarg.h>
18 #if defined(WIN32) || defined(__CYGWIN__)
19 #define PG_BINARY_R "rb"
20 #else
21 #define PG_BINARY_R "r"
22 #endif
24 #define NUL '\0'
26 #ifndef TRUE
27 #define TRUE 1
28 #endif
29 #ifndef FALSE
30 #define FALSE 0
31 #endif
33 void halt();
35 extern char *optarg;
36 extern int optind;
38 int
39 main(int argc, char **argv)
41 int tab_size = 8,
42 min_spaces = 2,
43 protect_quotes = FALSE,
44 del_tabs = FALSE,
45 clip_lines = FALSE,
46 prv_spaces,
47 col_in_tab,
48 escaped,
49 nxt_spaces;
50 char in_line[BUFSIZ],
51 out_line[BUFSIZ],
52 *src,
53 *dst,
54 quote_char,
55 *cp;
56 int ch;
57 FILE *in_file;
59 if ((cp = strrchr(argv[0], '/')) != NULL)
60 ++cp;
61 else
62 cp = argv[0];
63 if (strcmp(cp, "detab") == 0)
64 del_tabs = 1;
66 while ((ch = getopt(argc, argv, "cdhqs:t:")) != -1)
67 switch (ch)
69 case 'c':
70 clip_lines = TRUE;
71 break;
72 case 'd':
73 del_tabs = TRUE;
74 break;
75 case 'q':
76 protect_quotes = TRUE;
77 break;
78 case 's':
79 min_spaces = atoi(optarg);
80 break;
81 case 't':
82 tab_size = atoi(optarg);
83 break;
84 case 'h':
85 case '?':
86 halt("USAGE: %s [ -cdqst ] [file ...]\n\
87 -c (clip trailing whitespace)\n\
88 -d (delete tabs)\n\
89 -q (protect quotes)\n\
90 -s minimum_spaces\n\
91 -t tab_width\n",
92 cp);
95 argv += optind;
96 argc -= optind;
100 if (argc < 1)
101 in_file = stdin;
102 else
104 if ((in_file = fopen(*argv, PG_BINARY_R)) == NULL)
105 halt("PERROR: Cannot open file %s\n", argv[0]);
106 argv++;
109 escaped = FALSE;
111 while (fgets(in_line, sizeof(in_line), in_file) != NULL)
113 col_in_tab = 0;
114 prv_spaces = 0;
115 src = in_line; /* points to current processed char */
116 dst = out_line; /* points to next unallocated char */
117 if (escaped == FALSE)
118 quote_char = ' ';
119 escaped = FALSE;
121 while (*src != NUL)
123 col_in_tab++;
124 if (quote_char == ' ' && (*src == ' ' || *src == '\t'))
126 if (*src == '\t')
128 prv_spaces += tab_size - col_in_tab + 1;
129 col_in_tab = tab_size;
131 else
132 prv_spaces++;
134 if (col_in_tab == tab_size)
137 * Is the next character going to be a tab? Needed to
138 * do tab replacement in current spot if next char is
139 * going to be a tab, ignoring min_spaces
141 nxt_spaces = 0;
142 while (1)
144 if (*(src + nxt_spaces + 1) == NUL ||
145 (*(src + nxt_spaces + 1) != ' ' &&
146 *(src + nxt_spaces + 1) != '\t'))
147 break;
148 if (*(src + nxt_spaces + 1) == ' ')
149 ++nxt_spaces;
150 if (*(src + nxt_spaces + 1) == '\t' ||
151 nxt_spaces == tab_size)
153 nxt_spaces = tab_size;
154 break;
157 if ((prv_spaces >= min_spaces ||
158 nxt_spaces == tab_size) &&
159 del_tabs == FALSE)
161 *(dst++) = '\t';
162 prv_spaces = 0;
164 else
166 for (; prv_spaces > 0; prv_spaces--)
167 *(dst++) = ' ';
171 else
173 for (; prv_spaces > 0; prv_spaces--)
174 *(dst++) = ' ';
175 if (*src == '\t') /* only when in quote */
176 col_in_tab = 0;
177 if (*src == '\b')
178 col_in_tab -= 2;
179 if (escaped == FALSE && protect_quotes == TRUE)
181 if (*src == '\\')
182 escaped = TRUE;
183 if (*src == '"' || *src == '\'')
184 if (quote_char == ' ')
185 quote_char = *src;
186 else if (*src == quote_char)
187 quote_char = ' ';
189 else if (*src != '\r' && *src != '\n')
190 escaped = FALSE;
192 if ((*src == '\r' || *src == '\n') &&
193 quote_char == ' ' &&
194 clip_lines == TRUE &&
195 escaped == FALSE)
197 while (dst > out_line &&
198 (*(dst - 1) == ' ' || *(dst - 1) == '\t'))
199 dst--;
200 prv_spaces = 0;
202 *(dst++) = *src;
204 col_in_tab %= tab_size;
205 ++src;
207 /* for cases where the last line of file has no newline */
208 if (clip_lines == TRUE && escaped == FALSE)
210 while (dst > out_line &&
211 (*(dst - 1) == ' ' || *(dst - 1) == '\t'))
212 dst--;
213 prv_spaces = 0;
215 for (; prv_spaces > 0; prv_spaces--)
216 *(dst++) = ' ';
217 *dst = NUL;
218 if (fputs(out_line, stdout) == EOF)
219 halt("PERROR: Error writing output.\n");
221 } while (--argc > 0);
222 return 0;