1/*	$OpenBSD: ppt.c,v 1.17 2016/03/07 12:07:56 mestre Exp $	*/
2/*	$NetBSD: ppt.c,v 1.4 1995/03/23 08:35:40 cgd Exp $	*/
3
4/*
5 * Copyright (c) 1988, 1993
6 *	The Regents of the University of California.  All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#include <err.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <unistd.h>
38#include <vis.h>
39
40
41#define	EDGE	"___________"
42
43__dead void	usage(void);
44void	putppt(int);
45int	getppt(const char *buf);
46
47void
48usage(void)
49{
50	extern char *__progname;
51	fprintf(stderr, "usage: %s [string ...]\n", __progname);
52	fprintf(stderr, "usage: %s -d [-b]\n", __progname);
53	exit(1);
54}
55
56int
57main(int argc, char **argv)
58{
59	char *p, buf[132];
60	int c, start, seenl, dflag, bflag;
61
62	if (pledge("stdio", NULL) == -1)
63		err(1, "pledge");
64
65	dflag = bflag = 0;
66	while ((c = getopt(argc, argv, "bdh")) != -1)
67		switch(c) {
68		case 'd':
69			dflag = 1;
70			break;
71		case 'b':
72			bflag = 1;
73			break;
74		case 'h':
75		default:
76			usage();
77		}
78	if (bflag && !dflag)
79		usage();
80	argc -= optind;
81	argv += optind;
82
83	if (dflag) {
84		if (argc > 0)
85			usage();
86
87		seenl = start = 0;
88		while (fgets(buf, sizeof(buf), stdin) != NULL) {
89			c = getppt(buf);
90			if (c == -2)
91				continue;
92			if (c == -1) {
93				if (start)
94					/* lost sync */
95					putchar('x');
96				continue;
97			}
98			start = 1;
99			if (bflag)
100				putchar(c);
101			else {
102				char vbuf[5];
103				vis(vbuf, c, VIS_NOSLASH, 0);
104				fputs(vbuf, stdout);
105			}
106			seenl = (c == '\n');
107		}
108		if (!feof(stdin))
109			err(1, "fgets");
110		if (!seenl && !bflag)
111			putchar('\n');
112	} else {
113		(void) puts(EDGE);
114		if (argc > 0)
115			while ((p = *argv++)) {
116				for (; *p; ++p)
117					putppt((int)*p);
118				if (*argv)
119					putppt((int)' ');
120			}
121		else while ((c = getchar()) != EOF)
122			putppt(c);
123		(void) puts(EDGE);
124	}
125	return 0;
126}
127
128void
129putppt(int c)
130{
131	int i;
132
133	(void) putchar('|');
134	for (i = 7; i >= 0; i--) {
135		if (i == 2)
136			(void) putchar('.');	/* feed hole */
137		if ((c&(1<<i)) != 0)
138			(void) putchar('o');
139		else
140			(void) putchar(' ');
141	}
142	(void) putchar('|');
143	(void) putchar('\n');
144}
145
146int
147getppt(const char *buf)
148{
149	int c;
150
151	/* Demand left-aligned paper tape, but allow comments to the right */
152	if (strncmp(buf, EDGE, strlen(EDGE)) == 0)
153	    return (-2);
154	if (strlen(buf) < 12 || buf[0] != '|' || buf[10] != '|' ||
155	    buf[6] != '.' || strspn(buf, "| o.") < 11)
156		return (-1);
157
158	c = 0;
159	if (buf[1] != ' ')
160		c |= 0200;
161	if (buf[2] != ' ')
162		c |= 0100;
163	if (buf[3] != ' ')
164		c |= 0040;
165	if (buf[4] != ' ')
166		c |= 0020;
167	if (buf[5] != ' ')
168		c |= 0010;
169	if (buf[7] != ' ')
170		c |= 0004;
171	if (buf[8] != ' ')
172		c |= 0002;
173	if (buf[9] != ' ')
174		c |= 0001;
175
176	return (c);
177}
178