2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
5 * %sccs.include.redist.c%
9 static char sccsid
[] = "$Id: v_increment.c,v 8.6 1993/12/09 19:43:12 bostic Exp $ (Berkeley) $Date: 1993/12/09 19:43:12 $";
12 #include <sys/types.h>
21 static char * const fmt
[] = {
35 * v_increment -- [count]#[#+-]
36 * Increment/decrement a keyword number.
39 v_increment(sp
, ep
, vp
, fm
, tm
, rp
)
48 size_t blen
, len
, nlen
;
50 char *bp
, *ntype
, *p
, nbuf
[100];
54 /* Do repeat operations. */
55 if (vp
->character
== '#')
56 vp
->character
= vip
->inc_lastch
;
59 if (F_ISSET(vp
, VC_C1SET
))
60 vip
->inc_lastval
= vp
->count
;
62 if (vp
->character
!= '+' && vp
->character
!= '-') {
63 msgq(sp
, M_ERR
, "usage: %s.", vp
->kp
->usage
);
66 vip
->inc_lastch
= vp
->character
;
68 /* Figure out the resulting type and number. */
71 if (len
> 1 && p
[0] == '0') {
72 if (vp
->character
== '+') {
73 ulval
= strtoul(vp
->keyword
, NULL
, 0);
74 if (ULONG_MAX
- ulval
< vip
->inc_lastval
)
76 ulval
+= vip
->inc_lastval
;
78 ulval
= strtoul(vp
->keyword
, NULL
, 0);
79 if (ulval
< vip
->inc_lastval
)
81 ulval
-= vip
->inc_lastval
;
89 nlen
= snprintf(nbuf
, sizeof(nbuf
), ntype
, len
, ulval
);
91 if (vp
->character
== '+') {
92 lval
= strtol(vp
->keyword
, NULL
, 0);
93 if (lval
> 0 && LONG_MAX
- lval
< vip
->inc_lastval
) {
94 overflow
: msgq(sp
, M_ERR
, "Resulting number too large.");
97 lval
+= vip
->inc_lastval
;
99 lval
= strtol(vp
->keyword
, NULL
, 0);
100 if (lval
< 0 && -(LONG_MIN
- lval
) < vip
->inc_lastval
) {
101 underflow
: msgq(sp
, M_ERR
, "Resulting number too small.");
104 lval
-= vip
->inc_lastval
;
107 (*vp
->keyword
== '+' || *vp
->keyword
== '-') ?
108 fmt
[SDEC
] : fmt
[DEC
];
109 nlen
= snprintf(nbuf
, sizeof(nbuf
), ntype
, lval
);
112 if ((p
= file_gline(sp
, ep
, fm
->lno
, &len
)) == NULL
) {
113 GETLINE_ERR(sp
, fm
->lno
);
117 GET_SPACE_RET(sp
, bp
, blen
, len
+ nlen
);
118 memmove(bp
, p
, fm
->cno
);
119 memmove(bp
+ fm
->cno
, nbuf
, nlen
);
120 memmove(bp
+ fm
->cno
+ nlen
,
121 p
+ fm
->cno
+ vp
->klen
, len
- fm
->cno
- vp
->klen
);
122 len
= len
- vp
->klen
+ nlen
;
124 rval
= file_sline(sp
, ep
, fm
->lno
, bp
, len
);
125 FREE_SPACE(sp
, bp
, blen
);