From be848c7a13013b0555c07bfe92892b5dd546163f Mon Sep 17 00:00:00 2001 From: Xin LI Date: Wed, 16 Apr 2014 23:14:05 +0000 Subject: [PATCH] Sync with OpenBSD. MFC after: 2 weeks --- usr.bin/bc/Makefile | 12 +-- usr.bin/bc/bc.1 | 31 +++++-- usr.bin/bc/bc.library | 6 +- usr.bin/bc/bc.y | 46 +++++----- usr.bin/bc/extern.h | 32 ++++--- usr.bin/bc/scan.l | 196 +++++++++++++++++++++++++++--------------- usr.bin/bc/tty.c | 65 ++++++++++++++ usr.bin/dc/bcode.c | 19 ++-- usr.bin/dc/bcode.h | 26 +++--- usr.bin/dc/dc.1 | 28 +++--- usr.bin/dc/inout.c | 2 +- 11 files changed, 310 insertions(+), 153 deletions(-) create mode 100644 usr.bin/bc/tty.c diff --git a/usr.bin/bc/Makefile b/usr.bin/bc/Makefile index 39d54e06b005..5fd918d055c7 100644 --- a/usr.bin/bc/Makefile +++ b/usr.bin/bc/Makefile @@ -1,12 +1,12 @@ # $FreeBSD$ -# $OpenBSD: Makefile,v 1.4 2006/06/30 19:02:28 otto Exp $ +# $OpenBSD: Makefile,v 1.7 2013/09/19 16:12:00 otto Exp $ -PROG= bc -SRCS= bc.y scan.l -CFLAGS+= -I. -I${.CURDIR} +PROG= bc +SRCS= bc.y scan.l tty.c +CFLAGS+= -I. -I${.CURDIR} -DPADD= ${LIBEDIT} ${LIBTERMCAP} -LDADD= -ledit -ltermcap +LDADD+= -ledit -lcurses +DPADD+= ${LIBEDIT} ${LIBCURSES} NO_WMISSING_VARIABLE_DECLARATIONS= diff --git a/usr.bin/bc/bc.1 b/usr.bin/bc/bc.1 index 0592acda0d65..2d539ee1c5b6 100644 --- a/usr.bin/bc/bc.1 +++ b/usr.bin/bc/bc.1 @@ -1,5 +1,5 @@ .\" $FreeBSD$ -.\" $OpenBSD: bc.1,v 1.25 2010/01/02 19:48:56 schwarze Exp $ +.\" $OpenBSD: bc.1,v 1.30 2014/01/14 07:42:42 jmc Exp $ .\" .\" Copyright (C) Caldera International Inc. 2001-2002. .\" All rights reserved. @@ -35,7 +35,7 @@ .\" .\" @(#)bc.1 6.8 (Berkeley) 8/8/91 .\" -.Dd December 6, 2013 +.Dd April 16, 2014 .Dt BC 1 .Os .Sh NAME @@ -140,8 +140,7 @@ The following arithmetic and logical operators can be used. The semantics of the operators is the same as in the C language. They are listed in order of decreasing precedence. Operators in the same group have the same precedence. -.Bl -column -offset indent "= += \-= *= /= %= ^=" "Associativity" \ -"multiply, divide, modulus" +.Bl -column "= += \-= *= /= %= ^=" "Associativity" "multiply, divide, modulus" -offset indent .It Sy "Operator" Ta Sy "Associativity" Ta Sy "Description" .It "++ \-\-" Ta "none" Ta "increment, decrement" .It "\-" Ta "none" Ta "unary minus" @@ -160,7 +159,7 @@ Note the following: .It The relational operators may appear in any expression. The -.St -p1003.2 +.St -p1003.1-2008 standard only allows them in the conditional expression of an .Sq if , .Sq while @@ -342,6 +341,22 @@ $ bc -l -e 'scale = 500; 2 * a(2^10000)' -e quit .Ed .Pp prints an approximation of pi. +.Sh COMMAND LINE EDITING +.Nm +supports interactive command line editing, via the +.Xr editline 3 +library. +It is enabled by default if input is from a tty. +Previous lines can be recalled and edited with the arrow keys, +and other GNU Emacs-style editing keys may be used as well. +.Pp +The +.Xr editline 3 +library is configured with a +.Pa .editrc +file \- refer to +.Xr editrc 5 +for more information. .Sh FILES .Bl -tag -width /usr/share/misc/bc.library -compact .It Pa /usr/share/misc/bc.library @@ -359,9 +374,6 @@ options are no-ops for compatibility with some other implementations of and their use is discouraged. .Sh SEE ALSO .Xr dc 1 -.Pp -"BC \- An Arbitrary Precision Desk-Calculator Language", -.Pa /usr/share/doc/usd/06.bc/ . .Sh STANDARDS The .Nm @@ -370,7 +382,8 @@ utility is compliant with the specification. .Pp The flags -.Op Fl ce +.Op Fl ce , +as well as the parts noted above, are extensions to that specification. .Sh HISTORY The diff --git a/usr.bin/bc/bc.library b/usr.bin/bc/bc.library index 7f4a93e22360..8b92d25c95f8 100644 --- a/usr.bin/bc/bc.library +++ b/usr.bin/bc/bc.library @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $OpenBSD: bc.library,v 1.3 2007/02/03 21:15:06 otto Exp $ */ +/* $OpenBSD: bc.library,v 1.4 2012/03/14 07:35:53 otto Exp $ */ /* * Copyright (C) Caldera International Inc. 2001-2002. @@ -100,13 +100,13 @@ define l(x) { if (x < 1) { s = scale(x) } else { - s = length(x) - scale(x) + s = length(x)-scale(x) } scale = 0 a = (2.31*s)/1 /* estimated integer part of the answer */ s = t + length(a) + 2 /* estimated length of the answer */ while (x > 2) { - scale=0 + scale = 0 scale = (length(x) + scale(x))/2 + 1 if (scale < s) scale = s x = sqrt(x) diff --git a/usr.bin/bc/bc.y b/usr.bin/bc/bc.y index a819e3f51f09..8e7e00cbfc32 100644 --- a/usr.bin/bc/bc.y +++ b/usr.bin/bc/bc.y @@ -1,5 +1,5 @@ %{ -/* $OpenBSD: bc.y,v 1.33 2009/10/27 23:59:36 deraadt Exp $ */ +/* $OpenBSD: bc.y,v 1.44 2013/11/20 21:33:54 deraadt Exp $ */ /* * Copyright (c) 2003, Otto Moerbeek @@ -45,7 +45,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -53,7 +52,7 @@ __FBSDID("$FreeBSD$"); #include "extern.h" #include "pathnames.h" -#define BC_VER "1.0-FreeBSD" +#define BC_VER "1.1-FreeBSD" #define END_NODE ((ssize_t) -1) #define CONST_STRING ((ssize_t) -2) #define ALLOC_STRING ((ssize_t) -3) @@ -971,7 +970,12 @@ yyerror(const char *s) if (yyin != NULL && feof(yyin)) n = asprintf(&str, "%s: %s:%d: %s: unexpected EOF", __progname, filename, lineno, s); - else if (isspace(yytext[0]) || !isprint(yytext[0])) + else if (yytext[0] == '\n') + n = asprintf(&str, + "%s: %s:%d: %s: newline unexpected", + __progname, filename, lineno, s); + else if (isspace((unsigned char)yytext[0]) || + !isprint((unsigned char)yytext[0])) n = asprintf(&str, "%s: %s:%d: %s: ascii char 0x%02x unexpected", __progname, filename, lineno, s, yytext[0]); @@ -1085,26 +1089,25 @@ escape(const char *str) /* ARGSUSED */ static void -sigchld(int signo) +sigchld(int signo __unused) { pid_t pid; - int status; + int status, save_errno = errno; - switch (signo) { - default: - for (;;) { - pid = waitpid(dc, &status, WUNTRACED); - if (pid == -1) { - if (errno == EINTR) - continue; - _exit(0); - } - if (WIFEXITED(status) || WIFSIGNALED(status)) - _exit(0); - else - break; - } + for (;;) { + pid = waitpid(dc, &status, WCONTINUED | WNOHANG); + if (pid == -1) { + if (errno == EINTR) + continue; + _exit(0); + } else if (pid == 0) + break; + if (WIFEXITED(status) || WIFSIGNALED(status)) + _exit(0); + else + break; } + errno = save_errno; } static const char * @@ -1191,6 +1194,7 @@ main(int argc, char *argv[]) } } if (interactive) { + gettty(&ttysaved); el = el_init("bc", stdin, stderr, stderr); hist = history_init(); history(hist, &he, H_SETSIZE, 100); @@ -1198,6 +1202,8 @@ main(int argc, char *argv[]) el_set(el, EL_EDITOR, "emacs"); el_set(el, EL_SIGNAL, 1); el_set(el, EL_PROMPT, dummy_prompt); + el_set(el, EL_ADDFN, "bc_eof", "", bc_eof); + el_set(el, EL_BIND, "^D", "bc_eof", NULL); el_source(el, NULL); } yywrap(); diff --git a/usr.bin/bc/extern.h b/usr.bin/bc/extern.h index d1e9fe80e5f6..b692311e60f5 100644 --- a/usr.bin/bc/extern.h +++ b/usr.bin/bc/extern.h @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $OpenBSD: extern.h,v 1.6 2006/03/18 20:44:43 otto Exp $ */ +/* $OpenBSD: extern.h,v 1.10 2013/09/19 16:12:01 otto Exp $ */ /* * Copyright (c) 2003, Otto Moerbeek @@ -17,26 +17,34 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include struct lvalue { - ssize_t load; - ssize_t store; + ssize_t load; + ssize_t store; }; -int yylex(void); -void yyerror(const char *); -void fatal(const char *); -void abort_line(int); +int yylex(void); +void yyerror(const char *); +void fatal(const char *); +void abort_line(int); +struct termios; +int gettty(struct termios *); +void tstpcont(int); +unsigned char bc_eof(EditLine *, int); -extern int lineno; -extern int fileindex; -extern int sargc; +extern int lineno; +extern char *yytext; +extern FILE *yyin; +extern int fileindex; +extern int sargc; extern const char **sargv; extern const char *filename; -extern char *cmdexpr; extern bool interactive; extern EditLine *el; extern History *hist; extern HistEvent he; - +extern char *cmdexpr; +extern struct termios ttysaved; +extern bool interactive; diff --git a/usr.bin/bc/scan.l b/usr.bin/bc/scan.l index 71cb295956dc..1bf08c61c5eb 100644 --- a/usr.bin/bc/scan.l +++ b/usr.bin/bc/scan.l @@ -1,5 +1,5 @@ %{ -/* $OpenBSD: scan.l,v 1.23 2009/10/27 23:59:36 deraadt Exp $ */ +/* $OpenBSD: scan.l,v 1.28 2013/09/19 16:12:01 otto Exp $ */ /* * Copyright (c) 2003, Otto Moerbeek @@ -24,6 +24,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -31,19 +32,22 @@ __FBSDID("$FreeBSD$"); #include "bc.h" #include "pathnames.h" -int lineno; +int lineno; +bool interactive; -bool interactive; HistEvent he; EditLine *el; History *hist; static char *strbuf = NULL; -static size_t strbuf_sz = 1; -static bool dot_seen; +static size_t strbuf_sz = 1; +static bool dot_seen; +static int use_el; +static volatile sig_atomic_t skipchars; + +static void init_strbuf(void); +static void add_str(const char *); -static void init_strbuf(void); -static void add_str(const char *); static int bc_yyinput(char *, int); #define YY_DECL int yylex(void) @@ -51,6 +55,7 @@ static int bc_yyinput(char *, int); #undef YY_INPUT #define YY_INPUT(buf,retval,max) \ (retval = bc_yyinput(buf, max)) + %} %option always-interactive @@ -102,7 +107,7 @@ ALPHANUM [a-z_0-9] BEGIN(INITIAL); yylval.str = strbuf; unput('.'); - return (NUMBER); + return NUMBER; } else { dot_seen = true; add_str("."); @@ -113,73 +118,73 @@ ALPHANUM [a-z_0-9] BEGIN(INITIAL); unput(yytext[0]); if (strcmp(strbuf, ".") == 0) - return (DOT); + return DOT; else { yylval.str = strbuf; - return (NUMBER); + return NUMBER; } } } -"auto" return (AUTO); -"break" return (BREAK); -"continue" return (CONTINUE); -"define" return (DEFINE); -"else" return (ELSE); -"ibase" return (IBASE); -"if" return (IF); -"last" return (DOT); -"for" return (FOR); -"length" return (LENGTH); -"obase" return (OBASE); -"print" return (PRINT); -"quit" return (QUIT); -"return" return (RETURN); -"scale" return (SCALE); -"sqrt" return (SQRT); -"while" return (WHILE); +"auto" return AUTO; +"break" return BREAK; +"continue" return CONTINUE; +"define" return DEFINE; +"else" return ELSE; +"ibase" return IBASE; +"if" return IF; +"last" return DOT; +"for" return FOR; +"length" return LENGTH; +"obase" return OBASE; +"print" return PRINT; +"quit" return QUIT; +"return" return RETURN; +"scale" return SCALE; +"sqrt" return SQRT; +"while" return WHILE; -"^" return (EXPONENT); -"*" return (MULTIPLY); -"/" return (DIVIDE); -"%" return (REMAINDER); +"^" return EXPONENT; +"*" return MULTIPLY; +"/" return DIVIDE; +"%" return REMAINDER; -"!" return (BOOL_NOT); -"&&" return (BOOL_AND); -"||" return (BOOL_OR); +"!" return BOOL_NOT; +"&&" return BOOL_AND; +"||" return BOOL_OR; -"+" return (PLUS); -"-" return (MINUS); +"+" return PLUS; +"-" return MINUS; -"++" return (INCR); -"--" return (DECR); +"++" return INCR; +"--" return DECR; -"=" yylval.str = ""; return (ASSIGN_OP); -"+=" yylval.str = "+"; return (ASSIGN_OP); -"-=" yylval.str = "-"; return (ASSIGN_OP); -"*=" yylval.str = "*"; return (ASSIGN_OP); -"/=" yylval.str = "/"; return (ASSIGN_OP); -"%=" yylval.str = "%"; return (ASSIGN_OP); -"^=" yylval.str = "^"; return (ASSIGN_OP); +"=" yylval.str = ""; return ASSIGN_OP; +"+=" yylval.str = "+"; return ASSIGN_OP; +"-=" yylval.str = "-"; return ASSIGN_OP; +"*=" yylval.str = "*"; return ASSIGN_OP; +"/=" yylval.str = "/"; return ASSIGN_OP; +"%=" yylval.str = "%"; return ASSIGN_OP; +"^=" yylval.str = "^"; return ASSIGN_OP; -"==" return (EQUALS); -"<=" return (LESS_EQ); -">=" return (GREATER_EQ); -"!=" return (UNEQUALS); -"<" return (LESS); -">" return (GREATER); +"==" return EQUALS; +"<=" return LESS_EQ; +">=" return GREATER_EQ; +"!=" return UNEQUALS; +"<" return LESS; +">" return GREATER; -"," return (COMMA); -";" return (SEMICOLON); +"," return COMMA; +";" return SEMICOLON; -"(" return (LPAR); -")" return (RPAR); +"(" return LPAR; +")" return RPAR; -"[" return (LBRACKET); -"]" return (RBRACKET); +"[" return LBRACKET; +"]" return RBRACKET; -"{" return (LBRACE); -"}" return (RBRACE); +"{" return LBRACE; +"}" return RBRACE; {ALPHA}{ALPHANUM}* { /* alloc an extra byte for the type marker */ @@ -188,15 +193,15 @@ ALPHANUM [a-z_0-9] err(1, NULL); strlcpy(p, yytext, yyleng + 1); yylval.astr = p; - return (LETTER); + return LETTER; } \\\n lineno++; -\n lineno++; return (NEWLINE); +\n lineno++; return NEWLINE; #[^\n]* ; [ \t] ; -<> return (QUIT); +<> return QUIT; . yyerror("illegal character"); %% @@ -204,7 +209,6 @@ ALPHANUM [a-z_0-9] static void init_strbuf(void) { - if (strbuf == NULL) { strbuf = malloc(strbuf_sz); if (strbuf == NULL) @@ -221,8 +225,8 @@ add_str(const char *str) arglen = strlen(str); if (strlen(strbuf) + arglen + 1 > strbuf_sz) { - size_t newsize; - char *p; + size_t newsize; + char *p; newsize = strbuf_sz + arglen + 1; p = realloc(strbuf, newsize); @@ -236,11 +240,47 @@ add_str(const char *str) strlcat(strbuf, str, strbuf_sz); } +/* ARGSUSED */ +void +abort_line(int sig __unused) +{ + static const char str1[] = "[\n]P\n"; + static const char str2[] = "[^C\n]P\n"; + int save_errno; + const LineInfo *info; + + save_errno = errno; + if (use_el) { + write(STDOUT_FILENO, str2, sizeof(str2) - 1); + info = el_line(el); + skipchars = info->lastchar - info->buffer; + } else + write(STDOUT_FILENO, str1, sizeof(str1) - 1); + errno = save_errno; +} + +/* + * Avoid the echo of ^D by the default code of editline and take + * into account skipchars to make ^D work when the cursor is at start of + * line after a ^C. + */ +unsigned char +bc_eof(EditLine *e, int ch __unused) +{ + const struct lineinfo *info = el_line(e); + + if (info->buffer + skipchars == info->cursor && + info->cursor == info->lastchar) + return (CC_EOF); + else + return (CC_ERROR); +} + int yywrap(void) { - static YY_BUFFER_STATE buf; static int state; + static YY_BUFFER_STATE buf; if (fileindex == 0 && sargc > 0 && strcmp(sargv[0], _PATH_LIBB) == 0) { filename = sargv[fileindex++]; @@ -273,6 +313,10 @@ yywrap(void) } else if (fileindex == sargc) { fileindex++; yyin = stdin; + if (interactive) { + signal(SIGINT, abort_line); + signal(SIGTSTP, tstpcont); + } lineno = 1; filename = "stdin"; return (0); @@ -284,17 +328,32 @@ static int bc_yyinput(char *buf, int maxlen) { int num; - if (yyin == stdin && interactive) { + + if (el != NULL) + el_get(el, EL_EDITMODE, &use_el); + + if (yyin == stdin && interactive && use_el) { const char *bp; + sigset_t oset, nset; if ((bp = el_gets(el, &num)) == NULL || num == 0) return (0); + sigemptyset(&nset); + sigaddset(&nset, SIGINT); + sigprocmask(SIG_BLOCK, &nset, &oset); + if (skipchars < num) { + bp += skipchars; + num -= skipchars; + } + skipchars = 0; + sigprocmask(SIG_SETMASK, &oset, NULL); if (num > maxlen) { - el_push(el, (char *)(uintptr_t)(bp) + maxlen); + el_push(el, (char *)(void *)bp + maxlen); num = maxlen; } memcpy(buf, bp, num); history(hist, &he, H_ENTER, bp); + el_get(el, EL_EDITMODE, &use_el); } else { int c = '*'; for (num = 0; num < maxlen && @@ -308,3 +367,4 @@ bc_yyinput(char *buf, int maxlen) return (num); } + diff --git a/usr.bin/bc/tty.c b/usr.bin/bc/tty.c new file mode 100644 index 000000000000..05f9d1431797 --- /dev/null +++ b/usr.bin/bc/tty.c @@ -0,0 +1,65 @@ +/* $FreeBSD$ */ +/* $OpenBSD: tty.c,v 1.2 2013/11/12 13:54:51 deraadt Exp $ */ + +/* + * Copyright (c) 2013, Otto Moerbeek + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include "extern.h" + +struct termios ttysaved, ttyedit; + +static int +settty(struct termios *t) +{ + int ret; + + while ((ret = tcsetattr(0, TCSADRAIN, t) == -1) && errno == EINTR) + continue; + return ret; +} + +int +gettty(struct termios *t) +{ + int ret; + + while ((ret = tcgetattr(0, t) == -1) && errno == EINTR) + continue; + return ret; +} + +/* ARGSUSED */ +void +tstpcont(int sig) +{ + int save_errno = errno; + + if (sig == SIGTSTP) { + signal(SIGCONT, tstpcont); + gettty(&ttyedit); + settty(&ttysaved); + } else { + signal(SIGTSTP, tstpcont); + settty(&ttyedit); + } + signal(sig, SIG_DFL); + kill(0, sig); + errno = save_errno; +} diff --git a/usr.bin/dc/bcode.c b/usr.bin/dc/bcode.c index f17a0da56c28..52ce85c00c9d 100644 --- a/usr.bin/dc/bcode.c +++ b/usr.bin/dc/bcode.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bcode.c,v 1.40 2009/10/27 23:59:37 deraadt Exp $ */ +/* $OpenBSD: bcode.c,v 1.45 2012/11/07 11:06:14 otto Exp $ */ /* * Copyright (c) 2003, Otto Moerbeek @@ -29,7 +29,7 @@ __FBSDID("$FreeBSD$"); #include "extern.h" -#define __inline +/* #define DEBUGGING */ #define MAX_ARRAY_INDEX 2048 #define READSTACK_SIZE 8 @@ -253,7 +253,7 @@ init_bmachine(bool extended_registers) u_int bmachine_scale(void) { - return (bmachine.scale); + return bmachine.scale; } /* Reset the things needed before processing a (new) file */ @@ -428,7 +428,6 @@ get_ulong(struct number *n) void negate(struct number *n) { - BN_set_negative(n->number, !BN_is_negative(n->number)); } @@ -695,7 +694,7 @@ count_digits(const struct number *n) u_int i; if (BN_is_zero(n->number)) - return (n->scale ? n->scale : 1); + return n->scale ? n->scale : 1; int_part = new_number(); fract_part = new_number(); @@ -1171,9 +1170,10 @@ bdivmod(void) static void bexp(void) { - struct number *a, *p, *r; - u_int rscale; - bool neg; + struct number *a, *p; + struct number *r; + bool neg; + u_int rscale; p = pop_number(); if (p == NULL) { @@ -1193,8 +1193,7 @@ bexp(void) bn_checkp(f); split_number(p, i, f); if (!BN_is_zero(f)) - warnx("Runtime warning: non-zero fractional part " - "in exponent"); + warnx("Runtime warning: non-zero fractional part in exponent"); BN_free(i); BN_free(f); } diff --git a/usr.bin/dc/bcode.h b/usr.bin/dc/bcode.h index 7dc5d2db805f..7911bc21ff32 100644 --- a/usr.bin/dc/bcode.h +++ b/usr.bin/dc/bcode.h @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $OpenBSD: bcode.h,v 1.5 2006/01/16 08:09:25 otto Exp $ */ +/* $OpenBSD: bcode.h,v 1.7 2012/11/07 11:06:14 otto Exp $ */ /* * Copyright (c) 2003, Otto Moerbeek @@ -83,15 +83,15 @@ struct source { int lastchar; }; -void init_bmachine(bool); -void reset_bmachine(struct source *); -u_int bmachine_scale(void); -void scale_number(BIGNUM *, int); -void normalize(struct number *, u_int); -void eval(void); -void pn(const char *, const struct number *); -void pbn(const char *, const BIGNUM *); -void negate(struct number *); -void split_number(const struct number *, BIGNUM *, BIGNUM *); -void bmul_number(struct number *, struct number *, - struct number *, u_int); +void init_bmachine(bool); +void reset_bmachine(struct source *); +u_int bmachine_scale(void); +void scale_number(BIGNUM *, int); +void normalize(struct number *, u_int); +void eval(void); +void pn(const char *, const struct number *); +void pbn(const char *, const BIGNUM *); +void negate(struct number *); +void split_number(const struct number *, BIGNUM *, BIGNUM *); +void bmul_number(struct number *, struct number *, + struct number *, u_int scale); diff --git a/usr.bin/dc/dc.1 b/usr.bin/dc/dc.1 index 94dba767e653..507bbe6777d3 100644 --- a/usr.bin/dc/dc.1 +++ b/usr.bin/dc/dc.1 @@ -1,5 +1,5 @@ .\" $FreeBSD$ -.\" $OpenBSD: dc.1,v 1.24 2010/01/02 19:48:56 schwarze Exp $ +.\" $OpenBSD: dc.1,v 1.27 2012/08/19 12:07:21 jmc Exp $ .\" .\" Copyright (C) Caldera International Inc. 2001-2002. .\" All rights reserved. @@ -35,7 +35,7 @@ .\" .\" @(#)dc.1 8.1 (Berkeley) 6/6/93 .\" -.Dd January 22, 2010 +.Dd April 16, 2014 .Dt DC 1 .Os .Sh NAME @@ -73,12 +73,6 @@ Evaluate If multiple .Fl e options are specified, they will be processed in the order given. -If no -.Ar filename -argument is given, execution will stop after processing the expressions -given on the command line, -otherwise processing will continue with the contents of -.Ar filename . .It Fl f Ar filename , Fl Fl file Ar filename Process the content of the given file before further calculations are done. If multiple @@ -98,14 +92,26 @@ See for a more detailed description. .El .Pp +If neither +.Ar expression +nor +.Ar file +are specified on the command line, +.Nm +reads from the standard input. +Otherwise +.Ar expression +and +.Ar file +are processed and +.Nm +exits. +.Pp Ordinarily, .Nm operates on decimal integers, but one may specify an input base, output base, and a number of fractional digits (scale) to be maintained. -If an argument is given, -input is taken from that file until its end, -then from the standard input. Whitespace is ignored, except where it signals the end of a number, end of a line or when a register name is expected. The following constructions are recognized: diff --git a/usr.bin/dc/inout.c b/usr.bin/dc/inout.c index e35f0ad45942..740fb35bae7f 100644 --- a/usr.bin/dc/inout.c +++ b/usr.bin/dc/inout.c @@ -1,4 +1,4 @@ -/* $OpenBSD: inout.c,v 1.15 2009/10/27 23:59:37 deraadt Exp $ */ +/* $OpenBSD: inout.c,v 1.17 2012/11/07 11:06:14 otto Exp $ */ /* * Copyright (c) 2003, Otto Moerbeek