xref: /dragonfly/usr.bin/dc/dc.c (revision a977bf87)
1f2d37758SMatthew Dillon /*
2*a977bf87SJoris Giovannangeli  * $OpenBSD: dc.c,v 1.11 2009/10/27 23:59:37 deraadt Exp $
3abcef8f0SSascha Wildner  * $DragonFly: src/usr.bin/dc/dc.c,v 1.2 2005/04/21 18:50:50 swildner Exp $
4f2d37758SMatthew Dillon  */
5f2d37758SMatthew Dillon 
6f2d37758SMatthew Dillon /*
7f2d37758SMatthew Dillon  * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
8f2d37758SMatthew Dillon  *
9f2d37758SMatthew Dillon  * Permission to use, copy, modify, and distribute this software for any
10f2d37758SMatthew Dillon  * purpose with or without fee is hereby granted, provided that the above
11f2d37758SMatthew Dillon  * copyright notice and this permission notice appear in all copies.
12f2d37758SMatthew Dillon  *
13f2d37758SMatthew Dillon  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14f2d37758SMatthew Dillon  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15f2d37758SMatthew Dillon  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16f2d37758SMatthew Dillon  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17f2d37758SMatthew Dillon  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18f2d37758SMatthew Dillon  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19f2d37758SMatthew Dillon  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20f2d37758SMatthew Dillon  */
21f2d37758SMatthew Dillon 
22*a977bf87SJoris Giovannangeli #include <sys/stat.h>
23f2d37758SMatthew Dillon #include <err.h>
24*a977bf87SJoris Giovannangeli #include <errno.h>
25f2d37758SMatthew Dillon #include <stdlib.h>
26abcef8f0SSascha Wildner #include <string.h>
27f2d37758SMatthew Dillon #include <unistd.h>
28f2d37758SMatthew Dillon 
29f2d37758SMatthew Dillon #include "extern.h"
30f2d37758SMatthew Dillon 
31abcef8f0SSascha Wildner static __dead2 void    	usage(void);
32f2d37758SMatthew Dillon 
33f2d37758SMatthew Dillon extern char		*__progname;
34f2d37758SMatthew Dillon 
35abcef8f0SSascha Wildner static __dead2 void
usage(void)36f2d37758SMatthew Dillon usage(void)
37f2d37758SMatthew Dillon {
38abcef8f0SSascha Wildner 	fprintf(stderr, "usage: %s [-x] [-e expr] [file]\n", __progname);
39f2d37758SMatthew Dillon 	exit(1);
40f2d37758SMatthew Dillon }
41f2d37758SMatthew Dillon 
42f2d37758SMatthew Dillon int
main(int argc,char * argv[])43f2d37758SMatthew Dillon main(int argc, char *argv[])
44f2d37758SMatthew Dillon {
45f2d37758SMatthew Dillon 	int		ch;
46f2d37758SMatthew Dillon 	bool		extended_regs = false;
47f2d37758SMatthew Dillon 	FILE		*file;
48f2d37758SMatthew Dillon 	struct source	src;
49abcef8f0SSascha Wildner 	char		*buf, *p;
50*a977bf87SJoris Giovannangeli 	struct stat	st;
51f2d37758SMatthew Dillon 
52abcef8f0SSascha Wildner 	if ((buf = strdup("")) == NULL)
53abcef8f0SSascha Wildner 		err(1, NULL);
54f2d37758SMatthew Dillon 	/* accept and ignore a single dash to be 4.4BSD dc(1) compatible */
55abcef8f0SSascha Wildner 	while ((ch = getopt(argc, argv, "e:x-")) != -1) {
56f2d37758SMatthew Dillon 		switch (ch) {
57abcef8f0SSascha Wildner 		case 'e':
58abcef8f0SSascha Wildner 			p = buf;
59abcef8f0SSascha Wildner 			if (asprintf(&buf, "%s %s", buf, optarg) == -1)
60abcef8f0SSascha Wildner 				err(1, NULL);
61abcef8f0SSascha Wildner 			free(p);
62abcef8f0SSascha Wildner 			break;
63f2d37758SMatthew Dillon 		case 'x':
64f2d37758SMatthew Dillon 			extended_regs = true;
65f2d37758SMatthew Dillon 			break;
66f2d37758SMatthew Dillon 		case '-':
67f2d37758SMatthew Dillon 			break;
68f2d37758SMatthew Dillon 		default:
69f2d37758SMatthew Dillon 			usage();
70f2d37758SMatthew Dillon 		}
71f2d37758SMatthew Dillon 	}
72f2d37758SMatthew Dillon 	argc -= optind;
73f2d37758SMatthew Dillon 	argv += optind;
74f2d37758SMatthew Dillon 
75f2d37758SMatthew Dillon 	init_bmachine(extended_regs);
76f2d37758SMatthew Dillon 	setlinebuf(stdout);
77f2d37758SMatthew Dillon 	setlinebuf(stderr);
78f2d37758SMatthew Dillon 
79f2d37758SMatthew Dillon 	if (argc > 1)
80f2d37758SMatthew Dillon 		usage();
81abcef8f0SSascha Wildner 	if (buf[0] != '\0') {
82abcef8f0SSascha Wildner 		src_setstring(&src, buf);
83abcef8f0SSascha Wildner 		reset_bmachine(&src);
84abcef8f0SSascha Wildner 		eval();
85abcef8f0SSascha Wildner 		free(buf);
86abcef8f0SSascha Wildner 		if (argc == 0)
87abcef8f0SSascha Wildner 			return (0);
88abcef8f0SSascha Wildner 	}
89abcef8f0SSascha Wildner 	if (argc == 1) {
90f2d37758SMatthew Dillon 		file = fopen(argv[0], "r");
91f2d37758SMatthew Dillon 		if (file == NULL)
92f2d37758SMatthew Dillon 			err(1, "cannot open file %s", argv[0]);
93*a977bf87SJoris Giovannangeli 		if (fstat(fileno(file), &st) == -1)
94*a977bf87SJoris Giovannangeli 			err(1, "%s", argv[0]);
95*a977bf87SJoris Giovannangeli 		if (S_ISDIR(st.st_mode)) {
96*a977bf87SJoris Giovannangeli 			errno = EISDIR;
97*a977bf87SJoris Giovannangeli 			err(1, "%s", argv[0]);
98*a977bf87SJoris Giovannangeli 		}
99*a977bf87SJoris Giovannangeli 
100f2d37758SMatthew Dillon 		src_setstream(&src, file);
101f2d37758SMatthew Dillon 		reset_bmachine(&src);
102f2d37758SMatthew Dillon 		eval();
103f2d37758SMatthew Dillon 		fclose(file);
104f2d37758SMatthew Dillon 		/*
105abcef8f0SSascha Wildner 		 * BSD and Solaris dc(1) continue with stdin after processing
106abcef8f0SSascha Wildner 		 * the file given as the argument. We follow GNU dc(1).
107f2d37758SMatthew Dillon 		 */
108abcef8f0SSascha Wildner 		 return (0);
109abcef8f0SSascha Wildner 	}
110f2d37758SMatthew Dillon 	src_setstream(&src, stdin);
111f2d37758SMatthew Dillon 	reset_bmachine(&src);
112f2d37758SMatthew Dillon 	eval();
113f2d37758SMatthew Dillon 
114f2d37758SMatthew Dillon 	return 0;
115f2d37758SMatthew Dillon }
116