~ubuntu-branches/ubuntu/precise/tidy/precise-updates

« back to all changes in this revision

Viewing changes to console/tab2space.c

  • Committer: Bazaar Package Importer
  • Author(s): Jason Thomas
  • Date: 2005-04-20 11:22:49 UTC
  • mto: (3.1.1 lenny)
  • mto: This revision was merged to the branch mainline in revision 2.
  • Revision ID: james.westby@ubuntu.com-20050420112249-epdnkgi03ubep83z
Tags: upstream-20050415
ImportĀ upstreamĀ versionĀ 20050415

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
#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