1
0
mirror of git://git.sv.gnu.org/coreutils.git synced 2026-03-08 22:14:03 +02:00
Files
coreutils/src/asa.c

265 lines
4.5 KiB
C

/*
TODO
mark translatable strings
add usage function
call parse_long_options
dcl, set program_name
do fclose/error checking
*/
/* asa.c - interpret ASA carriage control characters
Copyright (C) 94, 1996 Thomas Koenig
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* System Headers */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
/* Macros */
#define LINESIZE 135
#define NUMLINES 5
#define MAX(a,b) ((a) > (b) ? (a) : (b))
/* Structures and unions */
struct Str
{
char *chr;
size_t len;
};
typedef struct Str str;
/* File scope variables */
static str *line_buffer = (str *) 0;
static size_t line_num = 0;
static size_t linebuf_size;
/* Function declarations */
char *xmalloc ();
char *xrealloc ();
static size_t readline (FILE *fp, char **a);
static void add_line (str *);
static void flush (void);
static void copy_file (FILE *fp);
/* Local functions */
static void
form_feed ()
{
putchar ('\f');
}
static void
new_line ()
{
putchar ('\n');
}
static void
add_line (str *line)
{
if (line_num >= linebuf_size)
{
linebuf_size += NUMLINES;
line_buffer = (str *) xrealloc (line_buffer, linebuf_size * sizeof (str *));
}
line_buffer[line_num] = *line;
line_num++;
}
static void
flush ()
{
size_t i, j;
size_t max_len;
if (line_num == 0)
return;
if (line_num == 1)
{
printf ("%s\n", line_buffer[0].chr + 1);
line_num = 0;
return;
}
max_len = 0;
for (j = 0; j < line_num; j++)
max_len = MAX (max_len, line_buffer[j].len);
for (i = 1; i <= max_len; i++)
{
int printed = 0;
for (j = 0; j < line_num; j++)
{
if (line_buffer[j].len > i)
{
int ch = line_buffer[j].chr[i];
if (ch != ' ')
{
if (printed)
putchar ('\b');
putchar (ch);
printed = 1;
}
}
}
if (!printed)
putchar (' ');
}
for (j = 0; j < line_num; j++)
free (line_buffer[j].chr);
line_num = 0;
putchar ('\n');
}
static size_t
readline (FILE *fp, char **ret)
{
static char *buffer = (char *) 0;
char *ret_buff;
static int bufsize = LINESIZE;
int ch;
size_t len = 0;
int inc;
int i;
if (buffer == (char *) 0)
buffer = (char *) xmalloc (LINESIZE);
while (1)
{
ch = fgetc (fp);
if (ch == EOF)
break;
if (ch == '\t')
{
ch = ' ';
inc = 8 - (len % 8);
}
else
inc = 1;
if (len + inc > bufsize - 2)
{
bufsize += LINESIZE;
buffer = xrealloc (buffer, bufsize);
}
for (i = 0; i < inc; i++)
buffer[len + i] = ch;
len += inc;
if (ch == '\n')
break;
}
buffer[len] = '\0';
ret_buff = xmalloc (len + 1);
strcpy (ret_buff, buffer);
*ret = ret_buff;
return len;
}
static void
copy_file (FILE *fp)
{
str line;
static first_line = 1;
while ((line.len = readline (fp, &(line.chr))))
{
if (line.chr[line.len - 1] == '\n')
{
line.chr[line.len - 1] = '\0';
line.len--;
}
switch (line.chr[0])
{
case '+':
add_line (&line);
break;
case '0':
flush ();
new_line ();
add_line (&line);
break;
case '1':
flush ();
if (!first_line)
form_feed ();
add_line (&line);
break;
case ' ':
flush ();
add_line (&line);
break;
default:
flush ();
add_line (&line);
break;
}
first_line = 0;
}
}
/* Global functions */
int
main (int argc, char **argv)
{
int err;
line_buffer = (str *) xmalloc (NUMLINES * sizeof (str *));
linebuf_size = NUMLINES;
err = 0;
if (argc == 1)
copy_file (stdin);
else
{
FILE *fp;
char *fname;
while (--argc > 0)
{
fname = *++argv;
if ((fp = fopen (fname, "r")) == NULL)
{
err = 1;
error (0, errno, "%s", fname);
}
else
{
copy_file (fp);
fclose (fp);
}
}
}
flush ();
exit (err ? EXIT_FAILURE : EXIT_SUCCESS);
}