NetBSD/usr.bin/vi/common/util.c

238 lines
4.2 KiB
C
Raw Normal View History

2002-04-09 05:47:30 +04:00
/* $NetBSD: util.c,v 1.4 2002/04/09 01:47:32 thorpej Exp $ */
1998-01-09 11:03:16 +03:00
1994-08-17 20:17:19 +04:00
/*-
* Copyright (c) 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
1996-05-20 06:01:36 +04:00
* Copyright (c) 1991, 1993, 1994, 1995, 1996
* Keith Bostic. All rights reserved.
1994-08-17 20:17:19 +04:00
*
1996-05-20 06:01:36 +04:00
* See the LICENSE file for redistribution information.
1994-08-17 20:17:19 +04:00
*/
1996-05-20 06:01:36 +04:00
#include "config.h"
2002-04-09 05:47:30 +04:00
#include <sys/cdefs.h>
1994-08-17 20:17:19 +04:00
#ifndef lint
2002-04-09 05:47:30 +04:00
#if 0
2001-03-31 15:37:44 +04:00
static const char sccsid[] = "@(#)util.c 10.11 (Berkeley) 9/15/96";
2002-04-09 05:47:30 +04:00
#else
__RCSID("$NetBSD: util.c,v 1.4 2002/04/09 01:47:32 thorpej Exp $");
#endif
1994-08-17 20:17:19 +04:00
#endif /* not lint */
#include <sys/types.h>
#include <sys/queue.h>
#include <bitstring.h>
1996-05-20 06:01:36 +04:00
#include <errno.h>
1994-08-17 20:17:19 +04:00
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
1996-05-20 06:01:36 +04:00
#include "common.h"
1994-08-17 20:17:19 +04:00
/*
* binc --
* Increase the size of a buffer.
1996-05-20 06:01:36 +04:00
*
* PUBLIC: void *binc __P((SCR *, void *, size_t *, size_t));
1994-08-17 20:17:19 +04:00
*/
void *
binc(sp, bp, bsizep, min)
SCR *sp; /* sp MAY BE NULL!!! */
void *bp;
size_t *bsizep, min;
{
size_t csize;
/* If already larger than the minimum, just return. */
if (min && *bsizep >= min)
return (bp);
csize = *bsizep + MAX(min, 256);
REALLOC(sp, bp, void *, csize);
if (bp == NULL) {
/*
* Theoretically, realloc is supposed to leave any already
* held memory alone if it can't get more. Don't trust it.
*/
*bsizep = 0;
return (NULL);
}
/*
* Memory is guaranteed to be zero-filled, various parts of
* nvi depend on this.
*/
memset((char *)bp + *bsizep, 0, csize - *bsizep);
*bsizep = csize;
return (bp);
}
/*
* nonblank --
* Set the column number of the first non-blank character
* including or after the starting column. On error, set
* the column to 0, it's safest.
1996-05-20 06:01:36 +04:00
*
* PUBLIC: int nonblank __P((SCR *, recno_t, size_t *));
1994-08-17 20:17:19 +04:00
*/
int
1996-05-20 06:01:36 +04:00
nonblank(sp, lno, cnop)
1994-08-17 20:17:19 +04:00
SCR *sp;
recno_t lno;
size_t *cnop;
{
char *p;
size_t cnt, len, off;
1996-05-20 06:01:36 +04:00
int isempty;
1994-08-17 20:17:19 +04:00
/* Default. */
off = *cnop;
*cnop = 0;
1996-05-20 06:01:36 +04:00
/* Get the line, succeeding in an empty file. */
if (db_eget(sp, lno, &p, &len, &isempty))
return (!isempty);
1994-08-17 20:17:19 +04:00
/* Set the offset. */
if (len == 0 || off >= len)
return (0);
for (cnt = off, p = &p[off],
len -= off; len && isblank(*p); ++cnt, ++p, --len);
/* Set the return. */
*cnop = len ? cnt : cnt - 1;
return (0);
}
/*
* tail --
* Return tail of a path.
1996-05-20 06:01:36 +04:00
*
* PUBLIC: char *tail __P((char *));
1994-08-17 20:17:19 +04:00
*/
char *
tail(path)
char *path;
{
char *p;
if ((p = strrchr(path, '/')) == NULL)
return (path);
return (p + 1);
}
/*
* v_strdup --
* Strdup for wide character strings with an associated length.
1996-05-20 06:01:36 +04:00
*
* PUBLIC: CHAR_T *v_strdup __P((SCR *, const CHAR_T *, size_t));
1994-08-17 20:17:19 +04:00
*/
CHAR_T *
v_strdup(sp, str, len)
SCR *sp;
1996-05-20 06:01:36 +04:00
const CHAR_T *str;
1994-08-17 20:17:19 +04:00
size_t len;
{
CHAR_T *copy;
MALLOC(sp, copy, CHAR_T *, len + 1);
if (copy == NULL)
return (NULL);
2001-03-31 15:37:44 +04:00
memcpy(copy, str, len * sizeof(CHAR_T));
1994-08-17 20:17:19 +04:00
copy[len] = '\0';
return (copy);
}
/*
1996-05-20 06:01:36 +04:00
* nget_uslong --
* Get an unsigned long, checking for overflow.
*
* PUBLIC: enum nresult nget_uslong __P((u_long *, const char *, char **, int));
*/
enum nresult
nget_uslong(valp, p, endp, base)
u_long *valp;
const char *p;
char **endp;
int base;
{
errno = 0;
*valp = strtoul(p, endp, base);
if (errno == 0)
return (NUM_OK);
if (errno == ERANGE && *valp == ULONG_MAX)
return (NUM_OVER);
return (NUM_ERR);
}
/*
* nget_slong --
* Convert a signed long, checking for overflow and underflow.
*
* PUBLIC: enum nresult nget_slong __P((long *, const char *, char **, int));
*/
enum nresult
nget_slong(valp, p, endp, base)
long *valp;
const char *p;
char **endp;
int base;
{
errno = 0;
*valp = strtol(p, endp, base);
if (errno == 0)
return (NUM_OK);
if (errno == ERANGE) {
if (*valp == LONG_MAX)
return (NUM_OVER);
if (*valp == LONG_MIN)
return (NUM_UNDER);
}
return (NUM_ERR);
}
#ifdef DEBUG
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
/*
* TRACE --
* debugging trace routine.
*
* PUBLIC: void TRACE __P((SCR *, const char *, ...));
1994-08-17 20:17:19 +04:00
*/
void
1996-05-20 06:01:36 +04:00
#ifdef __STDC__
TRACE(SCR *sp, const char *fmt, ...)
#else
TRACE(sp, fmt, va_alist)
SCR *sp;
char *fmt;
va_dcl
#endif
1994-08-17 20:17:19 +04:00
{
1996-05-20 06:01:36 +04:00
FILE *tfp;
va_list ap;
if ((tfp = sp->gp->tracefp) == NULL)
return;
#ifdef __STDC__
va_start(ap, fmt);
#else
va_start(ap);
#endif
(void)vfprintf(tfp, fmt, ap);
va_end(ap);
(void)fflush(tfp);
1994-08-17 20:17:19 +04:00
}
1996-05-20 06:01:36 +04:00
#endif