util.c revision 1.1
1/*-
2 * Copyright (c) 1991, 1993, 1994
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static char sccsid[] = "@(#)util.c	8.74 (Berkeley) 8/17/94";
36#endif /* not lint */
37
38#include <sys/types.h>
39#include <sys/queue.h>
40#include <sys/time.h>
41
42#include <bitstring.h>
43#include <limits.h>
44#include <signal.h>
45#include <stdio.h>
46#include <stdlib.h>
47#include <string.h>
48#include <termios.h>
49#include <unistd.h>
50
51#include "compat.h"
52#include <curses.h>
53#include <db.h>
54#include <regex.h>
55
56#include "vi.h"
57
58/*
59 * binc --
60 *	Increase the size of a buffer.
61 */
62void *
63binc(sp, bp, bsizep, min)
64	SCR *sp;			/* sp MAY BE NULL!!! */
65	void *bp;
66	size_t *bsizep, min;
67{
68	size_t csize;
69
70	/* If already larger than the minimum, just return. */
71	if (min && *bsizep >= min)
72		return (bp);
73
74	csize = *bsizep + MAX(min, 256);
75	REALLOC(sp, bp, void *, csize);
76
77	if (bp == NULL) {
78		/*
79		 * Theoretically, realloc is supposed to leave any already
80		 * held memory alone if it can't get more.  Don't trust it.
81		 */
82		*bsizep = 0;
83		return (NULL);
84	}
85	/*
86	 * Memory is guaranteed to be zero-filled, various parts of
87	 * nvi depend on this.
88	 */
89	memset((char *)bp + *bsizep, 0, csize - *bsizep);
90	*bsizep = csize;
91	return (bp);
92}
93
94/*
95 * nonblank --
96 *	Set the column number of the first non-blank character
97 *	including or after the starting column.  On error, set
98 *	the column to 0, it's safest.
99 */
100int
101nonblank(sp, ep, lno, cnop)
102	SCR *sp;
103	EXF *ep;
104	recno_t lno;
105	size_t *cnop;
106{
107	char *p;
108	size_t cnt, len, off;
109
110	/* Default. */
111	off = *cnop;
112	*cnop = 0;
113
114	/* Get the line. */
115	if ((p = file_gline(sp, ep, lno, &len)) == NULL) {
116		if (file_lline(sp, ep, &lno))
117			return (1);
118		if (lno == 0)
119			return (0);
120		GETLINE_ERR(sp, lno);
121		return (1);
122	}
123
124	/* Set the offset. */
125	if (len == 0 || off >= len)
126		return (0);
127
128	for (cnt = off, p = &p[off],
129	    len -= off; len && isblank(*p); ++cnt, ++p, --len);
130
131	/* Set the return. */
132	*cnop = len ? cnt : cnt - 1;
133	return (0);
134}
135
136/*
137 * tail --
138 *	Return tail of a path.
139 */
140char *
141tail(path)
142	char *path;
143{
144	char *p;
145
146	if ((p = strrchr(path, '/')) == NULL)
147		return (path);
148	return (p + 1);
149}
150
151/*
152 * set_alt_name --
153 *	Set the alternate file name.
154 *
155 * Swap the alternate file name.  It's a routine because I wanted some place
156 * to hang this comment.  The alternate file name (normally referenced using
157 * the special character '#' during file expansion) is set by many
158 * operations.  In the historic vi, the commands "ex", and "edit" obviously
159 * set the alternate file name because they switched the underlying file.
160 * Less obviously, the "read", "file", "write" and "wq" commands set it as
161 * well.  In this implementation, some new commands have been added to the
162 * list.  Where it gets interesting is that the alternate file name is set
163 * multiple times by some commands.  If an edit attempt fails (for whatever
164 * reason, like the current file is modified but as yet unwritten), it is
165 * set to the file name that the user was unable to edit.  If the edit
166 * succeeds, it is set to the last file name that was edited.  Good fun.
167 *
168 * If the user edits a temporary file, there are time when there isn't an
169 * alternative file name.  A name argument of NULL turns it off.
170 */
171void
172set_alt_name(sp, name)
173	SCR *sp;
174	char *name;
175{
176	if (sp->alt_name != NULL)
177		free(sp->alt_name);
178	if (name == NULL)
179		sp->alt_name = NULL;
180	else if ((sp->alt_name = strdup(name)) == NULL)
181		msgq(sp, M_SYSERR, NULL);
182}
183
184/*
185 * v_strdup --
186 *	Strdup for wide character strings with an associated length.
187 */
188CHAR_T *
189v_strdup(sp, str, len)
190	SCR *sp;
191	CHAR_T *str;
192	size_t len;
193{
194	CHAR_T *copy;
195
196	MALLOC(sp, copy, CHAR_T *, len + 1);
197	if (copy == NULL)
198		return (NULL);
199	memmove(copy, str, len * sizeof(CHAR_T));
200	copy[len] = '\0';
201	return (copy);
202}
203
204/*
205 * vi_putchar --
206 *	Functional version of putchar, for tputs.
207 */
208void
209vi_putchar(ch)
210	int ch;
211{
212	(void)putchar(ch);
213}
214