(recheck): Handle a race condition (including <dev,inode>
[coreutils.git] / src / asa.c
blob411122c38c8399748f8ac05fa91bdaea5693b2c1
1 /*
2 TODO
3 mark translatable strings
4 add usage function
5 call parse_long_options
6 dcl, set program_name
7 do fclose/error checking
8 */
10 /* asa.c - interpret ASA carriage control characters
11 Copyright (C) 94, 1996 Thomas Koenig
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software Foundation,
25 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
27 /* System Headers */
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <errno.h>
34 /* Macros */
36 #define LINESIZE 135
37 #define NUMLINES 5
38 #define MAX(a,b) ((a) > (b) ? (a) : (b))
40 /* Structures and unions */
42 struct Str
44 char *chr;
45 size_t len;
47 typedef struct Str str;
49 /* File scope variables */
51 static str *line_buffer = (str *) 0;
52 static size_t line_num = 0;
53 static size_t linebuf_size;
55 /* Function declarations */
57 char *xmalloc ();
58 char *xrealloc ();
60 static size_t readline (FILE *fp, char **a);
61 static void add_line (str *);
62 static void flush (void);
63 static void copy_file (FILE *fp);
65 /* Local functions */
67 static void
68 form_feed ()
70 putchar ('\f');
73 static void
74 new_line ()
76 putchar ('\n');
79 static void
80 add_line (str *line)
82 if (line_num >= linebuf_size)
84 linebuf_size += NUMLINES;
85 line_buffer = (str *) xrealloc (line_buffer, linebuf_size * sizeof (str *));
87 line_buffer[line_num] = *line;
88 line_num++;
91 static void
92 flush ()
94 size_t i, j;
95 size_t max_len;
97 if (line_num == 0)
98 return;
99 if (line_num == 1)
101 printf ("%s\n", line_buffer[0].chr + 1);
102 line_num = 0;
103 return;
105 max_len = 0;
106 for (j = 0; j < line_num; j++)
107 max_len = MAX (max_len, line_buffer[j].len);
109 for (i = 1; i <= max_len; i++)
111 int printed = 0;
113 for (j = 0; j < line_num; j++)
115 if (line_buffer[j].len > i)
117 int ch = line_buffer[j].chr[i];
119 if (ch != ' ')
121 if (printed)
122 putchar ('\b');
123 putchar (ch);
124 printed = 1;
128 if (!printed)
129 putchar (' ');
131 for (j = 0; j < line_num; j++)
132 free (line_buffer[j].chr);
134 line_num = 0;
135 putchar ('\n');
138 static size_t
139 readline (FILE *fp, char **ret)
141 static char *buffer = (char *) 0;
142 char *ret_buff;
143 static int bufsize = LINESIZE;
144 int ch;
145 size_t len = 0;
146 int inc;
147 int i;
149 if (buffer == (char *) 0)
150 buffer = (char *) xmalloc (LINESIZE);
152 while (1)
154 ch = fgetc (fp);
155 if (ch == EOF)
156 break;
157 if (ch == '\t')
159 ch = ' ';
160 inc = 8 - (len % 8);
162 else
163 inc = 1;
165 if (len + inc > bufsize - 2)
167 bufsize += LINESIZE;
168 buffer = xrealloc (buffer, bufsize);
170 for (i = 0; i < inc; i++)
171 buffer[len + i] = ch;
172 len += inc;
173 if (ch == '\n')
174 break;
176 buffer[len] = '\0';
177 ret_buff = xmalloc (len + 1);
178 strcpy (ret_buff, buffer);
179 *ret = ret_buff;
180 return len;
183 static void
184 copy_file (FILE *fp)
186 str line;
187 static first_line = 1;
189 while ((line.len = readline (fp, &(line.chr))))
191 if (line.chr[line.len - 1] == '\n')
193 line.chr[line.len - 1] = '\0';
194 line.len--;
197 switch (line.chr[0])
199 case '+':
200 add_line (&line);
201 break;
203 case '0':
204 flush ();
205 new_line ();
206 add_line (&line);
207 break;
209 case '1':
210 flush ();
211 if (!first_line)
212 form_feed ();
213 add_line (&line);
214 break;
216 case ' ':
217 flush ();
218 add_line (&line);
219 break;
221 default:
222 flush ();
223 add_line (&line);
224 break;
226 first_line = 0;
230 /* Global functions */
233 main (int argc, char **argv)
235 int err;
236 line_buffer = (str *) xmalloc (NUMLINES * sizeof (str *));
237 linebuf_size = NUMLINES;
239 err = 0;
240 if (argc == 1)
241 copy_file (stdin);
242 else
244 FILE *fp;
245 char *fname;
247 while (--argc > 0)
249 fname = *++argv;
250 if ((fp = fopen (fname, "r")) == NULL)
252 err = 1;
253 error (0, errno, "%s", fname);
255 else
257 copy_file (fp);
258 fclose (fp);
262 flush ();
263 exit (err ? EXIT_FAILURE : EXIT_SUCCESS);