fatbase

portable OpenBSD tools
git clone git://git.2f30.org/fatbase
Log | Files | Refs

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 }