Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
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;
00117 dst = out_line;
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
00139
00140
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')
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
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 }