dc.c revision 208974
1139749Simp/* $OpenBSD: dc.c,v 1.11 2009/10/27 23:59:37 deraadt Exp $ */ 2119917Swpaul 3119917Swpaul/* 4139749Simp * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net> 5119917Swpaul * Copyright (c) 2009, Gabor Kovesdan <gabor@FreeBSD.org> 6119917Swpaul * 7119917Swpaul * Permission to use, copy, modify, and distribute this software for any 8119917Swpaul * purpose with or without fee is hereby granted, provided that the above 9119917Swpaul * copyright notice and this permission notice appear in all copies. 10119917Swpaul * 11119917Swpaul * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12119917Swpaul * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13119917Swpaul * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14119917Swpaul * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15119917Swpaul * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16119917Swpaul * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17119917Swpaul * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18119917Swpaul */ 19119917Swpaul 20119917Swpaul#include <sys/cdefs.h> 21119917Swpaul__FBSDID("$FreeBSD: head/usr.bin/dc/dc.c 208974 2010-06-10 10:17:00Z gabor $"); 22119917Swpaul 23119917Swpaul#include <sys/stat.h> 24119917Swpaul 25119917Swpaul#include <ctype.h> 26119917Swpaul#include <err.h> 27119917Swpaul#include <errno.h> 28119917Swpaul#include <getopt.h> 29119917Swpaul#include <stdio.h> 30119917Swpaul#include <stdlib.h> 31119917Swpaul#include <string.h> 32119917Swpaul#include <unistd.h> 33181953Syongari 34181953Syongari#include "extern.h" 35181953Syongari 36181953Syongari#define DC_VER "1.3-FreeBSD" 37119917Swpaul 38129879Sphkstatic void usage(void); 39181953Syongari 40119917Swpaulextern char *__progname; 41181953Syongari 42181994Syongaristruct source src; 43119917Swpaul 44181953Syongaristruct option long_options[] = 45119917Swpaul{ 46119917Swpaul {"expression", required_argument, NULL, 'e'}, 47119917Swpaul {"file", required_argument, NULL, 'f'}, 48119917Swpaul {"help", no_argument, NULL, 'h'}, 49119917Swpaul {"version", no_argument, NULL, 'V'} 50119917Swpaul}; 51119917Swpaul 52119917Swpaulstatic void 53119917Swpaulusage(void) 54119917Swpaul{ 55119917Swpaul fprintf(stderr, "usage: %s [-hVx] [-e expression] [file]\n", 56119917Swpaul __progname); 57119917Swpaul exit(1); 58181953Syongari} 59181953Syongari 60119917Swpaulstatic void 61119917Swpaulprocfile(char *fname) { 62119917Swpaul struct stat st; 63119917Swpaul FILE *file; 64119917Swpaul 65119917Swpaul file = fopen(fname, "r"); 66151545Simp if (file == NULL) 67119917Swpaul err(1, "cannot open file %s", fname); 68119917Swpaul if (fstat(fileno(file), &st) == -1) 69119917Swpaul err(1, "%s", fname); 70119917Swpaul if (S_ISDIR(st.st_mode)) { 71119917Swpaul errno = EISDIR; 72119917Swpaul err(1, "%s", fname); 73119917Swpaul } 74134590Sdes src_setstream(&src, file); 75134590Sdes reset_bmachine(&src); 76119917Swpaul eval(); 77119917Swpaul fclose(file); 78119917Swpaul} 79119917Swpaul 80119917Swpaulint 81119917Swpaulmain(int argc, char *argv[]) 82164456Sjhb{ 83164456Sjhb int ch; 84119917Swpaul bool extended_regs = false, preproc_done = false; 85119917Swpaul 86181953Syongari /* accept and ignore a single dash to be 4.4BSD dc(1) compatible */ 87119917Swpaul while ((ch = getopt_long(argc, argv, "e:f:Vx", long_options, NULL)) != -1) { 88136804Smtm switch (ch) { 89119917Swpaul case 'e': 90119917Swpaul if (!preproc_done) 91136804Smtm init_bmachine(extended_regs); 92119917Swpaul src_setstring(&src, optarg); 93175787Syongari reset_bmachine(&src); 94173839Syongari eval(); 95119917Swpaul preproc_done = true; 96119917Swpaul break; 97119917Swpaul case 'f': 98119917Swpaul if (!preproc_done) 99119917Swpaul init_bmachine(extended_regs); 100181953Syongari procfile(optarg); 101181953Syongari preproc_done = true; 102181953Syongari break; 103119917Swpaul case 'x': 104119917Swpaul extended_regs = true; 105119917Swpaul break; 106119917Swpaul case 'V': 107119917Swpaul fprintf(stderr, "%s (BSD bc) %s\n", __progname, DC_VER); 108119917Swpaul exit(0); 109119917Swpaul break; 110119917Swpaul case '-': 111133282Sdes break; 112119917Swpaul case 'h': 113119917Swpaul /* FALLTHROUGH */ 114119917Swpaul default: 115119917Swpaul usage(); 116119917Swpaul } 117119917Swpaul } 118119917Swpaul argc -= optind; 119119917Swpaul argv += optind; 120119917Swpaul 121119917Swpaul if (!preproc_done) 122119917Swpaul init_bmachine(extended_regs); 123119917Swpaul setlinebuf(stdout); 124119917Swpaul setlinebuf(stderr); 125181953Syongari 126181953Syongari if (argc > 1) 127119917Swpaul usage(); 128119917Swpaul if (argc == 1) { 129181994Syongari procfile(argv[0]); 130119917Swpaul preproc_done = true; 131119917Swpaul } 132119917Swpaul if (preproc_done) 133119917Swpaul return (0); 134119917Swpaul 135119917Swpaul src_setstream(&src, stdin); 136119917Swpaul reset_bmachine(&src); 137164456Sjhb eval(); 138164456Sjhb 139119917Swpaul return (0); 140119917Swpaul} 141119917Swpaul