home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Spezial / SPEZIAL2_97.zip / SPEZIAL2_97.iso / ANWEND / EDITOR / NVI179B / NVI179B.ZIP / common / api.c next >
C/C++ Source or Header  |  1996-10-14  |  9KB  |  526 lines

  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
  15. static 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.  
  32. extern 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.  */
  41. SCR *
  42. api_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.  */
  77. int
  78. api_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.  */
  93. int
  94. api_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.  */
  107. int
  108. api_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.  */
  130. int
  131. api_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.  */
  146. int
  147. api_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.  */
  160. int
  161. api_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.  */
  176. int
  177. api_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.  */
  191. int
  192. api_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.  */
  207. int
  208. api_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.  */
  234. int
  235. api_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.  */
  250. int
  251. api_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.  */
  276. void
  277. api_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.  */
  290. void
  291. api_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.  */
  305. int
  306. api_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.  */
  334. int
  335. api_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.  */
  355. int
  356. api_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.  */
  376. int
  377. api_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.  */
  397. int 
  398. api_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.  */
  418. int
  419. api_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.  */
  468. 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;
  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.  */
  519. int     
  520. api_run_str(sp, cmd)
  521.     SCR *sp;
  522.     char *cmd;
  523. {
  524.     return (ex_run_str(sp, NULL, cmd, strlen(cmd), 0, 0));
  525. }
  526.