kernel - TMPFS - Stabilization pass, fix accounting for rmdir
[dragonfly.git] / contrib / nvi / common / api.c
blob35d9f0c8f66e6c71cc02874da53c66fa0368c134
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.
9 * See the LICENSE file for redistribution information.
12 #include "config.h"
14 #ifndef lint
15 static const char sccsid[] = "@(#)api.c 8.26 (Berkeley) 10/14/96";
16 #endif /* not lint */
18 #include <sys/types.h>
19 #include <sys/queue.h>
20 #include <sys/time.h>
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>
30 #include "../common/common.h"
32 extern GS *__global_list; /* XXX */
35 * api_fscreen --
36 * Return a pointer to the screen specified by the screen id
37 * or a file name.
39 * PUBLIC: SCR *api_fscreen __P((int, char *));
41 SCR *
42 api_fscreen(id, name)
43 int id;
44 char *name;
46 GS *gp;
47 SCR *tsp;
49 gp = __global_list;
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);
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);
72 * api_aline --
73 * Append a line.
75 * PUBLIC: int api_aline __P((SCR *, recno_t, char *, size_t));
77 int
78 api_aline(sp, lno, line, len)
79 SCR *sp;
80 recno_t lno;
81 char *line;
82 size_t len;
84 return (db_append(sp, 1, lno, line, len));
88 * api_dline --
89 * Delete a line.
91 * PUBLIC: int api_dline __P((SCR *, recno_t));
93 int
94 api_dline(sp, lno)
95 SCR *sp;
96 recno_t lno;
98 return (db_delete(sp, lno));
102 * api_gline --
103 * Get a line.
105 * PUBLIC: int api_gline __P((SCR *, recno_t, char **, size_t *));
108 api_gline(sp, lno, linepp, lenp)
109 SCR *sp;
110 recno_t lno;
111 char **linepp;
112 size_t *lenp;
114 int isempty;
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);
121 return (0);
125 * api_iline --
126 * Insert a line.
128 * PUBLIC: int api_iline __P((SCR *, recno_t, char *, size_t));
131 api_iline(sp, lno, line, len)
132 SCR *sp;
133 recno_t lno;
134 char *line;
135 size_t len;
137 return (db_insert(sp, lno, line, len));
141 * api_lline --
142 * Return the line number of the last line in the file.
144 * PUBLIC: int api_lline __P((SCR *, recno_t *));
147 api_lline(sp, lnop)
148 SCR *sp;
149 recno_t *lnop;
151 return (db_last(sp, lnop));
155 * api_sline --
156 * Set a line.
158 * PUBLIC: int api_sline __P((SCR *, recno_t, char *, size_t));
161 api_sline(sp, lno, line, len)
162 SCR *sp;
163 recno_t lno;
164 char *line;
165 size_t len;
167 return (db_set(sp, lno, line, len));
171 * api_getmark --
172 * Get the mark.
174 * PUBLIC: int api_getmark __P((SCR *, int, MARK *));
177 api_getmark(sp, markname, mp)
178 SCR *sp;
179 int markname;
180 MARK *mp;
182 return (mark_get(sp, (ARG_CHAR_T)markname, mp, M_ERR));
186 * api_setmark --
187 * Set the mark.
189 * PUBLIC: int api_setmark __P((SCR *, int, MARK *));
192 api_setmark(sp, markname, mp)
193 SCR *sp;
194 int markname;
195 MARK *mp;
197 return (mark_set(sp, (ARG_CHAR_T)markname, mp, 1));
201 * api_nextmark --
202 * Return the first mark if next not set, otherwise return the
203 * subsequent mark.
205 * PUBLIC: int api_nextmark __P((SCR *, int, char *));
208 api_nextmark(sp, next, namep)
209 SCR *sp;
210 int next;
211 char *namep;
213 LMARK *mp;
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;
222 if (mp == NULL)
223 return (1);
224 *namep = mp->name;
225 return (0);
229 * api_getcursor --
230 * Get the cursor.
232 * PUBLIC: int api_getcursor __P((SCR *, MARK *));
235 api_getcursor(sp, mp)
236 SCR *sp;
237 MARK *mp;
239 mp->lno = sp->lno;
240 mp->cno = sp->cno;
241 return (0);
245 * api_setcursor --
246 * Set the cursor.
248 * PUBLIC: int api_setcursor __P((SCR *, MARK *));
251 api_setcursor(sp, mp)
252 SCR *sp;
253 MARK *mp;
255 size_t len;
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);
264 /* Set the cursor. */
265 sp->lno = mp->lno;
266 sp->cno = mp->cno;
267 return (0);
271 * api_emessage --
272 * Print an error message.
274 * PUBLIC: void api_emessage __P((SCR *, char *));
276 void
277 api_emessage(sp, text)
278 SCR *sp;
279 char *text;
281 msgq(sp, M_ERR, "%s", text);
285 * api_imessage --
286 * Print an informational message.
288 * PUBLIC: void api_imessage __P((SCR *, char *));
290 void
291 api_imessage(sp, text)
292 SCR *sp;
293 char *text;
295 msgq(sp, M_INFO, "%s", text);
299 * api_edit
300 * Create a new screen and return its id
301 * or edit a new file in the current screen.
303 * PUBLIC: int api_edit __P((SCR *, char *, SCR **, int));
306 api_edit(sp, file, spp, newscreen)
307 SCR *sp;
308 char *file;
309 SCR **spp;
310 int newscreen;
312 ARGS *ap[2], a;
313 EXCMD cmd;
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);
329 * api_escreen
330 * End a screen.
332 * PUBLIC: int api_escreen __P((SCR *));
335 api_escreen(sp)
336 SCR *sp;
338 EXCMD cmd;
341 * XXX
342 * If the interpreter exits anything other than the current
343 * screen, vi isn't going to update everything correctly.
345 ex_cinit(&cmd, C_QUIT, 0, OOBLNO, OOBLNO, 0, NULL);
346 return (cmd.cmd->fn(sp, &cmd));
350 * api_swscreen --
351 * Switch to a new screen.
353 * PUBLIC: int api_swscreen __P((SCR *, SCR *));
356 api_swscreen(sp, new)
357 SCR *sp, *new;
360 * XXX
361 * If the interpreter switches from anything other than the
362 * current screen, vi isn't going to update everything correctly.
364 sp->nextdisp = new;
365 F_SET(sp, SC_SSWITCH);
367 return (0);
371 * api_map --
372 * Map a key.
374 * PUBLIC: int api_map __P((SCR *, char *, char *, size_t));
377 api_map(sp, name, map, len)
378 SCR *sp;
379 char *name, *map;
380 size_t len;
382 ARGS *ap[3], a, b;
383 EXCMD cmd;
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));
392 * api_unmap --
393 * Unmap a key.
395 * PUBLIC: int api_unmap __P((SCR *, char *));
397 int
398 api_unmap(sp, name)
399 SCR *sp;
400 char *name;
402 ARGS *ap[2], a;
403 EXCMD cmd;
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));
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.
416 * PUBLIC: int api_opts_get __P((SCR *, char *, char **, int *));
419 api_opts_get(sp, name, value, boolvalue)
420 SCR *sp;
421 char *name, **value;
422 int *boolvalue;
424 OPTLIST const *op;
425 int offset;
427 if ((op = opts_search(name)) == NULL) {
428 opts_nomatch(sp, name);
429 return (1);
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));
457 break;
459 return (0);
463 * api_opts_set --
464 * Set options.
466 * PUBLIC: int api_opts_set __P((SCR *, char *, char *, u_long, int));
469 api_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;
475 ARGS *ap[2], a, b;
476 OPTLIST const *op;
477 int rval;
478 size_t blen;
479 char *bp;
481 if ((op = opts_search(name)) == NULL) {
482 opts_nomatch(sp, name);
483 return (1);
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;
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);
508 FREE_SPACE(sp, bp, blen);
510 return (rval);
514 * api_run_str --
515 * Execute a string as an ex command.
517 * PUBLIC: int api_run_str __P((SCR *, char *));
519 int
520 api_run_str(sp, cmd)
521 SCR *sp;
522 char *cmd;
524 return (ex_run_str(sp, NULL, cmd, strlen(cmd), 0, 0));