2 * Copyright (c) 1992, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1992, 1993, 1994, 1995, 1996
5 * Keith Bostic. All rights reserved.
7 * George V. Neville-Neil. All rights reserved.
9 * See the LICENSE file for redistribution information.
15 static const char sccsid
[] = "$Id: api.c,v 8.30 2000/06/25 17:34:37 skimo Exp $ (Berkeley) $Date: 2000/06/25 17:34:37 $";
18 #include <sys/types.h>
19 #include <sys/queue.h>
22 #include <bitstring.h>
30 #include "../common/common.h"
31 #include "../ex/tag.h"
33 extern GS
*__global_list
; /* XXX */
37 * Return a pointer to the screen specified by the screen id
40 * PUBLIC: SCR *api_fscreen __P((int, char *));
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(sp
, lno
, line
, len
)
88 return (db_append(sp
, 1, lno
, line
, len
));
95 * PUBLIC: int api_extend __P((SCR *, db_recno_t));
103 if (db_last(sp
, &lastlno
))
106 if (db_append(sp
, 1, lastlno
++, "", 0))
115 * PUBLIC: int api_dline __P((SCR *, db_recno_t));
122 if (db_delete(sp
, lno
))
124 /* change current line if deleted line is that one
125 * or one berfore that
127 if (sp
->lno
>= lno
&& sp
->lno
> 1)
136 * PUBLIC: int api_gline __P((SCR *, db_recno_t, CHAR_T **, size_t *));
139 api_gline(sp
, lno
, linepp
, lenp
)
147 if (db_eget(sp
, lno
, linepp
, lenp
, &isempty
)) {
149 msgq(sp
, M_ERR
, "209|The file is empty");
159 * PUBLIC: int api_iline __P((SCR *, db_recno_t, char *, size_t));
162 api_iline(sp
, lno
, line
, len
)
168 return (db_insert(sp
, lno
, line
, len
));
173 * Return the line number of the last line in the file.
175 * PUBLIC: int api_lline __P((SCR *, db_recno_t *));
182 return (db_last(sp
, lnop
));
189 * PUBLIC: int api_sline __P((SCR *, db_recno_t, char *, size_t));
192 api_sline(sp
, lno
, line
, len
)
198 return (db_set(sp
, lno
, line
, len
));
205 * PUBLIC: int api_getmark __P((SCR *, int, MARK *));
208 api_getmark(sp
, markname
, mp
)
213 return (mark_get(sp
, (ARG_CHAR_T
)markname
, mp
, M_ERR
));
220 * PUBLIC: int api_setmark __P((SCR *, int, MARK *));
223 api_setmark(sp
, markname
, mp
)
228 return (mark_set(sp
, (ARG_CHAR_T
)markname
, mp
, 1));
233 * Return the first mark if next not set, otherwise return the
236 * PUBLIC: int api_nextmark __P((SCR *, int, char *));
239 api_nextmark(sp
, next
, namep
)
246 mp
= sp
->ep
->marks
.lh_first
;
248 for (; mp
!= NULL
; mp
= mp
->q
.le_next
)
249 if (mp
->name
== *namep
) {
263 * PUBLIC: int api_getcursor __P((SCR *, MARK *));
266 api_getcursor(sp
, mp
)
279 * PUBLIC: int api_setcursor __P((SCR *, MARK *));
282 api_setcursor(sp
, mp
)
288 if (db_get(sp
, mp
->lno
, DBG_FATAL
, NULL
, &len
))
290 if (mp
->cno
< 0 || mp
->cno
> len
) {
291 msgq(sp
, M_ERR
, "Cursor set to nonexistent column");
295 /* Set the cursor. */
303 * Print an error message.
305 * PUBLIC: void api_emessage __P((SCR *, char *));
308 api_emessage(sp
, text
)
312 msgq(sp
, M_ERR
, "%s", text
);
317 * Print an informational message.
319 * PUBLIC: void api_imessage __P((SCR *, char *));
322 api_imessage(sp
, text
)
326 msgq(sp
, M_INFO
, "%s", text
);
331 * Create a new screen and return its id
332 * or edit a new file in the current screen.
334 * PUBLIC: int api_edit __P((SCR *, char *, SCR **, int));
337 api_edit(sp
, file
, spp
, newscreen
)
346 ex_cinit(sp
, &cmd
, C_EDIT
, 0, OOBLNO
, OOBLNO
, 0);
347 argv_exp0(sp
, &cmd
, file
, strlen(file
));
349 ex_cinit(sp
, &cmd
, C_EDIT
, 0, OOBLNO
, OOBLNO
, 0);
351 cmd
.flags
|= E_NEWSCREEN
; /* XXX */
352 if (cmd
.cmd
->fn(sp
, &cmd
))
362 * PUBLIC: int api_escreen __P((SCR *));
372 * If the interpreter exits anything other than the current
373 * screen, vi isn't going to update everything correctly.
375 ex_cinit(sp
, &cmd
, C_QUIT
, 0, OOBLNO
, OOBLNO
, 0);
376 return (cmd
.cmd
->fn(sp
, &cmd
));
381 * Switch to a new screen.
383 * PUBLIC: int api_swscreen __P((SCR *, SCR *));
386 api_swscreen(sp
, new)
391 * If the interpreter switches from anything other than the
392 * current screen, vi isn't going to update everything correctly.
395 F_SET(sp
, SC_SSWITCH
);
404 * PUBLIC: int api_map __P((SCR *, char *, char *, size_t));
407 api_map(sp
, name
, map
, len
)
414 ex_cinit(sp
, &cmd
, C_MAP
, 0, OOBLNO
, OOBLNO
, 0);
415 argv_exp0(sp
, &cmd
, name
, strlen(name
));
416 argv_exp0(sp
, &cmd
, map
, len
);
417 return (cmd
.cmd
->fn(sp
, &cmd
));
424 * PUBLIC: int api_unmap __P((SCR *, char *));
433 ex_cinit(sp
, &cmd
, C_UNMAP
, 0, OOBLNO
, OOBLNO
, 0);
434 argv_exp0(sp
, &cmd
, name
, strlen(name
));
435 return (cmd
.cmd
->fn(sp
, &cmd
));
440 * Return a option value as a string, in allocated memory.
441 * If the option is of type boolean, boolvalue is (un)set
442 * according to the value; otherwise boolvalue is -1.
444 * PUBLIC: int api_opts_get __P((SCR *, char *, char **, int *));
447 api_opts_get(sp
, name
, value
, boolvalue
)
455 if ((op
= opts_search(name
)) == NULL
) {
456 opts_nomatch(sp
, name
);
460 offset
= op
- optlist
;
461 if (boolvalue
!= NULL
)
466 MALLOC_RET(sp
, *value
, char *, strlen(op
->name
) + 2 + 1);
467 (void)sprintf(*value
,
468 "%s%s", O_ISSET(sp
, offset
) ? "" : "no", op
->name
);
469 if (boolvalue
!= NULL
)
470 *boolvalue
= O_ISSET(sp
, offset
);
473 MALLOC_RET(sp
, *value
, char *, 20);
474 (void)sprintf(*value
, "%lu", (u_long
)O_VAL(sp
, offset
));
477 if (O_STR(sp
, offset
) == NULL
) {
478 MALLOC_RET(sp
, *value
, char *, 2);
482 *value
, char *, strlen(O_STR(sp
, offset
)) + 1);
483 (void)sprintf(*value
, "%s", O_STR(sp
, offset
));
494 * PUBLIC: int api_opts_set __P((SCR *, char *, char *, u_long, int));
497 api_opts_set(sp
, name
, str_value
, num_value
, bool_value
)
499 char *name
, *str_value
;
509 if ((op
= opts_search(name
)) == NULL
) {
510 opts_nomatch(sp
, name
);
517 GET_SPACE_RET(sp
, bp
, blen
, 64);
518 a
.len
= snprintf(bp
, 64, "%s%s", bool_value
? "" : "no", name
);
521 GET_SPACE_RET(sp
, bp
, blen
, 64);
522 a
.len
= snprintf(bp
, 64, "%s=%lu", name
, num_value
);
525 GET_SPACE_RET(sp
, bp
, blen
, 1024);
526 a
.len
= snprintf(bp
, 1024, "%s=%s", name
, str_value
);
534 rval
= opts_set(sp
, ap
, NULL
);
536 FREE_SPACE(sp
, bp
, blen
);
543 * Execute a string as an ex command.
545 * PUBLIC: int api_run_str __P((SCR *, char *));
552 return (ex_run_str(sp
, NULL
, cmd
, strlen(cmd
), 0, 0));
556 * PUBLIC: TAGQ * api_tagq_new __P((SCR*, char*));
559 api_tagq_new(sp
, tag
)
566 /* Allocate and initialize the tag queue structure. */
568 CALLOC_GOTO(sp
, tqp
, TAGQ
*, 1, sizeof(TAGQ
) + len
+ 1);
569 CIRCLEQ_INIT(&tqp
->tagq
);
571 memcpy(tqp
->tag
, tag
, (tqp
->tlen
= len
) + 1);
580 * PUBLIC: void api_tagq_add __P((SCR*, TAGQ*, char*, char *, char *));
583 api_tagq_add(sp
, tqp
, filename
, search
, msg
)
586 char *filename
, *search
, *msg
;
589 size_t flen
= strlen(filename
);
590 size_t slen
= strlen(search
);
592 CALLOC_GOTO(sp
, tp
, TAG
*, 1, sizeof(TAG
) - 1 + flen
+ 1 + slen
+ 1);
594 memcpy(tp
->fname
, filename
, flen
+ 1);
596 tp
->search
= tp
->fname
+ flen
+ 1;
597 memcpy(tp
->search
, search
, slen
+ 1);
599 CIRCLEQ_INSERT_TAIL(&tqp
->tagq
, tp
, q
);
606 * PUBLIC: int api_tagq_push __P((SCR*, TAGQ**));
609 api_tagq_push(sp
, tqpp
)
623 /* Check to see if we found anything. */
624 if (tqp
->tagq
.cqh_first
== (void *)&tqp
->tagq
) {
629 tqp
->current
= tqp
->tagq
.cqh_first
;
631 if (tagq_push(sp
, tqp
, 0, 0))
638 * PUBLIC: void api_tagq_free __P((SCR*, TAGQ*));
641 api_tagq_free(sp
, tqp
)