dc.c revision 247441
1249423Sdim/* $OpenBSD: dc.c,v 1.11 2009/10/27 23:59:37 deraadt Exp $ */ 2249423Sdim 3249423Sdim/* 4249423Sdim * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net> 5249423Sdim * Copyright (c) 2009, Gabor Kovesdan <gabor@FreeBSD.org> 6249423Sdim * 7249423Sdim * Permission to use, copy, modify, and distribute this software for any 8249423Sdim * purpose with or without fee is hereby granted, provided that the above 9249423Sdim * copyright notice and this permission notice appear in all copies. 10249423Sdim * 11249423Sdim * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12249423Sdim * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13249423Sdim * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14193326Sed * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15249423Sdim * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16249423Sdim * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17234353Sdim * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18249423Sdim */ 19198092Srdivacky 20249423Sdim#include <sys/cdefs.h> 21226633Sdim__FBSDID("$FreeBSD: head/usr.bin/dc/dc.c 247441 2013-02-28 01:22:14Z gjb $"); 22249423Sdim 23226633Sdim#include <sys/stat.h> 24226633Sdim 25193326Sed#include <ctype.h> 26226633Sdim#include <err.h> 27193326Sed#include <errno.h> 28193326Sed#include <getopt.h> 29198092Srdivacky#include <stdio.h> 30226633Sdim#include <stdlib.h> 31226633Sdim#include <string.h> 32226633Sdim#include <unistd.h> 33234353Sdim 34193326Sed#include "extern.h" 35234353Sdim 36226633Sdim#define DC_VER "1.3-FreeBSD" 37234353Sdim 38226633Sdimstatic void usage(void); 39226633Sdim 40226633Sdimextern char *__progname; 41226633Sdim 42193326Sedstatic struct source src; 43226633Sdim 44193326Sedstatic const struct option long_options[] = 45226633Sdim{ 46226633Sdim {"expression", required_argument, NULL, 'e'}, 47198092Srdivacky {"file", required_argument, NULL, 'f'}, 48226633Sdim {"help", no_argument, NULL, 'h'}, 49193326Sed {"version", no_argument, NULL, 'V'} 50226633Sdim}; 51226633Sdim 52226633Sdimstatic void 53226633Sdimusage(void) 54193326Sed{ 55226633Sdim fprintf(stderr, "usage: %s [-hVx] [-e expression] [file]\n", 56226633Sdim __progname); 57226633Sdim exit(1); 58226633Sdim} 59226633Sdim 60226633Sdimstatic void 61226633Sdimprocfile(char *fname) { 62226633Sdim struct stat st; 63193326Sed FILE *file; 64226633Sdim 65226633Sdim file = fopen(fname, "r"); 66198092Srdivacky if (file == NULL) 67226633Sdim err(1, "cannot open file %s", fname); 68226633Sdim if (fstat(fileno(file), &st) == -1) 69226633Sdim err(1, "%s", fname); 70226633Sdim if (S_ISDIR(st.st_mode)) { 71226633Sdim errno = EISDIR; 72226633Sdim err(1, "%s", fname); 73226633Sdim } 74226633Sdim src_setstream(&src, file); 75193326Sed reset_bmachine(&src); 76226633Sdim eval(); 77226633Sdim fclose(file); 78226633Sdim} 79198092Srdivacky 80226633Sdimint 81226633Sdimmain(int argc, char *argv[]) 82193326Sed{ 83226633Sdim int ch; 84234353Sdim bool extended_regs = false, preproc_done = false; 85226633Sdim 86198092Srdivacky /* accept and ignore a single dash to be 4.4BSD dc(1) compatible */ 87226633Sdim while ((ch = getopt_long(argc, argv, "e:f:hVx", long_options, NULL)) != -1) { 88226633Sdim switch (ch) { 89226633Sdim case 'e': 90263508Sdim if (!preproc_done) 91226633Sdim init_bmachine(extended_regs); 92226633Sdim src_setstring(&src, optarg); 93193326Sed reset_bmachine(&src); 94193326Sed eval(); 95226633Sdim preproc_done = true; 96226633Sdim break; 97226633Sdim case 'f': 98234353Sdim if (!preproc_done) 99226633Sdim init_bmachine(extended_regs); 100226633Sdim procfile(optarg); 101226633Sdim preproc_done = true; 102226633Sdim break; 103226633Sdim case 'x': 104226633Sdim extended_regs = true; 105226633Sdim break; 106226633Sdim case 'V': 107226633Sdim fprintf(stderr, "%s (BSD bc) %s\n", __progname, DC_VER); 108226633Sdim exit(0); 109226633Sdim break; 110226633Sdim case '-': 111226633Sdim break; 112226633Sdim case 'h': 113226633Sdim /* FALLTHROUGH */ 114226633Sdim default: 115226633Sdim usage(); 116226633Sdim } 117226633Sdim } 118234353Sdim argc -= optind; 119226633Sdim argv += optind; 120226633Sdim 121226633Sdim if (!preproc_done) 122226633Sdim init_bmachine(extended_regs); 123226633Sdim setlinebuf(stdout); 124226633Sdim setlinebuf(stderr); 125226633Sdim 126226633Sdim if (argc > 1) 127226633Sdim usage(); 128226633Sdim if (argc == 1) { 129226633Sdim procfile(argv[0]); 130193326Sed preproc_done = true; 131226633Sdim } 132198092Srdivacky if (preproc_done) 133193326Sed return (0); 134226633Sdim 135226633Sdim src_setstream(&src, stdin); 136226633Sdim reset_bmachine(&src); 137193326Sed eval(); 138226633Sdim 139226633Sdim return (0); 140226633Sdim} 141193326Sed