summaryrefslogtreecommitdiff
path: root/src/asa.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>1996-04-29 01:43:52 +0000
committerJim Meyering <jim@meyering.net>1996-04-29 01:43:52 +0000
commit346b0368cf4a14587881e37ae3d8295417922eaf (patch)
treecf376fd25dd2f01e676616ce6933911e176ee044 /src/asa.c
parent175585876f4814b69cfdec9136b1431cd0a65d59 (diff)
downloadcoreutils-346b0368cf4a14587881e37ae3d8295417922eaf.tar.xz
.
Diffstat (limited to 'src/asa.c')
-rw-r--r--src/asa.c277
1 files changed, 277 insertions, 0 deletions
diff --git a/src/asa.c b/src/asa.c
new file mode 100644
index 000000000..64260f88f
--- /dev/null
+++ b/src/asa.c
@@ -0,0 +1,277 @@
+/*
+ * asa.c - interpret ASA carriage control characters
+ * Copyright (C) 1994 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define _POSIX_SOURCE 1
+
+/* 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 */
+
+typedef struct
+{
+ char *chr;
+ size_t len;
+} str;
+
+/* File scope variables */
+
+static char rcsid[] = "$Id: asa.c,v 1.1 1996/04/29 01:43:52 meyering Exp $";
+static str *line_buffer = (str *) 0;
+static size_t line_num = 0;
+static size_t linebuf_size;
+
+/* Function declarations */
+
+static void *mymalloc(size_t);
+static size_t readline(FILE *fp, char **a);
+static void form_feed(void);
+static void add_line(str);
+static void flush(void);
+static void copy_file(FILE *fp);
+
+/* Local functions */
+
+static void*
+mymalloc(size_t n)
+{
+ void *p;
+ if ((p=malloc(n)))
+ return p;
+ else
+ {
+ fprintf(stderr,"Virtual memory exhausted\n");
+ exit(EXIT_FAILURE);
+ }
+}
+
+static void*
+myrealloc(void *p, size_t n)
+{
+ if ((p=realloc(p,n)))
+ return p;
+ else
+ {
+ fprintf(stderr,"Virtual memory exhausted\n");
+ exit(EXIT_FAILURE);
+ }
+}
+static void
+form_feed()
+{
+ putchar('\f');
+}
+
+static void
+new_line()
+{
+ putchar('\n');
+}
+
+static void
+add_line(str a)
+{
+ if (line_num >= linebuf_size)
+ {
+ linebuf_size += NUMLINES;
+ line_buffer = myrealloc(line_buffer, linebuf_size*sizeof(str *));
+ }
+ line_buffer[line_num]=a;
+ 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 *) mymalloc(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 = myrealloc(buffer, bufsize);
+ }
+ for (i=0; i<inc; i++)
+ buffer[len+i] = ch;
+ len += inc;
+ if (ch == '\n')
+ break;
+ }
+ buffer[len]='\0';
+ ret_buff = mymalloc(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)
+{
+
+ line_buffer = (str *) mymalloc(NUMLINES*sizeof(str*));
+ linebuf_size = NUMLINES;
+
+ if (argc == 1)
+ copy_file(stdin);
+ else
+ {
+ FILE *fp;
+ char *fname;
+
+ while(--argc > 0)
+ {
+ fname = *++argv;
+ if ((fp = fopen(fname,"r")) == NULL)
+ {
+ fprintf(stderr,"Cannot open %s: %s\n",fname,strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ copy_file(fp);
+ fclose(fp);
+ }
+ }
+ flush();
+ exit(EXIT_SUCCESS);
+}