source: trunk/third/nvi/common/api.c @ 14302

Revision 14302, 9.0 KB checked in by ghudson, 25 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r14301, which included commits to RCS files with non-trunk default branches.
Line 
1/*-
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.
6 * Copyright (c) 1995
7 *      George V. Neville-Neil. All rights reserved.
8 *
9 * See the LICENSE file for redistribution information.
10 */
11
12#include "config.h"
13
14#ifndef lint
15static const char sccsid[] = "@(#)api.c 8.26 (Berkeley) 10/14/96";
16#endif /* not lint */
17
18#include <sys/types.h>
19#include <sys/queue.h>
20#include <sys/time.h>
21
22#include <bitstring.h>
23#include <limits.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <termios.h>
28#include <unistd.h>
29
30#include "../common/common.h"
31
32extern GS *__global_list;                       /* XXX */
33
34/*
35 * api_fscreen --
36 *      Return a pointer to the screen specified by the screen id
37 *      or a file name.
38 *
39 * PUBLIC: SCR *api_fscreen __P((int, char *));
40 */
41SCR *
42api_fscreen(id, name)
43        int id;
44        char *name;
45{
46        GS *gp;
47        SCR *tsp;
48
49        gp = __global_list;
50
51        /* Search the displayed list. */
52        for (tsp = gp->dq.cqh_first;
53            tsp != (void *)&gp->dq; tsp = tsp->q.cqe_next)
54                if (name == NULL) {
55                        if (id == tsp->id)
56                                return (tsp);
57                } else if (!strcmp(name, tsp->frp->name))
58                        return (tsp);
59
60        /* Search the hidden list. */
61        for (tsp = gp->hq.cqh_first;
62            tsp != (void *)&gp->hq; tsp = tsp->q.cqe_next)
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);
69}
70
71/*
72 * api_aline --
73 *      Append a line.
74 *
75 * PUBLIC: int api_aline __P((SCR *, recno_t, char *, size_t));
76 */
77int
78api_aline(sp, lno, line, len)
79        SCR *sp;
80        recno_t lno;
81        char *line;
82        size_t len;
83{
84        return (db_append(sp, 1, lno, line, len));
85}
86
87/*
88 * api_dline --
89 *      Delete a line.
90 *
91 * PUBLIC: int api_dline __P((SCR *, recno_t));
92 */
93int
94api_dline(sp, lno)
95        SCR *sp;
96        recno_t lno;
97{
98        return (db_delete(sp, lno));
99}
100
101/*
102 * api_gline --
103 *      Get a line.
104 *
105 * PUBLIC: int api_gline __P((SCR *, recno_t, char **, size_t *));
106 */
107int
108api_gline(sp, lno, linepp, lenp)
109        SCR *sp;
110        recno_t lno;
111        char **linepp;
112        size_t *lenp;
113{
114        int isempty;
115
116        if (db_eget(sp, lno, linepp, lenp, &isempty)) {
117                if (isempty)
118                        msgq(sp, M_ERR, "209|The file is empty");
119                return (1);
120        }
121        return (0);
122}
123
124/*
125 * api_iline --
126 *      Insert a line.
127 *
128 * PUBLIC: int api_iline __P((SCR *, recno_t, char *, size_t));
129 */
130int
131api_iline(sp, lno, line, len)
132        SCR *sp;
133        recno_t lno;
134        char *line;
135        size_t len;
136{
137        return (db_insert(sp, lno, line, len));
138}
139
140/*
141 * api_lline --
142 *      Return the line number of the last line in the file.
143 *
144 * PUBLIC: int api_lline __P((SCR *, recno_t *));
145 */
146int
147api_lline(sp, lnop)
148        SCR *sp;
149        recno_t *lnop;
150{
151        return (db_last(sp, lnop));
152}
153
154/*
155 * api_sline --
156 *      Set a line.
157 *
158 * PUBLIC: int api_sline __P((SCR *, recno_t, char *, size_t));
159 */
160int
161api_sline(sp, lno, line, len)
162        SCR *sp;
163        recno_t lno;
164        char *line;
165        size_t len;
166{
167        return (db_set(sp, lno, line, len));
168}
169
170/*
171 * api_getmark --
172 *      Get the mark.
173 *
174 * PUBLIC: int api_getmark __P((SCR *, int, MARK *));
175 */
176int
177api_getmark(sp, markname, mp)
178        SCR *sp;
179        int markname;
180        MARK *mp;
181{
182        return (mark_get(sp, (ARG_CHAR_T)markname, mp, M_ERR));
183}
184
185/*
186 * api_setmark --
187 *      Set the mark.
188 *
189 * PUBLIC: int api_setmark __P((SCR *, int, MARK *));
190 */
191int
192api_setmark(sp, markname, mp)
193        SCR *sp;
194        int markname;
195        MARK *mp;
196{
197        return (mark_set(sp, (ARG_CHAR_T)markname, mp, 1));
198}
199
200/*
201 * api_nextmark --
202 *      Return the first mark if next not set, otherwise return the
203 *      subsequent mark.
204 *
205 * PUBLIC: int api_nextmark __P((SCR *, int, char *));
206 */
207int
208api_nextmark(sp, next, namep)
209        SCR *sp;
210        int next;
211        char *namep;
212{
213        LMARK *mp;
214
215        mp = sp->ep->marks.lh_first;
216        if (next)
217                for (; mp != NULL; mp = mp->q.le_next)
218                        if (mp->name == *namep) {
219                                mp = mp->q.le_next;
220                                break;
221                        }
222        if (mp == NULL)
223                return (1);
224        *namep = mp->name;
225        return (0);
226}
227
228/*
229 * api_getcursor --
230 *      Get the cursor.
231 *
232 * PUBLIC: int api_getcursor __P((SCR *, MARK *));
233 */
234int
235api_getcursor(sp, mp)
236        SCR *sp;
237        MARK *mp;
238{
239        mp->lno = sp->lno;
240        mp->cno = sp->cno;
241        return (0);
242}
243
244/*
245 * api_setcursor --
246 *      Set the cursor.
247 *
248 * PUBLIC: int api_setcursor __P((SCR *, MARK *));
249 */
250int
251api_setcursor(sp, mp)
252        SCR *sp;
253        MARK *mp;
254{
255        size_t len;
256
257        if (db_get(sp, mp->lno, DBG_FATAL, NULL, &len))
258                return (1);
259        if (mp->cno < 0 || mp->cno > len) {
260                msgq(sp, M_ERR, "Cursor set to nonexistent column");
261                return (1);
262        }
263
264        /* Set the cursor. */
265        sp->lno = mp->lno;
266        sp->cno = mp->cno;
267        return (0);
268}
269
270/*
271 * api_emessage --
272 *      Print an error message.
273 *
274 * PUBLIC: void api_emessage __P((SCR *, char *));
275 */
276void
277api_emessage(sp, text)
278        SCR *sp;
279        char *text;
280{
281        msgq(sp, M_ERR, "%s", text);
282}
283
284/*
285 * api_imessage --
286 *      Print an informational message.
287 *
288 * PUBLIC: void api_imessage __P((SCR *, char *));
289 */
290void
291api_imessage(sp, text)
292        SCR *sp;
293        char *text;
294{
295        msgq(sp, M_INFO, "%s", text);
296}
297
298/*
299 * api_edit
300 *      Create a new screen and return its id
301 *      or edit a new file in the current screen.
302 *
303 * PUBLIC: int api_edit __P((SCR *, char *, SCR **, int));
304 */
305int
306api_edit(sp, file, spp, newscreen)
307        SCR *sp;
308        char *file;
309        SCR **spp;
310        int newscreen;
311{
312        ARGS *ap[2], a;
313        EXCMD cmd;
314
315        if (file) {
316                ex_cinit(&cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0, ap);
317                ex_cadd(&cmd, &a, file, strlen(file));
318        } else
319                ex_cinit(&cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0, NULL);
320        if (newscreen)
321                cmd.flags |= E_NEWSCREEN;               /* XXX */
322        if (cmd.cmd->fn(sp, &cmd))
323                return (1);
324        *spp = sp->nextdisp;
325        return (0);
326}
327
328/*
329 * api_escreen
330 *      End a screen.
331 *
332 * PUBLIC: int api_escreen __P((SCR *));
333 */
334int
335api_escreen(sp)
336        SCR *sp;
337{
338        EXCMD cmd;
339
340        /*
341         * XXX
342         * If the interpreter exits anything other than the current
343         * screen, vi isn't going to update everything correctly.
344         */
345        ex_cinit(&cmd, C_QUIT, 0, OOBLNO, OOBLNO, 0, NULL);
346        return (cmd.cmd->fn(sp, &cmd));
347}
348
349/*
350 * api_swscreen --
351 *    Switch to a new screen.
352 *
353 * PUBLIC: int api_swscreen __P((SCR *, SCR *));
354 */
355int
356api_swscreen(sp, new)
357      SCR *sp, *new;
358{
359        /*
360         * XXX
361         * If the interpreter switches from anything other than the
362         * current screen, vi isn't going to update everything correctly.
363         */
364        sp->nextdisp = new;
365        F_SET(sp, SC_SSWITCH);
366
367        return (0);
368}
369
370/*
371 * api_map --
372 *      Map a key.
373 *
374 * PUBLIC: int api_map __P((SCR *, char *, char *, size_t));
375 */
376int
377api_map(sp, name, map, len)
378        SCR *sp;
379        char *name, *map;
380        size_t len;
381{
382        ARGS *ap[3], a, b;
383        EXCMD cmd;
384
385        ex_cinit(&cmd, C_MAP, 0, OOBLNO, OOBLNO, 0, ap);
386        ex_cadd(&cmd, &a, name, strlen(name));
387        ex_cadd(&cmd, &b, map, len);
388        return (cmd.cmd->fn(sp, &cmd));
389}
390
391/*
392 * api_unmap --
393 *      Unmap a key.
394 *
395 * PUBLIC: int api_unmap __P((SCR *, char *));
396 */
397int
398api_unmap(sp, name)
399        SCR *sp;
400        char *name;
401{
402        ARGS *ap[2], a;
403        EXCMD cmd;
404
405        ex_cinit(&cmd, C_UNMAP, 0, OOBLNO, OOBLNO, 0, ap);
406        ex_cadd(&cmd, &a, name, strlen(name));
407        return (cmd.cmd->fn(sp, &cmd));
408}
409
410/*
411 * api_opts_get --
412 *      Return a option value as a string, in allocated memory.
413 *      If the option is of type boolean, boolvalue is (un)set
414 *      according to the value; otherwise boolvalue is -1.
415 *
416 * PUBLIC: int api_opts_get __P((SCR *, char *, char **, int *));
417 */
418int
419api_opts_get(sp, name, value, boolvalue)
420        SCR *sp;
421        char *name, **value;
422        int *boolvalue;
423{
424        OPTLIST const *op;
425        int offset;
426
427        if ((op = opts_search(name)) == NULL) {
428                opts_nomatch(sp, name);
429                return (1);
430        }
431
432        offset = op - optlist;
433        if (boolvalue != NULL)
434                *boolvalue = -1;
435        switch (op->type) {
436        case OPT_0BOOL:
437        case OPT_1BOOL:
438                MALLOC_RET(sp, *value, char *, strlen(op->name) + 2 + 1);
439                (void)sprintf(*value,
440                    "%s%s", O_ISSET(sp, offset) ? "" : "no", op->name);
441                if (boolvalue != NULL)
442                        *boolvalue = O_ISSET(sp, offset);
443                break;
444        case OPT_NUM:
445                MALLOC_RET(sp, *value, char *, 20);
446                (void)sprintf(*value, "%lu", (u_long)O_VAL(sp, offset));
447                break;
448        case OPT_STR:
449                if (O_STR(sp, offset) == NULL) {
450                        MALLOC_RET(sp, *value, char *, 2);
451                        value[0] = '\0';
452                } else {
453                        MALLOC_RET(sp,
454                            *value, char *, strlen(O_STR(sp, offset)) + 1);
455                        (void)sprintf(*value, "%s", O_STR(sp, offset));
456                }
457                break;
458        }
459        return (0);
460}
461
462/*
463 * api_opts_set --
464 *      Set options.
465 *
466 * PUBLIC: int api_opts_set __P((SCR *, char *, char *, u_long, int));
467 */
468int
469api_opts_set(sp, name, str_value, num_value, bool_value)
470        SCR *sp;
471        char *name, *str_value;
472        u_long num_value;
473        int bool_value;
474{
475        ARGS *ap[2], a, b;
476        OPTLIST const *op;
477        int rval;
478        size_t blen;
479        char *bp;
480
481        if ((op = opts_search(name)) == NULL) {
482                opts_nomatch(sp, name);
483                return (1);
484        }
485
486        switch (op->type) {
487        case OPT_0BOOL:
488        case OPT_1BOOL:
489                GET_SPACE_RET(sp, bp, blen, 64);
490                a.len = snprintf(bp, 64, "%s%s", bool_value ? "" : "no", name);
491                break;
492        case OPT_NUM:
493                GET_SPACE_RET(sp, bp, blen, 64);
494                a.len = snprintf(bp, 64, "%s=%lu", name, num_value);
495                break;
496        case OPT_STR:
497                GET_SPACE_RET(sp, bp, blen, 1024);
498                a.len = snprintf(bp, 1024, "%s=%s", name, str_value);
499                break;
500        }
501        a.bp = bp;
502        b.len = 0;
503        b.bp = NULL;
504        ap[0] = &a;
505        ap[1] = &b;
506        rval = opts_set(sp, ap, NULL);
507
508        FREE_SPACE(sp, bp, blen);
509
510        return (rval);
511}
512
513/*
514 * api_run_str --
515 *      Execute a string as an ex command.
516 *
517 * PUBLIC: int api_run_str __P((SCR *, char *));
518 */
519int     
520api_run_str(sp, cmd)
521        SCR *sp;
522        char *cmd;
523{
524        return (ex_run_str(sp, NULL, cmd, strlen(cmd), 0, 0));
525}
Note: See TracBrowser for help on using the repository browser.