~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

TidyLib
tidy/console/tab2space.c

Version: ~ [ 1.0 ] ~

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 
  5 #include "platform.h"
  6 
  7 #define true       1
  8 #define false      0
  9 #define TABSIZE    4
 10 
 11 #define DOS_CRLF   0
 12 #define UNIX_LF    1
 13 #define MAC_CR     2
 14 
 15 typedef struct
 16 {
 17     Bool pushed;
 18     int tabs;
 19     int curcol;
 20     int lastcol;
 21     int maxcol;
 22     int curline;
 23     int pushed_char;
 24     uint size;
 25     uint length;
 26     char *buf;
 27     FILE *fp;
 28 } Stream;
 29 
 30 static int tabsize = TABSIZE;
 31 static int endline = DOS_CRLF;
 32 static Bool tabs = false;
 33 
 34 /*
 35  Memory allocation functions vary from one environment to
 36  the next, and experience shows that wrapping the local
 37  mechanisms up provides for greater flexibility and allows
 38  out of memory conditions to be detected in one place.
 39 */
 40 void *MemAlloc(size_t size)
 41 {
 42     void *p;
 43 
 44     p = malloc(size);
 45 
 46     if (!p)
 47     {
 48         fprintf(stderr, "***** Out of memory! *****\n");
 49         exit(1);
 50     }
 51 
 52     return p;
 53 }
 54 
 55 void *MemRealloc(void *old, size_t size)
 56 {
 57     void *p;
 58 
 59     p = realloc(old, size);
 60 
 61     if (!p)
 62     {
 63         fprintf(stderr, "***** Out of memory! *****\n");
 64         return NULL;
 65     }
 66 
 67     return p;
 68 }
 69 
 70 void MemFree(void *p)
 71 {
 72     free(p);
 73     p = NULL;
 74 }
 75 
 76 static Stream *NewStream(FILE *fp)
 77 {
 78     Stream *in;
 79 
 80     in = (Stream *)MemAlloc(sizeof(Stream));
 81 
 82     memset(in, 0, sizeof(Stream));
 83     in->fp = fp;
 84     return in;
 85 }
 86 
 87 static void FreeStream(Stream *in)
 88 {
 89     if (in->buf)
 90         MemFree(in->buf);
 91 
 92     MemFree(in);
 93 }
 94 
 95 static void AddByte(Stream *in, uint c)
 96 {
 97     if (in->size + 1 >= in->length)
 98     {
 99         while (in->size + 1 >= in->length)
100         {
101             if (in->length == 0)
102                 in->length = 8192;
103             else
104                 in->length = in->length * 2;
105         }
106 
107         in->buf = (char *)MemRealloc(in->buf, in->length*sizeof(char));
108     }
109 
110     in->buf[in->size++] = (char)c;
111     in->buf[in->size] = '\0';  /* debug */
112 }
113 
114 
115 
116 /*
117   Read a character from a stream, keeping track
118   of lines, columns etc. This is used for parsing
119   markup and plain text etc. A single level
120   pushback is allowed with UngetChar(c, in).
121   Returns EndOfStream if there's nothing more to read.
122 */
123 static int ReadChar(Stream *in)
124 {
125     int c;
126 
127     if (in->pushed)
128     {
129         in->pushed = false;
130 
131         if (in->pushed_char == '\n')
132             in->curline--;
133 
134         return in->pushed_char;
135     }
136 
137     in->lastcol = in->curcol;
138 
139     /* expanding tab ? */
140     if (in->tabs > 0)
141     {
142         in->curcol++;
143         in->tabs--;
144         return ' ';
145     }
146     
147     /* Else go on with normal buffer: */
148     for (;;)
149     {
150         c = getc(in->fp);
151 
152         /* end of file? */
153         if (c == EOF)
154             break;
155 
156         /* coerce \r\n  and isolated \r as equivalent to \n : */
157         if (c == '\r')
158         {
159             c = getc(in->fp);
160 
161             if (c != '\n')
162                 ungetc(c, in->fp);
163 
164             c = '\n';
165         }
166 
167         if (c == '\n')
168         {
169             if (in->maxcol < in->curcol)
170                 in->maxcol = in->curcol;
171 
172             in->curcol = 1;
173             in->curline++;
174             break;
175         }
176 
177         if (c == '\t')
178         {
179             if (tabs)
180               in->curcol += tabsize - ((in->curcol - 1) % tabsize);
181             else /* expand to spaces */
182             {
183                 in->tabs = tabsize - ((in->curcol - 1) % tabsize) - 1;
184                 in->curcol++;
185                 c = ' ';
186             }
187 
188             break;
189         }
190 
191         if (c == '\033')
192             break;
193 
194         /* strip control characters including '\r' */
195 
196         if (0 < c && c < 32)
197             continue;
198 
199         in->curcol++;
200         break;
201     }
202 
203     return c;
204 }
205 
206 static Stream *ReadFile(FILE *fin)
207 {
208     int c;
209     Stream *in  = NewStream(fin);
210 
211     while ((c = ReadChar(in)) >= 0)
212         AddByte(in, (uint)c);
213 
214     return in;
215 }
216 
217 static void WriteFile(Stream *in, FILE *fout)
218 {
219     int i, c;
220     char *p;
221 
222     i = in->size;
223     p = in->buf;
224 
225     while (i--)
226     {
227         c = *p++;
228 
229         if (c == '\n')
230         {
231             if (endline == DOS_CRLF)
232             {
233                 putc('\r', fout);
234                 putc('\n', fout);
235             }
236             else if (endline == UNIX_LF)
237                 putc('\n', fout);
238             else if (endline == MAC_CR)
239                 putc('\r', fout);
240 
241             continue;
242         }
243 
244         putc(c, fout);
245     }
246 }
247 
248 static void HelpText(FILE *errout, char *prog)
249 {
250     fprintf(errout, "%s: [options] [infile [outfile]] ...\n", prog);
251     fprintf(errout, "Utility to expand tabs and ensure consistent line endings\n");
252     fprintf(errout, "options for tab2space vers: 6th February 2003\n");
253     fprintf(errout, "  -help or -h     display this help message\n");
254     fprintf(errout, "  -dos  or -crlf  set line ends to CRLF (PC-DOS/Windows - default)\n");
255     fprintf(errout, "  -mac  or -cr    set line ends to CR (classic Mac OS)\n");
256     fprintf(errout, "  -unix or -lf    set line ends to LF (Unix)\n");
257     fprintf(errout, "  -tabs           preserve tabs, e.g. for Makefile\n");
258     fprintf(errout, "  -t<n>           set tabs to <n> (default is 4) spaces\n");
259     fprintf(errout, "\nNote this utility doesn't map spaces to tabs!\n");
260 }
261 
262 int main(int argc, char **argv)
263 {
264     char const *infile, *outfile;
265     char *prog;
266     FILE *fin, *fout;
267     Stream *in = NULL;
268 
269     prog = argv[0];
270 
271     while (argc > 0)
272     {
273         if (argc > 1 && argv[1][0] == '-')
274         {
275             if (strcmp(argv[1], "-help") == 0 || argv[1][1] == 'h')
276             {
277                 HelpText(stdout, prog);
278                 return 1;
279             }
280 
281             if (strcmp(argv[1], "-dos") == 0 ||
282                 strcmp(argv[1], "-crlf") == 0)
283                  endline = DOS_CRLF;
284 
285             else if (strcmp(argv[1], "-mac") == 0 ||
286                 strcmp(argv[1], "-cr") == 0)
287                 endline = MAC_CR;
288 
289             else if (strcmp(argv[1], "-unix") == 0 ||
290                 strcmp(argv[1], "-lf") == 0)
291                 endline = UNIX_LF;
292 
293             else if (strcmp(argv[1], "-tabs") == 0)
294                 tabs = true;
295 
296             else if (strncmp(argv[1], "-t", 2) == 0)
297                 sscanf(argv[1]+2, "%d", &tabsize);
298 
299             --argc;
300             ++argv;
301             continue;
302         }
303 
304         if (argc > 1)
305         {
306             infile = argv[1];
307             fin = fopen(infile, "rb");
308         }
309         else
310         {
311             infile = "stdin";
312             fin = stdin;
313         }
314 
315         if (argc > 2)
316         {
317             outfile = argv[2];
318             fout = NULL;
319             --argc;
320             ++argv;
321         }
322         else
323         {
324             outfile = "stdout";
325             fout = stdout;
326         }
327 
328         if (fin)
329         {
330             in = ReadFile(fin);
331 
332             if (fin != stdin)
333                 fclose(fin);
334             
335             if (fout != stdout)
336                fout = fopen(outfile, "wb");
337             
338             if (fout)
339             {
340                WriteFile(in, fout);
341                 
342                if (fout != stdout)
343                   fclose(fout);
344             }
345             else
346                 fprintf(stderr, "%s - can't open \"%s\" for writing\n", prog, outfile);
347 
348             FreeStream(in);
349         }
350         else
351             fprintf(stderr, "%s - can't open \"%s\" for reading\n", prog, infile);
352 
353         --argc;
354         ++argv;
355         
356         if (argc <= 1)
357             break;
358     }
359 
360     return 0;
361 }
362 
363 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.