tools/llvm: Do not build with symbols
[minix3.git] / external / bsd / nvi / dist / common / api.c
blob18e4ebb0f6ed886d07413e40bb53f54fe54c4fa8
1 /* $NetBSD: api.c,v 1.3 2013/11/25 22:43:46 christos Exp $ */
2 /*-
3 * Copyright (c) 1992, 1993, 1994
4 * The Regents of the University of California. All rights reserved.
5 * Copyright (c) 1992, 1993, 1994, 1995, 1996
6 * Keith Bostic. All rights reserved.
7 * Copyright (c) 1995
8 * George V. Neville-Neil. All rights reserved.
10 * See the LICENSE file for redistribution information.
13 #include "config.h"
15 #ifndef lint
16 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 ";
17 #endif /* not lint */
19 #include <sys/types.h>
20 #include <sys/queue.h>
21 #include <sys/time.h>
23 #include <bitstring.h>
24 #include <limits.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <termios.h>
29 #include <unistd.h>
31 #include "../common/common.h"
32 #include "../ex/tag.h"
34 extern GS *__global_list; /* XXX */
37 * api_fscreen --
38 * Return a pointer to the screen specified by the screen id
39 * or a file name.
41 * PUBLIC: SCR *api_fscreen __P((int, char *));
43 SCR *
44 api_fscreen(int id, char *name)
46 GS *gp;
47 SCR *tsp;
48 WIN *wp;
50 gp = __global_list;
52 /* Search the displayed lists. */
53 TAILQ_FOREACH(wp, &gp->dq, q)
54 TAILQ_FOREACH(tsp, &wp->scrq, q)
55 if (name == NULL) {
56 if (id == tsp->id)
57 return (tsp);
58 } else if (!strcmp(name, tsp->frp->name))
59 return (tsp);
61 /* Search the hidden list. */
62 TAILQ_FOREACH (tsp, &gp->hq, q)
63 if (name == NULL) {
64 if (id == tsp->id)
65 return (tsp);
66 } else if (!strcmp(name, tsp->frp->name))
67 return (tsp);
68 return (NULL);
72 * api_aline --
73 * Append a line.
75 * PUBLIC: int api_aline __P((SCR *, db_recno_t, char *, size_t));
77 int
78 api_aline(SCR *sp, db_recno_t lno, char *line, size_t len)
80 size_t wblen;
81 const CHAR_T *wbp;
83 CHAR2INT(sp, line, len, wbp, wblen);
85 return (db_append(sp, 1, lno, wbp, wblen));
89 * api_extend --
90 * Extend file.
92 * PUBLIC: int api_extend __P((SCR *, db_recno_t));
94 int
95 api_extend(SCR *sp, db_recno_t lno)
97 db_recno_t lastlno;
98 if (db_last(sp, &lastlno))
99 return 1;
100 while(lastlno < lno)
101 if (db_append(sp, 1, lastlno++, NULL, 0))
102 return 1;
103 return 0;
107 * api_dline --
108 * Delete a line.
110 * PUBLIC: int api_dline __P((SCR *, db_recno_t));
113 api_dline(SCR *sp, db_recno_t lno)
115 if (db_delete(sp, lno))
116 return 1;
117 /* change current line if deleted line is that one
118 * or one berfore that
120 if (sp->lno >= lno && sp->lno > 1)
121 sp->lno--;
122 return 0;
126 * api_gline --
127 * Get a line.
129 * PUBLIC: int api_gline __P((SCR *, db_recno_t, CHAR_T **, size_t *));
132 api_gline(SCR *sp, db_recno_t lno, CHAR_T **linepp, size_t *lenp)
134 int isempty;
136 if (db_eget(sp, lno, linepp, lenp, &isempty)) {
137 if (isempty)
138 msgq(sp, M_ERR, "209|The file is empty");
139 return (1);
141 return (0);
145 * api_iline --
146 * Insert a line.
148 * PUBLIC: int api_iline __P((SCR *, db_recno_t, CHAR_T *, size_t));
151 api_iline(SCR *sp, db_recno_t lno, CHAR_T *line, size_t len)
153 return (db_insert(sp, lno, line, len));
157 * api_lline --
158 * Return the line number of the last line in the file.
160 * PUBLIC: int api_lline __P((SCR *, db_recno_t *));
163 api_lline(SCR *sp, db_recno_t *lnop)
165 return (db_last(sp, lnop));
169 * api_sline --
170 * Set a line.
172 * PUBLIC: int api_sline __P((SCR *, db_recno_t, CHAR_T *, size_t));
175 api_sline(SCR *sp, db_recno_t lno, CHAR_T *line, size_t len)
177 return (db_set(sp, lno, line, len));
181 * api_getmark --
182 * Get the mark.
184 * PUBLIC: int api_getmark __P((SCR *, int, MARK *));
187 api_getmark(SCR *sp, int markname, MARK *mp)
189 return (mark_get(sp, (ARG_CHAR_T)markname, mp, M_ERR));
193 * api_setmark --
194 * Set the mark.
196 * PUBLIC: int api_setmark __P((SCR *, int, MARK *));
199 api_setmark(SCR *sp, int markname, MARK *mp)
201 return (mark_set(sp, (ARG_CHAR_T)markname, mp, 1));
205 * api_nextmark --
206 * Return the first mark if next not set, otherwise return the
207 * subsequent mark.
209 * PUBLIC: int api_nextmark __P((SCR *, int, char *));
212 api_nextmark(SCR *sp, int next, char *namep)
214 LMARK *mp;
216 mp = LIST_FIRST(&sp->ep->marks);
217 if (next)
218 for (; mp != NULL; mp = LIST_NEXT(mp, q))
219 if (mp->name == *namep) {
220 mp = LIST_NEXT(mp, q);
221 break;
223 if (mp == NULL)
224 return (1);
225 *namep = mp->name;
226 return (0);
230 * api_getcursor --
231 * Get the cursor.
233 * PUBLIC: int api_getcursor __P((SCR *, MARK *));
236 api_getcursor(SCR *sp, MARK *mp)
238 mp->lno = sp->lno;
239 mp->cno = sp->cno;
240 return (0);
244 * api_setcursor --
245 * Set the cursor.
247 * PUBLIC: int api_setcursor __P((SCR *, MARK *));
250 api_setcursor(SCR *sp, MARK *mp)
252 size_t len;
254 if (db_get(sp, mp->lno, DBG_FATAL, NULL, &len))
255 return (1);
256 if (mp->cno > len) {
257 msgq(sp, M_ERR, "Cursor set to nonexistent column");
258 return (1);
261 /* Set the cursor. */
262 sp->lno = mp->lno;
263 sp->cno = mp->cno;
264 return (0);
268 * api_emessage --
269 * Print an error message.
271 * PUBLIC: void api_emessage __P((SCR *, char *));
273 void
274 api_emessage(SCR *sp, char *text)
276 msgq(sp, M_ERR, "%s", text);
280 * api_imessage --
281 * Print an informational message.
283 * PUBLIC: void api_imessage __P((SCR *, char *));
285 void
286 api_imessage(SCR *sp, char *text)
288 msgq(sp, M_INFO, "%s", text);
292 * api_edit
293 * Create a new screen and return its id
294 * or edit a new file in the current screen.
296 * PUBLIC: int api_edit __P((SCR *, char *, SCR **, int));
299 api_edit(SCR *sp, char *file, SCR **spp, int newscreen)
301 EXCMD cmd;
302 size_t wlen;
303 const CHAR_T *wp;
305 if (file) {
306 ex_cinit(sp, &cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0);
307 CHAR2INT(sp, file, strlen(file) + 1, wp, wlen);
308 argv_exp0(sp, &cmd, wp, wlen - 1 /* terminating 0 */);
309 } else
310 ex_cinit(sp, &cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0);
311 if (newscreen)
312 cmd.flags |= E_NEWSCREEN; /* XXX */
313 if (cmd.cmd->fn(sp, &cmd))
314 return (1);
315 *spp = sp->nextdisp;
316 return (0);
320 * api_escreen
321 * End a screen.
323 * PUBLIC: int api_escreen __P((SCR *));
326 api_escreen(SCR *sp)
328 EXCMD cmd;
331 * XXX
332 * If the interpreter exits anything other than the current
333 * screen, vi isn't going to update everything correctly.
335 ex_cinit(sp, &cmd, C_QUIT, 0, OOBLNO, OOBLNO, 0);
336 return (cmd.cmd->fn(sp, &cmd));
340 * api_swscreen --
341 * Switch to a new screen.
343 * PUBLIC: int api_swscreen __P((SCR *, SCR *));
346 api_swscreen(SCR *sp, SCR *new)
349 * XXX
350 * If the interpreter switches from anything other than the
351 * current screen, vi isn't going to update everything correctly.
353 sp->nextdisp = new;
354 F_SET(sp, SC_SSWITCH);
356 return (0);
360 * api_map --
361 * Map a key.
363 * PUBLIC: int api_map __P((SCR *, char *, char *, size_t));
366 api_map(SCR *sp, char *name, char *map, size_t len)
368 EXCMD cmd;
369 size_t wlen;
370 const CHAR_T *wp;
372 ex_cinit(sp, &cmd, C_MAP, 0, OOBLNO, OOBLNO, 0);
373 CHAR2INT(sp, name, strlen(name) + 1, wp, wlen);
374 argv_exp0(sp, &cmd, wp, wlen - 1);
375 CHAR2INT(sp, map, len, wp, wlen);
376 argv_exp0(sp, &cmd, wp, wlen);
377 return (cmd.cmd->fn(sp, &cmd));
381 * api_unmap --
382 * Unmap a key.
384 * PUBLIC: int api_unmap __P((SCR *, char *));
386 int
387 api_unmap(SCR *sp, char *name)
389 EXCMD cmd;
390 size_t wlen;
391 const CHAR_T *wp;
393 ex_cinit(sp, &cmd, C_UNMAP, 0, OOBLNO, OOBLNO, 0);
394 CHAR2INT(sp, name, strlen(name) + 1, wp, wlen);
395 argv_exp0(sp, &cmd, wp, wlen - 1);
396 return (cmd.cmd->fn(sp, &cmd));
400 * api_opts_get --
401 * Return a option value as a string, in allocated memory.
402 * If the option is of type boolean, boolvalue is (un)set
403 * according to the value; otherwise boolvalue is -1.
405 * PUBLIC: int api_opts_get __P((SCR *, const CHAR_T *, char **, int *));
408 api_opts_get(SCR *sp, const CHAR_T *name, char **value, int *boolvalue)
410 OPTLIST const *op;
411 int offset;
413 if ((op = opts_search(name)) == NULL) {
414 opts_nomatch(sp, name);
415 return (1);
418 offset = op - optlist;
419 if (boolvalue != NULL)
420 *boolvalue = -1;
421 switch (op->type) {
422 case OPT_0BOOL:
423 case OPT_1BOOL:
424 MALLOC_RET(sp, *value, char *, STRLEN(op->name) + 2 + 1);
425 (void)sprintf(*value,
426 "%s"WS, O_ISSET(sp, offset) ? "" : "no", op->name);
427 if (boolvalue != NULL)
428 *boolvalue = O_ISSET(sp, offset);
429 break;
430 case OPT_NUM:
431 MALLOC_RET(sp, *value, char *, 20);
432 (void)sprintf(*value, "%lu", (u_long)O_VAL(sp, offset));
433 break;
434 case OPT_STR:
435 if (O_STR(sp, offset) == NULL) {
436 MALLOC_RET(sp, *value, char *, 2);
437 value[0][0] = '\0';
438 } else {
439 MALLOC_RET(sp,
440 *value, char *, strlen(O_STR(sp, offset)) + 1);
441 (void)sprintf(*value, "%s", O_STR(sp, offset));
443 break;
445 return (0);
449 * api_opts_set --
450 * Set options.
452 * PUBLIC: int api_opts_set __P((SCR *, const CHAR_T *, const char *, u_long, int));
455 api_opts_set(SCR *sp, const CHAR_T *name,
456 const char *str_value, u_long num_value, int bool_value)
458 ARGS *ap[2], a, b;
459 OPTLIST const *op;
460 int rval;
461 size_t blen;
462 CHAR_T *bp;
464 if ((op = opts_search(name)) == NULL) {
465 opts_nomatch(sp, name);
466 return (1);
469 switch (op->type) {
470 case OPT_0BOOL:
471 case OPT_1BOOL:
472 GET_SPACE_RETW(sp, bp, blen, 64);
473 a.len = SPRINTF(bp, 64, L("%s"WS), bool_value ? "" : "no", name);
474 break;
475 case OPT_NUM:
476 GET_SPACE_RETW(sp, bp, blen, 64);
477 a.len = SPRINTF(bp, 64, L(""WS"=%lu"), name, num_value);
478 break;
479 case OPT_STR:
480 GET_SPACE_RETW(sp, bp, blen, 1024);
481 a.len = SPRINTF(bp, 1024, L(""WS"=%s"), name, str_value);
482 break;
483 default:
484 bp = NULL;
485 break;
488 a.bp = bp;
489 b.len = 0;
490 b.bp = NULL;
491 ap[0] = &a;
492 ap[1] = &b;
493 rval = opts_set(sp, ap, NULL);
495 FREE_SPACEW(sp, bp, blen);
497 return (rval);
501 * api_run_str --
502 * Execute a string as an ex command.
504 * PUBLIC: int api_run_str __P((SCR *, char *));
506 int
507 api_run_str(SCR *sp, char *cmd)
509 size_t wlen;
510 const CHAR_T *wp;
512 CHAR2INT(sp, cmd, strlen(cmd)+1, wp, wlen);
513 return (ex_run_str(sp, NULL, wp, wlen - 1, 0, 0));
517 * PUBLIC: TAGQ * api_tagq_new __P((SCR*, char*));
519 TAGQ *
520 api_tagq_new(SCR *sp, char *tag)
522 TAGQ *tqp;
523 size_t len;
525 /* Allocate and initialize the tag queue structure. */
526 len = strlen(tag);
527 CALLOC_GOTO(sp, tqp, TAGQ *, 1, sizeof(TAGQ) + len + 1);
528 TAILQ_INIT(&tqp->tagq);
529 tqp->tag = tqp->buf;
530 memcpy(tqp->tag, tag, (tqp->tlen = len) + 1);
532 return tqp;
534 alloc_err:
535 return (NULL);
539 * PUBLIC: void api_tagq_add __P((SCR*, TAGQ*, char*, char *, char *));
541 void
542 api_tagq_add(SCR *sp, TAGQ *tqp, char *filename, char *search, char *msg)
544 TAG *tp;
545 const CHAR_T *wp;
546 size_t wlen;
547 size_t flen = strlen(filename);
548 size_t slen = strlen(search);
549 size_t mlen = strlen(msg);
551 CALLOC_GOTO(sp, tp, TAG *, 1,
552 sizeof(TAG) - 1 + flen + 1 +
553 (slen + 1 + mlen + 1) * sizeof(CHAR_T));
554 tp->fname = (char *)tp->buf;
555 memcpy(tp->fname, filename, flen + 1);
556 tp->fnlen = flen;
557 tp->search = (CHAR_T *)((char *)tp->fname + flen + 1);
558 CHAR2INT(sp, search, slen + 1, wp, wlen);
559 MEMCPYW(tp->search, wp, wlen);
560 tp->slen = slen;
561 tp->msg = tp->search + slen + 1;
562 CHAR2INT(sp, msg, mlen + 1, wp, wlen);
563 MEMCPYW(tp->msg, wp, wlen);
564 tp->mlen = mlen;
565 TAILQ_INSERT_TAIL(&tqp->tagq, tp, q);
567 alloc_err:
568 return;
572 * PUBLIC: int api_tagq_push __P((SCR*, TAGQ**));
575 api_tagq_push(SCR *sp, TAGQ **tqpp)
577 TAGQ *tqp;
579 tqp = *tqpp;
581 *tqpp = 0;
583 /* Check to see if we found anything. */
584 if (TAILQ_EMPTY(&tqp->tagq)) {
585 free(tqp);
586 return 0;
589 tqp->current = TAILQ_FIRST(&tqp->tagq);
591 if (tagq_push(sp, tqp, 0, 0))
592 return 1;
594 return (0);
598 * PUBLIC: void api_tagq_free __P((SCR*, TAGQ*));
600 void
601 api_tagq_free(SCR *sp, TAGQ *tqp)
603 if (tqp)
604 tagq_free(sp, tqp);