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