1 /* @(#)numbercmds.c 1.19 09/07/09 Copyright 1984-2009 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)numbercmds.c 1.19 09/07/09 Copyright 1984-2009 J. Schilling";
6 #endif
7 /*
8 * Routines that deal with number and mult.
9 *
10 * Copyright (c) 1984-2009 J. Schilling
11 */
12 /*
13 * The contents of this file are subject to the terms of the
14 * Common Development and Distribution License, Version 1.0 only
15 * (the "License"). You may not use this file except in compliance
16 * with the License.
17 *
18 * See the file CDDL.Schily.txt in this distribution for details.
19 * A copy of the CDDL is also available via the Internet at
20 * http://www.opensource.org/licenses/cddl1.txt
21 *
22 * When distributing Covered Code, include this CDDL HEADER in each
23 * file and include the License file CDDL.Schily.txt from this distribution.
24 */
25
26 #include "ved.h"
27
28 LOCAL ecnt_t mult = (ecnt_t)4;
29 LOCAL ecnt_t maxnum = (ecnt_t)0;
30
31 EXPORT void initnum __PR((void));
32 EXPORT void vmult __PR((ewin_t *wp));
33 EXPORT void vsmult __PR((ewin_t *wp));
34 EXPORT void vnum __PR((ewin_t *wp));
35 LOCAL void enumbad __PR((ewin_t *wp));
36 LOCAL void enumoverflow __PR((ewin_t *wp));
37 LOCAL void enumnegative __PR((ewin_t *wp));
38
39 /*
40 * Multiply number with mult.
41 */
42 EXPORT void
initnum()43 initnum()
44 {
45 ecnt_t n;
46 ecnt_t on;
47 ecnt_t a;
48 int i;
49
50 if (maxnum == 0) {
51 /*
52 * Overflow bei Berechnung von maxnum verhindern
53 */
54 for (i = 0, on = 0, n = (ecnt_t)1; n > 0 && n > on && i < 256; i++) {
55 on = n;
56 n = 2*n;
57 }
58 for (i = 0, a = n = on; n > (ecnt_t)0 && n >= on && i < 256; i++) {
59 on = n;
60 a /= 2;
61 if (a < 1)
62 break;
63 n += a;
64 }
65 maxnum = on;
66 }
67 }
68
69 /*
70 * Multiply number with mult.
71 */
72 EXPORT void
vmult(wp)73 vmult(wp)
74 ewin_t *wp;
75 {
76 if ((wp->eflags & KEEPDEL) != 0)
77 wp->eflags |= DELDONE;
78 wp->eflags &= ~COLUPDATE;
79
80 if (wp->number >= maxnum/mult) {
81 enumoverflow(wp);
82 return;
83 }
84 wp->eflags |= SAVENUM;
85 wp->number *= mult;
86 writenum(wp, wp->number);
87 }
88
89 /*
90 * Set mult.
91 */
92 EXPORT void
vsmult(wp)93 vsmult(wp)
94 ewin_t *wp;
95 {
96 Llong l;
97 ecnt_t n;
98 Uchar numbuf[NAMESIZE];
99
100 if (! getcmdline(wp, numbuf, sizeof (numbuf), "Mult = "))
101 return;
102 if (*astoll(C numbuf, &l)) {
103 enumbad(wp);
104 } else if (l <= 0) {
105 enumnegative(wp);
106 } else {
107 n = l;
108 if (n != l) {
109 enumoverflow(wp);
110 return;
111 }
112 mult = l;
113 }
114 wp->eflags &= ~COLUPDATE;
115 }
116
117 /*
118 * Set number from the commandline.
119 * We already have the first character.
120 * XXX If we bind this to something else than ESC[0-9], we have to rethink.
121 */
122 EXPORT void
vnum(wp)123 vnum(wp)
124 ewin_t *wp;
125 {
126 Llong l;
127 ecnt_t n;
128 Uchar numbuf[NAMESIZE];
129
130 if (! getccmdline(wp, wp->lastch, numbuf, sizeof (numbuf), "# = "))
131 return;
132 if (*astoll(C numbuf, &l)) {
133 enumbad(wp);
134 } else if (l <= 0) {
135 enumnegative(wp);
136 } else {
137 n = l;
138 if (n != l) {
139 enumoverflow(wp);
140 return;
141 }
142 wp->number = l;
143 writenum(wp, wp->number);
144 }
145 wp->eflags |= SAVENUM;
146 if ((wp->eflags & KEEPDEL) != 0)
147 wp->eflags |= DELDONE;
148 }
149
150 LOCAL void
enumbad(wp)151 enumbad(wp)
152 ewin_t *wp;
153 {
154 writeerr(wp, "Bad Number");
155 }
156
157 LOCAL void
enumoverflow(wp)158 enumoverflow(wp)
159 ewin_t *wp;
160 {
161 writeerr(wp, "Number Overflow!");
162 }
163
164 LOCAL void
enumnegative(wp)165 enumnegative(wp)
166 ewin_t *wp;
167 {
168 writeerr(wp, "Must be Positive");
169 }
170