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