/*- * Copyright (c) 1991, 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 * are met: * 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 * SUCH DAMAGE. */ #ifndef lint static char sccsid[] = "@(#)util.c 8.74 (Berkeley) 8/17/94"; #endif /* not lint */ #include #include #include #include #include #include #include #include #include #include #include #include "compat.h" #include #include #include #include "vi.h" /* * binc -- * Increase the size of a buffer. */ 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. */ int nonblank(sp, ep, lno, cnop) SCR *sp; EXF *ep; recno_t lno; size_t *cnop; { char *p; size_t cnt, len, off; /* Default. */ off = *cnop; *cnop = 0; /* Get the line. */ if ((p = file_gline(sp, ep, lno, &len)) == NULL) { if (file_lline(sp, ep, &lno)) return (1); if (lno == 0) return (0); GETLINE_ERR(sp, lno); return (1); } /* 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. */ char * tail(path) char *path; { char *p; if ((p = strrchr(path, '/')) == NULL) return (path); return (p + 1); } /* * set_alt_name -- * Set the alternate file name. * * Swap the alternate file name. It's a routine because I wanted some place * to hang this comment. The alternate file name (normally referenced using * the special character '#' during file expansion) is set by many * operations. In the historic vi, the commands "ex", and "edit" obviously * set the alternate file name because they switched the underlying file. * Less obviously, the "read", "file", "write" and "wq" commands set it as * well. In this implementation, some new commands have been added to the * list. Where it gets interesting is that the alternate file name is set * multiple times by some commands. If an edit attempt fails (for whatever * reason, like the current file is modified but as yet unwritten), it is * set to the file name that the user was unable to edit. If the edit * succeeds, it is set to the last file name that was edited. Good fun. * * If the user edits a temporary file, there are time when there isn't an * alternative file name. A name argument of NULL turns it off. */ void set_alt_name(sp, name) SCR *sp; char *name; { if (sp->alt_name != NULL) free(sp->alt_name); if (name == NULL) sp->alt_name = NULL; else if ((sp->alt_name = strdup(name)) == NULL) msgq(sp, M_SYSERR, NULL); } /* * v_strdup -- * Strdup for wide character strings with an associated length. */ CHAR_T * v_strdup(sp, str, len) SCR *sp; CHAR_T *str; size_t len; { CHAR_T *copy; MALLOC(sp, copy, CHAR_T *, len + 1); if (copy == NULL) return (NULL); memmove(copy, str, len * sizeof(CHAR_T)); copy[len] = '\0'; return (copy); } /* * vi_putchar -- * Functional version of putchar, for tputs. */ void vi_putchar(ch) int ch; { (void)putchar(ch); }