xref: /netbsd-src/external/bsd/nvi/dist/common/api.c (revision 2f698edb5c1cb2dcd9e762b0abb50c41dde8b6b7)
1*2f698edbSchristos /*	$NetBSD: api.c,v 1.4 2014/01/26 21:43:45 christos Exp $ */
2dbd550edSchristos /*-
3dbd550edSchristos  * Copyright (c) 1992, 1993, 1994
4dbd550edSchristos  *	The Regents of the University of California.  All rights reserved.
5dbd550edSchristos  * Copyright (c) 1992, 1993, 1994, 1995, 1996
6dbd550edSchristos  *	Keith Bostic.  All rights reserved.
7dbd550edSchristos  * Copyright (c) 1995
8dbd550edSchristos  *	George V. Neville-Neil. All rights reserved.
9dbd550edSchristos  *
10dbd550edSchristos  * See the LICENSE file for redistribution information.
11dbd550edSchristos  */
12dbd550edSchristos 
13dbd550edSchristos #include "config.h"
14dbd550edSchristos 
15*2f698edbSchristos #include <sys/cdefs.h>
16*2f698edbSchristos #if 0
17dbd550edSchristos #ifndef lint
18dbd550edSchristos static const char sccsid[] = "Id: api.c,v 8.40 2002/06/08 19:30:33 skimo Exp  (Berkeley) Date: 2002/06/08 19:30:33 ";
19dbd550edSchristos #endif /* not lint */
20*2f698edbSchristos #else
21*2f698edbSchristos __RCSID("$NetBSD: api.c,v 1.4 2014/01/26 21:43:45 christos Exp $");
22*2f698edbSchristos #endif
23dbd550edSchristos 
24dbd550edSchristos #include <sys/types.h>
25dbd550edSchristos #include <sys/queue.h>
26dbd550edSchristos #include <sys/time.h>
27dbd550edSchristos 
28dbd550edSchristos #include <bitstring.h>
29dbd550edSchristos #include <limits.h>
30dbd550edSchristos #include <stdio.h>
31dbd550edSchristos #include <stdlib.h>
32dbd550edSchristos #include <string.h>
33dbd550edSchristos #include <termios.h>
34dbd550edSchristos #include <unistd.h>
35dbd550edSchristos 
36dbd550edSchristos #include "../common/common.h"
37dbd550edSchristos #include "../ex/tag.h"
38dbd550edSchristos 
39dbd550edSchristos extern GS *__global_list;			/* XXX */
40dbd550edSchristos 
41dbd550edSchristos /*
42dbd550edSchristos  * api_fscreen --
43dbd550edSchristos  *	Return a pointer to the screen specified by the screen id
44dbd550edSchristos  *	or a file name.
45dbd550edSchristos  *
46dbd550edSchristos  * PUBLIC: SCR *api_fscreen __P((int, char *));
47dbd550edSchristos  */
48dbd550edSchristos SCR *
api_fscreen(int id,char * name)49dbd550edSchristos api_fscreen(int id, char *name)
50dbd550edSchristos {
51dbd550edSchristos 	GS *gp;
52dbd550edSchristos 	SCR *tsp;
53dbd550edSchristos 	WIN *wp;
54dbd550edSchristos 
55dbd550edSchristos 	gp = __global_list;
56dbd550edSchristos 
57dbd550edSchristos 	/* Search the displayed lists. */
58d89691f9Schristos 	TAILQ_FOREACH(wp, &gp->dq, q)
59d89691f9Schristos 		TAILQ_FOREACH(tsp, &wp->scrq, q)
60dbd550edSchristos 			if (name == NULL) {
61dbd550edSchristos 				if (id == tsp->id)
62dbd550edSchristos 					return (tsp);
63dbd550edSchristos 			} else if (!strcmp(name, tsp->frp->name))
64dbd550edSchristos 				return (tsp);
65dbd550edSchristos 
66dbd550edSchristos 	/* Search the hidden list. */
67d89691f9Schristos 	TAILQ_FOREACH (tsp,  &gp->hq, q)
68dbd550edSchristos 		if (name == NULL) {
69dbd550edSchristos 			if (id == tsp->id)
70dbd550edSchristos 				return (tsp);
71dbd550edSchristos 		} else if (!strcmp(name, tsp->frp->name))
72dbd550edSchristos 			return (tsp);
73dbd550edSchristos 	return (NULL);
74dbd550edSchristos }
75dbd550edSchristos 
76dbd550edSchristos /*
77dbd550edSchristos  * api_aline --
78dbd550edSchristos  *	Append a line.
79dbd550edSchristos  *
80dbd550edSchristos  * PUBLIC: int api_aline __P((SCR *, db_recno_t, char *, size_t));
81dbd550edSchristos  */
82dbd550edSchristos int
api_aline(SCR * sp,db_recno_t lno,char * line,size_t len)83dbd550edSchristos api_aline(SCR *sp, db_recno_t lno, char *line, size_t len)
84dbd550edSchristos {
85dbd550edSchristos 	size_t wblen;
868d01a27eSchristos 	const CHAR_T *wbp;
87dbd550edSchristos 
88dbd550edSchristos 	CHAR2INT(sp, line, len, wbp, wblen);
89dbd550edSchristos 
90dbd550edSchristos 	return (db_append(sp, 1, lno, wbp, wblen));
91dbd550edSchristos }
92dbd550edSchristos 
93dbd550edSchristos /*
94dbd550edSchristos  * api_extend --
95dbd550edSchristos  *	Extend file.
96dbd550edSchristos  *
97dbd550edSchristos  * PUBLIC: int api_extend __P((SCR *, db_recno_t));
98dbd550edSchristos  */
99dbd550edSchristos int
api_extend(SCR * sp,db_recno_t lno)100dbd550edSchristos api_extend(SCR *sp, db_recno_t lno)
101dbd550edSchristos {
102dbd550edSchristos 	db_recno_t lastlno;
103dbd550edSchristos 	if (db_last(sp, &lastlno))
104dbd550edSchristos 	    return 1;
105dbd550edSchristos 	while(lastlno < lno)
106dbd550edSchristos 	    if (db_append(sp, 1, lastlno++, NULL, 0))
107dbd550edSchristos 		return 1;
108dbd550edSchristos 	return 0;
109dbd550edSchristos }
110dbd550edSchristos 
111dbd550edSchristos /*
112dbd550edSchristos  * api_dline --
113dbd550edSchristos  *	Delete a line.
114dbd550edSchristos  *
115dbd550edSchristos  * PUBLIC: int api_dline __P((SCR *, db_recno_t));
116dbd550edSchristos  */
117dbd550edSchristos int
api_dline(SCR * sp,db_recno_t lno)118dbd550edSchristos api_dline(SCR *sp, db_recno_t lno)
119dbd550edSchristos {
120dbd550edSchristos 	if (db_delete(sp, lno))
121dbd550edSchristos 		return 1;
122dbd550edSchristos 	/* change current line if deleted line is that one
123dbd550edSchristos 	 * or one berfore that
124dbd550edSchristos 	 */
125dbd550edSchristos 	if (sp->lno >= lno && sp->lno > 1)
126dbd550edSchristos 		sp->lno--;
127dbd550edSchristos 	return 0;
128dbd550edSchristos }
129dbd550edSchristos 
130dbd550edSchristos /*
131dbd550edSchristos  * api_gline --
132dbd550edSchristos  *	Get a line.
133dbd550edSchristos  *
134dbd550edSchristos  * PUBLIC: int api_gline __P((SCR *, db_recno_t, CHAR_T **, size_t *));
135dbd550edSchristos  */
136dbd550edSchristos int
api_gline(SCR * sp,db_recno_t lno,CHAR_T ** linepp,size_t * lenp)137dbd550edSchristos api_gline(SCR *sp, db_recno_t lno, CHAR_T **linepp, size_t *lenp)
138dbd550edSchristos {
139dbd550edSchristos 	int isempty;
140dbd550edSchristos 
141dbd550edSchristos 	if (db_eget(sp, lno, linepp, lenp, &isempty)) {
142dbd550edSchristos 		if (isempty)
143dbd550edSchristos 			msgq(sp, M_ERR, "209|The file is empty");
144dbd550edSchristos 		return (1);
145dbd550edSchristos 	}
146dbd550edSchristos 	return (0);
147dbd550edSchristos }
148dbd550edSchristos 
149dbd550edSchristos /*
150dbd550edSchristos  * api_iline --
151dbd550edSchristos  *	Insert a line.
152dbd550edSchristos  *
153dbd550edSchristos  * PUBLIC: int api_iline __P((SCR *, db_recno_t, CHAR_T *, size_t));
154dbd550edSchristos  */
155dbd550edSchristos int
api_iline(SCR * sp,db_recno_t lno,CHAR_T * line,size_t len)156dbd550edSchristos api_iline(SCR *sp, db_recno_t lno, CHAR_T *line, size_t len)
157dbd550edSchristos {
158dbd550edSchristos 	return (db_insert(sp, lno, line, len));
159dbd550edSchristos }
160dbd550edSchristos 
161dbd550edSchristos /*
162dbd550edSchristos  * api_lline --
163dbd550edSchristos  *	Return the line number of the last line in the file.
164dbd550edSchristos  *
165dbd550edSchristos  * PUBLIC: int api_lline __P((SCR *, db_recno_t *));
166dbd550edSchristos  */
167dbd550edSchristos int
api_lline(SCR * sp,db_recno_t * lnop)168dbd550edSchristos api_lline(SCR *sp, db_recno_t *lnop)
169dbd550edSchristos {
170dbd550edSchristos 	return (db_last(sp, lnop));
171dbd550edSchristos }
172dbd550edSchristos 
173dbd550edSchristos /*
174dbd550edSchristos  * api_sline --
175dbd550edSchristos  *	Set a line.
176dbd550edSchristos  *
177dbd550edSchristos  * PUBLIC: int api_sline __P((SCR *, db_recno_t, CHAR_T *, size_t));
178dbd550edSchristos  */
179dbd550edSchristos int
api_sline(SCR * sp,db_recno_t lno,CHAR_T * line,size_t len)180dbd550edSchristos api_sline(SCR *sp, db_recno_t lno, CHAR_T *line, size_t len)
181dbd550edSchristos {
182dbd550edSchristos 	return (db_set(sp, lno, line, len));
183dbd550edSchristos }
184dbd550edSchristos 
185dbd550edSchristos /*
186dbd550edSchristos  * api_getmark --
187dbd550edSchristos  *	Get the mark.
188dbd550edSchristos  *
189dbd550edSchristos  * PUBLIC: int api_getmark __P((SCR *, int, MARK *));
190dbd550edSchristos  */
191dbd550edSchristos int
api_getmark(SCR * sp,int markname,MARK * mp)192dbd550edSchristos api_getmark(SCR *sp, int markname, MARK *mp)
193dbd550edSchristos {
194dbd550edSchristos 	return (mark_get(sp, (ARG_CHAR_T)markname, mp, M_ERR));
195dbd550edSchristos }
196dbd550edSchristos 
197dbd550edSchristos /*
198dbd550edSchristos  * api_setmark --
199dbd550edSchristos  *	Set the mark.
200dbd550edSchristos  *
201dbd550edSchristos  * PUBLIC: int api_setmark __P((SCR *, int, MARK *));
202dbd550edSchristos  */
203dbd550edSchristos int
api_setmark(SCR * sp,int markname,MARK * mp)204dbd550edSchristos api_setmark(SCR *sp, int markname, MARK *mp)
205dbd550edSchristos {
206dbd550edSchristos 	return (mark_set(sp, (ARG_CHAR_T)markname, mp, 1));
207dbd550edSchristos }
208dbd550edSchristos 
209dbd550edSchristos /*
210dbd550edSchristos  * api_nextmark --
211dbd550edSchristos  *	Return the first mark if next not set, otherwise return the
212dbd550edSchristos  *	subsequent mark.
213dbd550edSchristos  *
214dbd550edSchristos  * PUBLIC: int api_nextmark __P((SCR *, int, char *));
215dbd550edSchristos  */
216dbd550edSchristos int
api_nextmark(SCR * sp,int next,char * namep)217dbd550edSchristos api_nextmark(SCR *sp, int next, char *namep)
218dbd550edSchristos {
219dbd550edSchristos 	LMARK *mp;
220dbd550edSchristos 
221d89691f9Schristos 	mp = LIST_FIRST(&sp->ep->marks);
222dbd550edSchristos 	if (next)
223d89691f9Schristos 		for (; mp != NULL; mp = LIST_NEXT(mp, q))
224dbd550edSchristos 			if (mp->name == *namep) {
225d89691f9Schristos 				mp = LIST_NEXT(mp, q);
226dbd550edSchristos 				break;
227dbd550edSchristos 			}
228dbd550edSchristos 	if (mp == NULL)
229dbd550edSchristos 		return (1);
230dbd550edSchristos 	*namep = mp->name;
231dbd550edSchristos 	return (0);
232dbd550edSchristos }
233dbd550edSchristos 
234dbd550edSchristos /*
235dbd550edSchristos  * api_getcursor --
236dbd550edSchristos  *	Get the cursor.
237dbd550edSchristos  *
238dbd550edSchristos  * PUBLIC: int api_getcursor __P((SCR *, MARK *));
239dbd550edSchristos  */
240dbd550edSchristos int
api_getcursor(SCR * sp,MARK * mp)241dbd550edSchristos api_getcursor(SCR *sp, MARK *mp)
242dbd550edSchristos {
243dbd550edSchristos 	mp->lno = sp->lno;
244dbd550edSchristos 	mp->cno = sp->cno;
245dbd550edSchristos 	return (0);
246dbd550edSchristos }
247dbd550edSchristos 
248dbd550edSchristos /*
249dbd550edSchristos  * api_setcursor --
250dbd550edSchristos  *	Set the cursor.
251dbd550edSchristos  *
252dbd550edSchristos  * PUBLIC: int api_setcursor __P((SCR *, MARK *));
253dbd550edSchristos  */
254dbd550edSchristos int
api_setcursor(SCR * sp,MARK * mp)255dbd550edSchristos api_setcursor(SCR *sp, MARK *mp)
256dbd550edSchristos {
257dbd550edSchristos 	size_t len;
258dbd550edSchristos 
259dbd550edSchristos 	if (db_get(sp, mp->lno, DBG_FATAL, NULL, &len))
260dbd550edSchristos 		return (1);
2618d01a27eSchristos 	if (mp->cno > len) {
262dbd550edSchristos 		msgq(sp, M_ERR, "Cursor set to nonexistent column");
263dbd550edSchristos 		return (1);
264dbd550edSchristos 	}
265dbd550edSchristos 
266dbd550edSchristos 	/* Set the cursor. */
267dbd550edSchristos 	sp->lno = mp->lno;
268dbd550edSchristos 	sp->cno = mp->cno;
269dbd550edSchristos 	return (0);
270dbd550edSchristos }
271dbd550edSchristos 
272dbd550edSchristos /*
273dbd550edSchristos  * api_emessage --
274dbd550edSchristos  *	Print an error message.
275dbd550edSchristos  *
276dbd550edSchristos  * PUBLIC: void api_emessage __P((SCR *, char *));
277dbd550edSchristos  */
278dbd550edSchristos void
api_emessage(SCR * sp,char * text)279dbd550edSchristos api_emessage(SCR *sp, char *text)
280dbd550edSchristos {
281dbd550edSchristos 	msgq(sp, M_ERR, "%s", text);
282dbd550edSchristos }
283dbd550edSchristos 
284dbd550edSchristos /*
285dbd550edSchristos  * api_imessage --
286dbd550edSchristos  *	Print an informational message.
287dbd550edSchristos  *
288dbd550edSchristos  * PUBLIC: void api_imessage __P((SCR *, char *));
289dbd550edSchristos  */
290dbd550edSchristos void
api_imessage(SCR * sp,char * text)291dbd550edSchristos api_imessage(SCR *sp, char *text)
292dbd550edSchristos {
293dbd550edSchristos 	msgq(sp, M_INFO, "%s", text);
294dbd550edSchristos }
295dbd550edSchristos 
296dbd550edSchristos /*
297dbd550edSchristos  * api_edit
298dbd550edSchristos  *	Create a new screen and return its id
299dbd550edSchristos  *	or edit a new file in the current screen.
300dbd550edSchristos  *
301dbd550edSchristos  * PUBLIC: int api_edit __P((SCR *, char *, SCR **, int));
302dbd550edSchristos  */
303dbd550edSchristos int
api_edit(SCR * sp,char * file,SCR ** spp,int newscreen)304dbd550edSchristos api_edit(SCR *sp, char *file, SCR **spp, int newscreen)
305dbd550edSchristos {
306dbd550edSchristos 	EXCMD cmd;
307dbd550edSchristos 	size_t wlen;
3088d01a27eSchristos 	const CHAR_T *wp;
309dbd550edSchristos 
310dbd550edSchristos 	if (file) {
311dbd550edSchristos 		ex_cinit(sp, &cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0);
312dbd550edSchristos 		CHAR2INT(sp, file, strlen(file) + 1, wp, wlen);
313dbd550edSchristos 		argv_exp0(sp, &cmd, wp, wlen - 1 /* terminating 0 */);
314dbd550edSchristos 	} else
315dbd550edSchristos 		ex_cinit(sp, &cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0);
316dbd550edSchristos 	if (newscreen)
317dbd550edSchristos 		cmd.flags |= E_NEWSCREEN;		/* XXX */
318dbd550edSchristos 	if (cmd.cmd->fn(sp, &cmd))
319dbd550edSchristos 		return (1);
320dbd550edSchristos 	*spp = sp->nextdisp;
321dbd550edSchristos 	return (0);
322dbd550edSchristos }
323dbd550edSchristos 
324dbd550edSchristos /*
325dbd550edSchristos  * api_escreen
326dbd550edSchristos  *	End a screen.
327dbd550edSchristos  *
328dbd550edSchristos  * PUBLIC: int api_escreen __P((SCR *));
329dbd550edSchristos  */
330dbd550edSchristos int
api_escreen(SCR * sp)331dbd550edSchristos api_escreen(SCR *sp)
332dbd550edSchristos {
333dbd550edSchristos 	EXCMD cmd;
334dbd550edSchristos 
335dbd550edSchristos 	/*
336dbd550edSchristos 	 * XXX
337dbd550edSchristos 	 * If the interpreter exits anything other than the current
338dbd550edSchristos 	 * screen, vi isn't going to update everything correctly.
339dbd550edSchristos 	 */
340dbd550edSchristos 	ex_cinit(sp, &cmd, C_QUIT, 0, OOBLNO, OOBLNO, 0);
341dbd550edSchristos 	return (cmd.cmd->fn(sp, &cmd));
342dbd550edSchristos }
343dbd550edSchristos 
344dbd550edSchristos /*
345dbd550edSchristos  * api_swscreen --
346dbd550edSchristos  *    Switch to a new screen.
347dbd550edSchristos  *
348dbd550edSchristos  * PUBLIC: int api_swscreen __P((SCR *, SCR *));
349dbd550edSchristos  */
350dbd550edSchristos int
api_swscreen(SCR * sp,SCR * new)351dbd550edSchristos api_swscreen(SCR *sp, SCR *new)
352dbd550edSchristos {
353dbd550edSchristos 	/*
354dbd550edSchristos 	 * XXX
355dbd550edSchristos 	 * If the interpreter switches from anything other than the
356dbd550edSchristos 	 * current screen, vi isn't going to update everything correctly.
357dbd550edSchristos 	 */
358dbd550edSchristos 	sp->nextdisp = new;
359dbd550edSchristos 	F_SET(sp, SC_SSWITCH);
360dbd550edSchristos 
361dbd550edSchristos 	return (0);
362dbd550edSchristos }
363dbd550edSchristos 
364dbd550edSchristos /*
365dbd550edSchristos  * api_map --
366dbd550edSchristos  *	Map a key.
367dbd550edSchristos  *
368dbd550edSchristos  * PUBLIC: int api_map __P((SCR *, char *, char *, size_t));
369dbd550edSchristos  */
370dbd550edSchristos int
api_map(SCR * sp,char * name,char * map,size_t len)371dbd550edSchristos api_map(SCR *sp, char *name, char *map, size_t len)
372dbd550edSchristos {
373dbd550edSchristos 	EXCMD cmd;
374dbd550edSchristos 	size_t wlen;
3758d01a27eSchristos 	const CHAR_T *wp;
376dbd550edSchristos 
377dbd550edSchristos 	ex_cinit(sp, &cmd, C_MAP, 0, OOBLNO, OOBLNO, 0);
378dbd550edSchristos 	CHAR2INT(sp, name, strlen(name) + 1, wp, wlen);
379dbd550edSchristos 	argv_exp0(sp, &cmd, wp, wlen - 1);
380dbd550edSchristos 	CHAR2INT(sp, map, len, wp, wlen);
381dbd550edSchristos 	argv_exp0(sp, &cmd, wp, wlen);
382dbd550edSchristos 	return (cmd.cmd->fn(sp, &cmd));
383dbd550edSchristos }
384dbd550edSchristos 
385dbd550edSchristos /*
386dbd550edSchristos  * api_unmap --
387dbd550edSchristos  *	Unmap a key.
388dbd550edSchristos  *
389dbd550edSchristos  * PUBLIC: int api_unmap __P((SCR *, char *));
390dbd550edSchristos  */
391dbd550edSchristos int
api_unmap(SCR * sp,char * name)392dbd550edSchristos api_unmap(SCR *sp, char *name)
393dbd550edSchristos {
394dbd550edSchristos 	EXCMD cmd;
395dbd550edSchristos 	size_t wlen;
3968d01a27eSchristos 	const CHAR_T *wp;
397dbd550edSchristos 
398dbd550edSchristos 	ex_cinit(sp, &cmd, C_UNMAP, 0, OOBLNO, OOBLNO, 0);
399dbd550edSchristos 	CHAR2INT(sp, name, strlen(name) + 1, wp, wlen);
400dbd550edSchristos 	argv_exp0(sp, &cmd, wp, wlen - 1);
401dbd550edSchristos 	return (cmd.cmd->fn(sp, &cmd));
402dbd550edSchristos }
403dbd550edSchristos 
404dbd550edSchristos /*
405dbd550edSchristos  * api_opts_get --
406dbd550edSchristos  *	Return a option value as a string, in allocated memory.
407dbd550edSchristos  *	If the option is of type boolean, boolvalue is (un)set
408dbd550edSchristos  *	according to the value; otherwise boolvalue is -1.
409dbd550edSchristos  *
4108d01a27eSchristos  * PUBLIC: int api_opts_get __P((SCR *, const CHAR_T *, char **, int *));
411dbd550edSchristos  */
412dbd550edSchristos int
api_opts_get(SCR * sp,const CHAR_T * name,char ** value,int * boolvalue)4138d01a27eSchristos api_opts_get(SCR *sp, const CHAR_T *name, char **value, int *boolvalue)
414dbd550edSchristos {
415dbd550edSchristos 	OPTLIST const *op;
416dbd550edSchristos 	int offset;
417dbd550edSchristos 
418dbd550edSchristos 	if ((op = opts_search(name)) == NULL) {
419dbd550edSchristos 		opts_nomatch(sp, name);
420dbd550edSchristos 		return (1);
421dbd550edSchristos 	}
422dbd550edSchristos 
423dbd550edSchristos 	offset = op - optlist;
424dbd550edSchristos 	if (boolvalue != NULL)
425dbd550edSchristos 		*boolvalue = -1;
426dbd550edSchristos 	switch (op->type) {
427dbd550edSchristos 	case OPT_0BOOL:
428dbd550edSchristos 	case OPT_1BOOL:
429dbd550edSchristos 		MALLOC_RET(sp, *value, char *, STRLEN(op->name) + 2 + 1);
430dbd550edSchristos 		(void)sprintf(*value,
431dbd550edSchristos 		    "%s"WS, O_ISSET(sp, offset) ? "" : "no", op->name);
432dbd550edSchristos 		if (boolvalue != NULL)
433dbd550edSchristos 			*boolvalue = O_ISSET(sp, offset);
434dbd550edSchristos 		break;
435dbd550edSchristos 	case OPT_NUM:
436dbd550edSchristos 		MALLOC_RET(sp, *value, char *, 20);
437dbd550edSchristos 		(void)sprintf(*value, "%lu", (u_long)O_VAL(sp, offset));
438dbd550edSchristos 		break;
439dbd550edSchristos 	case OPT_STR:
440dbd550edSchristos 		if (O_STR(sp, offset) == NULL) {
441dbd550edSchristos 			MALLOC_RET(sp, *value, char *, 2);
4428d01a27eSchristos 			value[0][0] = '\0';
443dbd550edSchristos 		} else {
444dbd550edSchristos 			MALLOC_RET(sp,
445dbd550edSchristos 			    *value, char *, strlen(O_STR(sp, offset)) + 1);
446dbd550edSchristos 			(void)sprintf(*value, "%s", O_STR(sp, offset));
447dbd550edSchristos 		}
448dbd550edSchristos 		break;
449dbd550edSchristos 	}
450dbd550edSchristos 	return (0);
451dbd550edSchristos }
452dbd550edSchristos 
453dbd550edSchristos /*
454dbd550edSchristos  * api_opts_set --
455dbd550edSchristos  *	Set options.
456dbd550edSchristos  *
4578d01a27eSchristos  * PUBLIC: int api_opts_set __P((SCR *, const CHAR_T *, const char *, u_long, int));
458dbd550edSchristos  */
459dbd550edSchristos int
api_opts_set(SCR * sp,const CHAR_T * name,const char * str_value,u_long num_value,int bool_value)4608d01a27eSchristos api_opts_set(SCR *sp, const CHAR_T *name,
4618d01a27eSchristos 	     const char *str_value, u_long num_value, int bool_value)
462dbd550edSchristos {
463dbd550edSchristos 	ARGS *ap[2], a, b;
464dbd550edSchristos 	OPTLIST const *op;
465dbd550edSchristos 	int rval;
466dbd550edSchristos 	size_t blen;
467dbd550edSchristos 	CHAR_T *bp;
468dbd550edSchristos 
469dbd550edSchristos 	if ((op = opts_search(name)) == NULL) {
470dbd550edSchristos 		opts_nomatch(sp, name);
471dbd550edSchristos 		return (1);
472dbd550edSchristos 	}
473dbd550edSchristos 
474dbd550edSchristos 	switch (op->type) {
475dbd550edSchristos 	case OPT_0BOOL:
476dbd550edSchristos 	case OPT_1BOOL:
477dbd550edSchristos 		GET_SPACE_RETW(sp, bp, blen, 64);
478dbd550edSchristos 		a.len = SPRINTF(bp, 64, L("%s"WS), bool_value ? "" : "no", name);
479dbd550edSchristos 		break;
480dbd550edSchristos 	case OPT_NUM:
481dbd550edSchristos 		GET_SPACE_RETW(sp, bp, blen, 64);
482dbd550edSchristos 		a.len = SPRINTF(bp, 64, L(""WS"=%lu"), name, num_value);
483dbd550edSchristos 		break;
484dbd550edSchristos 	case OPT_STR:
485dbd550edSchristos 		GET_SPACE_RETW(sp, bp, blen, 1024);
486dbd550edSchristos 		a.len = SPRINTF(bp, 1024, L(""WS"=%s"), name, str_value);
487dbd550edSchristos 		break;
488dbd550edSchristos 	default:
489dbd550edSchristos 		bp = NULL;
490dbd550edSchristos 		break;
491dbd550edSchristos 	}
492dbd550edSchristos 
493dbd550edSchristos 	a.bp = bp;
494dbd550edSchristos 	b.len = 0;
495dbd550edSchristos 	b.bp = NULL;
496dbd550edSchristos 	ap[0] = &a;
497dbd550edSchristos 	ap[1] = &b;
498dbd550edSchristos 	rval = opts_set(sp, ap, NULL);
499dbd550edSchristos 
500dbd550edSchristos 	FREE_SPACEW(sp, bp, blen);
501dbd550edSchristos 
502dbd550edSchristos 	return (rval);
503dbd550edSchristos }
504dbd550edSchristos 
505dbd550edSchristos /*
506dbd550edSchristos  * api_run_str --
507dbd550edSchristos  *      Execute a string as an ex command.
508dbd550edSchristos  *
509dbd550edSchristos  * PUBLIC: int api_run_str __P((SCR *, char *));
510dbd550edSchristos  */
511dbd550edSchristos int
api_run_str(SCR * sp,char * cmd)512dbd550edSchristos api_run_str(SCR *sp, char *cmd)
513dbd550edSchristos {
514dbd550edSchristos 	size_t wlen;
5158d01a27eSchristos 	const CHAR_T *wp;
516dbd550edSchristos 
517dbd550edSchristos 	CHAR2INT(sp, cmd, strlen(cmd)+1, wp, wlen);
518dbd550edSchristos 	return (ex_run_str(sp, NULL, wp, wlen - 1, 0, 0));
519dbd550edSchristos }
520dbd550edSchristos 
521dbd550edSchristos /*
522dbd550edSchristos  * PUBLIC: TAGQ * api_tagq_new __P((SCR*, char*));
523dbd550edSchristos  */
524dbd550edSchristos TAGQ *
api_tagq_new(SCR * sp,char * tag)525dbd550edSchristos api_tagq_new(SCR *sp, char *tag)
526dbd550edSchristos {
527dbd550edSchristos 	TAGQ *tqp;
528dbd550edSchristos 	size_t len;
529dbd550edSchristos 
530dbd550edSchristos 	/* Allocate and initialize the tag queue structure. */
531dbd550edSchristos 	len = strlen(tag);
532dbd550edSchristos 	CALLOC_GOTO(sp, tqp, TAGQ *, 1, sizeof(TAGQ) + len + 1);
533d89691f9Schristos 	TAILQ_INIT(&tqp->tagq);
534dbd550edSchristos 	tqp->tag = tqp->buf;
535dbd550edSchristos 	memcpy(tqp->tag, tag, (tqp->tlen = len) + 1);
536dbd550edSchristos 
537dbd550edSchristos 	return tqp;
538dbd550edSchristos 
539dbd550edSchristos alloc_err:
540dbd550edSchristos 	return (NULL);
541dbd550edSchristos }
542dbd550edSchristos 
543dbd550edSchristos /*
544dbd550edSchristos  * PUBLIC: void api_tagq_add __P((SCR*, TAGQ*, char*, char *, char *));
545dbd550edSchristos  */
546dbd550edSchristos void
api_tagq_add(SCR * sp,TAGQ * tqp,char * filename,char * search,char * msg)547dbd550edSchristos api_tagq_add(SCR *sp, TAGQ *tqp, char *filename, char *search, char *msg)
548dbd550edSchristos {
549dbd550edSchristos 	TAG *tp;
5508d01a27eSchristos 	const CHAR_T *wp;
551dbd550edSchristos 	size_t wlen;
552dbd550edSchristos 	size_t flen = strlen(filename);
553dbd550edSchristos 	size_t slen = strlen(search);
554dbd550edSchristos 	size_t mlen = strlen(msg);
555dbd550edSchristos 
556dbd550edSchristos 	CALLOC_GOTO(sp, tp, TAG *, 1,
557dbd550edSchristos 		    sizeof(TAG) - 1 + flen + 1 +
558dbd550edSchristos 		    (slen + 1 + mlen + 1) * sizeof(CHAR_T));
559dbd550edSchristos 	tp->fname = (char *)tp->buf;
560dbd550edSchristos 	memcpy(tp->fname, filename, flen + 1);
561dbd550edSchristos 	tp->fnlen = flen;
562dbd550edSchristos 	tp->search = (CHAR_T *)((char *)tp->fname + flen + 1);
563dbd550edSchristos 	CHAR2INT(sp, search, slen + 1, wp, wlen);
564dbd550edSchristos 	MEMCPYW(tp->search, wp, wlen);
565dbd550edSchristos 	tp->slen = slen;
566dbd550edSchristos 	tp->msg = tp->search + slen + 1;
567dbd550edSchristos 	CHAR2INT(sp, msg, mlen + 1, wp, wlen);
568dbd550edSchristos 	MEMCPYW(tp->msg, wp, wlen);
569dbd550edSchristos 	tp->mlen = mlen;
570d89691f9Schristos 	TAILQ_INSERT_TAIL(&tqp->tagq, tp, q);
571dbd550edSchristos 
572dbd550edSchristos alloc_err:
573dbd550edSchristos 	return;
574dbd550edSchristos }
575dbd550edSchristos 
576dbd550edSchristos /*
577dbd550edSchristos  * PUBLIC: int api_tagq_push __P((SCR*, TAGQ**));
578dbd550edSchristos  */
579dbd550edSchristos int
api_tagq_push(SCR * sp,TAGQ ** tqpp)580dbd550edSchristos api_tagq_push(SCR *sp, TAGQ **tqpp)
581dbd550edSchristos {
582dbd550edSchristos 	TAGQ *tqp;
583dbd550edSchristos 
584dbd550edSchristos 	tqp = *tqpp;
585dbd550edSchristos 
586dbd550edSchristos 	*tqpp = 0;
587dbd550edSchristos 
588dbd550edSchristos 	/* Check to see if we found anything. */
589d89691f9Schristos 	if (TAILQ_EMPTY(&tqp->tagq)) {
590dbd550edSchristos 		free(tqp);
591dbd550edSchristos 		return 0;
592dbd550edSchristos 	}
593dbd550edSchristos 
594d89691f9Schristos 	tqp->current = TAILQ_FIRST(&tqp->tagq);
595dbd550edSchristos 
596dbd550edSchristos 	if (tagq_push(sp, tqp, 0, 0))
597dbd550edSchristos 		return 1;
598dbd550edSchristos 
599dbd550edSchristos 	return (0);
600dbd550edSchristos }
601dbd550edSchristos 
602dbd550edSchristos /*
603dbd550edSchristos  * PUBLIC: void api_tagq_free __P((SCR*, TAGQ*));
604dbd550edSchristos  */
605dbd550edSchristos void
api_tagq_free(SCR * sp,TAGQ * tqp)606dbd550edSchristos api_tagq_free(SCR *sp, TAGQ *tqp)
607dbd550edSchristos {
608dbd550edSchristos 	if (tqp)
609dbd550edSchristos 		tagq_free(sp, tqp);
610dbd550edSchristos }
611