~ubuntu-branches/ubuntu/gutsy/tidy/gutsy

« back to all changes in this revision

Viewing changes to src/tab2space.c

  • Committer: Bazaar Package Importer
  • Author(s): Jason Thomas
  • Date: 2005-04-20 11:22:49 UTC
  • mfrom: (0.2.1 upstream) (1.1.2 hoary)
  • Revision ID: james.westby@ubuntu.com-20050420112249-mygnr5vcrutwsen3
Tags: 20050415-1
New upstream release 

Show diffs side-by-side

added added

removed removed

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