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