* Copyright (c) 1992, 1993, 1994
* The Regents of the University of California. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
static char sccsid
[] = "@(#)v_increment.c 8.8 (Berkeley) 3/8/94";
static char * const fmt
[] = {
* v_increment -- [count]#[#+-]
* Increment/decrement a keyword number.
char *bp
, *ntype
, *p
, nbuf
[100];
/* Do repeat operations. */
if (vp
->character
== '#')
vp
->character
= vip
->inc_lastch
;
if (F_ISSET(vp
, VC_C1SET
))
vip
->inc_lastval
= vp
->count
;
if (vp
->character
!= '+' && vp
->character
!= '-') {
msgq(sp
, M_ERR
, "usage: %s.", vp
->kp
->usage
);
vip
->inc_lastch
= vp
->character
;
/* Figure out the resulting type and number. */
if (len
> 1 && p
[0] == '0') {
if (vp
->character
== '+') {
ulval
= strtoul(vp
->keyword
, NULL
, 0);
if (ULONG_MAX
- ulval
< vip
->inc_lastval
)
ulval
+= vip
->inc_lastval
;
ulval
= strtoul(vp
->keyword
, NULL
, 0);
if (ulval
< vip
->inc_lastval
)
ulval
-= vip
->inc_lastval
;
nlen
= snprintf(nbuf
, sizeof(nbuf
), ntype
, len
, ulval
);
if (vp
->character
== '+') {
lval
= strtol(vp
->keyword
, NULL
, 0);
if (lval
> 0 && LONG_MAX
- lval
< vip
->inc_lastval
) {
overflow
: msgq(sp
, M_ERR
, "Resulting number too large.");
lval
+= vip
->inc_lastval
;
lval
= strtol(vp
->keyword
, NULL
, 0);
if (lval
< 0 && -(LONG_MIN
- lval
) < vip
->inc_lastval
) {
underflow
: msgq(sp
, M_ERR
, "Resulting number too small.");
lval
-= vip
->inc_lastval
;
(*vp
->keyword
== '+' || *vp
->keyword
== '-') ?
nlen
= snprintf(nbuf
, sizeof(nbuf
), ntype
, lval
);
if ((p
= file_gline(sp
, ep
, vp
->m_start
.lno
, &len
)) == NULL
) {
GETLINE_ERR(sp
, vp
->m_start
.lno
);
GET_SPACE_RET(sp
, bp
, blen
, len
+ nlen
);
memmove(bp
, p
, vp
->m_start
.cno
);
memmove(bp
+ vp
->m_start
.cno
, nbuf
, nlen
);
memmove(bp
+ vp
->m_start
.cno
+ nlen
,
p
+ vp
->m_start
.cno
+ vp
->klen
, len
- vp
->m_start
.cno
- vp
->klen
);
len
= len
- vp
->klen
+ nlen
;
rval
= file_sline(sp
, ep
, vp
->m_start
.lno
, bp
, len
);
FREE_SPACE(sp
, bp
, blen
);