1 /* $NetBSD: api.c,v 1.1.1.2 2008/05/18 14:29:40 aymeric Exp $ */
4 * Copyright (c) 1992, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 * Copyright (c) 1992, 1993, 1994, 1995, 1996
7 * Keith Bostic. All rights reserved.
9 * George V. Neville-Neil. All rights reserved.
11 * See the LICENSE file for redistribution information.
17 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";
20 #include <sys/types.h>
21 #include <sys/queue.h>
24 #include <bitstring.h>
32 #include "../common/common.h"
33 #include "../ex/tag.h"
35 extern GS
*__global_list
; /* XXX */
39 * Return a pointer to the screen specified by the screen id
42 * PUBLIC: SCR *api_fscreen __P((int, char *));
45 api_fscreen(int id
, char *name
)
53 /* Search the displayed lists. */
54 for (wp
= gp
->dq
.cqh_first
;
55 wp
!= (void *)&gp
->dq
; wp
= wp
->q
.cqe_next
)
56 for (tsp
= wp
->scrq
.cqh_first
;
57 tsp
!= (void *)&wp
->scrq
; tsp
= tsp
->q
.cqe_next
)
61 } else if (!strcmp(name
, tsp
->frp
->name
))
64 /* Search the hidden list. */
65 for (tsp
= gp
->hq
.cqh_first
;
66 tsp
!= (void *)&gp
->hq
; tsp
= tsp
->q
.cqe_next
)
70 } else if (!strcmp(name
, tsp
->frp
->name
))
79 * PUBLIC: int api_aline __P((SCR *, db_recno_t, char *, size_t));
82 api_aline(SCR
*sp
, db_recno_t lno
, char *line
, size_t len
)
87 CHAR2INT(sp
, line
, len
, wbp
, wblen
);
89 return (db_append(sp
, 1, lno
, wbp
, wblen
));
96 * PUBLIC: int api_extend __P((SCR *, db_recno_t));
99 api_extend(SCR
*sp
, db_recno_t lno
)
102 if (db_last(sp
, &lastlno
))
105 if (db_append(sp
, 1, lastlno
++, NULL
, 0))
114 * PUBLIC: int api_dline __P((SCR *, db_recno_t));
117 api_dline(SCR
*sp
, db_recno_t lno
)
119 if (db_delete(sp
, lno
))
121 /* change current line if deleted line is that one
122 * or one berfore that
124 if (sp
->lno
>= lno
&& sp
->lno
> 1)
133 * PUBLIC: int api_gline __P((SCR *, db_recno_t, CHAR_T **, size_t *));
136 api_gline(SCR
*sp
, db_recno_t lno
, CHAR_T
**linepp
, size_t *lenp
)
140 if (db_eget(sp
, lno
, linepp
, lenp
, &isempty
)) {
142 msgq(sp
, M_ERR
, "209|The file is empty");
152 * PUBLIC: int api_iline __P((SCR *, db_recno_t, CHAR_T *, size_t));
155 api_iline(SCR
*sp
, db_recno_t lno
, CHAR_T
*line
, size_t len
)
157 return (db_insert(sp
, lno
, line
, len
));
162 * Return the line number of the last line in the file.
164 * PUBLIC: int api_lline __P((SCR *, db_recno_t *));
167 api_lline(SCR
*sp
, db_recno_t
*lnop
)
169 return (db_last(sp
, lnop
));
176 * PUBLIC: int api_sline __P((SCR *, db_recno_t, CHAR_T *, size_t));
179 api_sline(SCR
*sp
, db_recno_t lno
, CHAR_T
*line
, size_t len
)
181 return (db_set(sp
, lno
, line
, len
));
188 * PUBLIC: int api_getmark __P((SCR *, int, MARK *));
191 api_getmark(SCR
*sp
, int markname
, MARK
*mp
)
193 return (mark_get(sp
, (ARG_CHAR_T
)markname
, mp
, M_ERR
));
200 * PUBLIC: int api_setmark __P((SCR *, int, MARK *));
203 api_setmark(SCR
*sp
, int markname
, MARK
*mp
)
205 return (mark_set(sp
, (ARG_CHAR_T
)markname
, mp
, 1));
210 * Return the first mark if next not set, otherwise return the
213 * PUBLIC: int api_nextmark __P((SCR *, int, char *));
216 api_nextmark(SCR
*sp
, int next
, char *namep
)
220 mp
= sp
->ep
->marks
.lh_first
;
222 for (; mp
!= NULL
; mp
= mp
->q
.le_next
)
223 if (mp
->name
== *namep
) {
237 * PUBLIC: int api_getcursor __P((SCR *, MARK *));
240 api_getcursor(SCR
*sp
, MARK
*mp
)
251 * PUBLIC: int api_setcursor __P((SCR *, MARK *));
254 api_setcursor(SCR
*sp
, MARK
*mp
)
258 if (db_get(sp
, mp
->lno
, DBG_FATAL
, NULL
, &len
))
261 msgq(sp
, M_ERR
, "Cursor set to nonexistent column");
265 /* Set the cursor. */
273 * Print an error message.
275 * PUBLIC: void api_emessage __P((SCR *, char *));
278 api_emessage(SCR
*sp
, char *text
)
280 msgq(sp
, M_ERR
, "%s", text
);
285 * Print an informational message.
287 * PUBLIC: void api_imessage __P((SCR *, char *));
290 api_imessage(SCR
*sp
, char *text
)
292 msgq(sp
, M_INFO
, "%s", text
);
297 * Create a new screen and return its id
298 * or edit a new file in the current screen.
300 * PUBLIC: int api_edit __P((SCR *, char *, SCR **, int));
303 api_edit(SCR
*sp
, char *file
, SCR
**spp
, int newscreen
)
310 ex_cinit(sp
, &cmd
, C_EDIT
, 0, OOBLNO
, OOBLNO
, 0);
311 CHAR2INT(sp
, file
, strlen(file
) + 1, wp
, wlen
);
312 argv_exp0(sp
, &cmd
, wp
, wlen
- 1 /* terminating 0 */);
314 ex_cinit(sp
, &cmd
, C_EDIT
, 0, OOBLNO
, OOBLNO
, 0);
316 cmd
.flags
|= E_NEWSCREEN
; /* XXX */
317 if (cmd
.cmd
->fn(sp
, &cmd
))
327 * PUBLIC: int api_escreen __P((SCR *));
336 * If the interpreter exits anything other than the current
337 * screen, vi isn't going to update everything correctly.
339 ex_cinit(sp
, &cmd
, C_QUIT
, 0, OOBLNO
, OOBLNO
, 0);
340 return (cmd
.cmd
->fn(sp
, &cmd
));
345 * Switch to a new screen.
347 * PUBLIC: int api_swscreen __P((SCR *, SCR *));
350 api_swscreen(SCR
*sp
, SCR
*new)
354 * If the interpreter switches from anything other than the
355 * current screen, vi isn't going to update everything correctly.
358 F_SET(sp
, SC_SSWITCH
);
367 * PUBLIC: int api_map __P((SCR *, char *, char *, size_t));
370 api_map(SCR
*sp
, char *name
, char *map
, size_t len
)
376 ex_cinit(sp
, &cmd
, C_MAP
, 0, OOBLNO
, OOBLNO
, 0);
377 CHAR2INT(sp
, name
, strlen(name
) + 1, wp
, wlen
);
378 argv_exp0(sp
, &cmd
, wp
, wlen
- 1);
379 CHAR2INT(sp
, map
, len
, wp
, wlen
);
380 argv_exp0(sp
, &cmd
, wp
, wlen
);
381 return (cmd
.cmd
->fn(sp
, &cmd
));
388 * PUBLIC: int api_unmap __P((SCR *, char *));
391 api_unmap(SCR
*sp
, char *name
)
397 ex_cinit(sp
, &cmd
, C_UNMAP
, 0, OOBLNO
, OOBLNO
, 0);
398 CHAR2INT(sp
, name
, strlen(name
) + 1, wp
, wlen
);
399 argv_exp0(sp
, &cmd
, wp
, wlen
- 1);
400 return (cmd
.cmd
->fn(sp
, &cmd
));
405 * Return a option value as a string, in allocated memory.
406 * If the option is of type boolean, boolvalue is (un)set
407 * according to the value; otherwise boolvalue is -1.
409 * PUBLIC: int api_opts_get __P((SCR *, CHAR_T *, char **, int *));
412 api_opts_get(SCR
*sp
, const CHAR_T
*name
, char **value
, int *boolvalue
)
417 if ((op
= opts_search(name
)) == NULL
) {
418 opts_nomatch(sp
, name
);
422 offset
= op
- optlist
;
423 if (boolvalue
!= NULL
)
428 MALLOC_RET(sp
, *value
, char *, STRLEN(op
->name
) + 2 + 1);
429 (void)sprintf(*value
,
430 "%s"WS
, O_ISSET(sp
, offset
) ? "" : "no", op
->name
);
431 if (boolvalue
!= NULL
)
432 *boolvalue
= O_ISSET(sp
, offset
);
435 MALLOC_RET(sp
, *value
, char *, 20);
436 (void)sprintf(*value
, "%lu", (u_long
)O_VAL(sp
, offset
));
439 if (O_STR(sp
, offset
) == NULL
) {
440 MALLOC_RET(sp
, *value
, char *, 2);
444 *value
, char *, strlen(O_STR(sp
, offset
)) + 1);
445 (void)sprintf(*value
, "%s", O_STR(sp
, offset
));
456 * PUBLIC: int api_opts_set __P((SCR *, CHAR_T *, char *, u_long, int));
459 api_opts_set(SCR
*sp
, const CHAR_T
*name
,
460 const char *str_value
, u_long num_value
, int bool_value
)
468 if ((op
= opts_search(name
)) == NULL
) {
469 opts_nomatch(sp
, name
);
476 GET_SPACE_RETW(sp
, bp
, blen
, 64);
477 a
.len
= SPRINTF(bp
, 64, L("%s"WS
), bool_value
? "" : "no", name
);
480 GET_SPACE_RETW(sp
, bp
, blen
, 64);
481 a
.len
= SPRINTF(bp
, 64, L(""WS
"=%lu"), name
, num_value
);
484 GET_SPACE_RETW(sp
, bp
, blen
, 1024);
485 a
.len
= SPRINTF(bp
, 1024, L(""WS
"=%s"), name
, str_value
);
497 rval
= opts_set(sp
, ap
, NULL
);
499 FREE_SPACEW(sp
, bp
, blen
);
506 * Execute a string as an ex command.
508 * PUBLIC: int api_run_str __P((SCR *, char *));
511 api_run_str(SCR
*sp
, char *cmd
)
516 CHAR2INT(sp
, cmd
, strlen(cmd
)+1, wp
, wlen
);
517 return (ex_run_str(sp
, NULL
, wp
, wlen
- 1, 0, 0));
521 * PUBLIC: TAGQ * api_tagq_new __P((SCR*, char*));
524 api_tagq_new(SCR
*sp
, char *tag
)
529 /* Allocate and initialize the tag queue structure. */
531 CALLOC_GOTO(sp
, tqp
, TAGQ
*, 1, sizeof(TAGQ
) + len
+ 1);
532 CIRCLEQ_INIT(&tqp
->tagq
);
534 memcpy(tqp
->tag
, tag
, (tqp
->tlen
= len
) + 1);
543 * PUBLIC: void api_tagq_add __P((SCR*, TAGQ*, char*, char *, char *));
546 api_tagq_add(SCR
*sp
, TAGQ
*tqp
, char *filename
, char *search
, char *msg
)
551 size_t flen
= strlen(filename
);
552 size_t slen
= strlen(search
);
553 size_t mlen
= strlen(msg
);
555 CALLOC_GOTO(sp
, tp
, TAG
*, 1,
556 sizeof(TAG
) - 1 + flen
+ 1 +
557 (slen
+ 1 + mlen
+ 1) * sizeof(CHAR_T
));
558 tp
->fname
= (char *)tp
->buf
;
559 memcpy(tp
->fname
, filename
, flen
+ 1);
561 tp
->search
= (CHAR_T
*)((char *)tp
->fname
+ flen
+ 1);
562 CHAR2INT(sp
, search
, slen
+ 1, wp
, wlen
);
563 MEMCPYW(tp
->search
, wp
, wlen
);
565 tp
->msg
= tp
->search
+ slen
+ 1;
566 CHAR2INT(sp
, msg
, mlen
+ 1, wp
, wlen
);
567 MEMCPYW(tp
->msg
, wp
, wlen
);
569 CIRCLEQ_INSERT_TAIL(&tqp
->tagq
, tp
, q
);
576 * PUBLIC: int api_tagq_push __P((SCR*, TAGQ**));
579 api_tagq_push(SCR
*sp
, TAGQ
**tqpp
)
587 /* Check to see if we found anything. */
588 if (tqp
->tagq
.cqh_first
== (void *)&tqp
->tagq
) {
593 tqp
->current
= tqp
->tagq
.cqh_first
;
595 if (tagq_push(sp
, tqp
, 0, 0))
602 * PUBLIC: void api_tagq_free __P((SCR*, TAGQ*));
605 api_tagq_free(SCR
*sp
, TAGQ
*tqp
)