home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / gnu / src / amiga / ed-0.1-src.lha / ed-0.1 / glbl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-19  |  5.5 KB  |  230 lines

  1. /* glbl.c: This file contains the global command routines for the ed line
  2.    editor */
  3. /* ed line editor.
  4.    Copyright (C) 1993 Andrew Moore, Talke Studio
  5.    All Rights Reserved
  6.  
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 2, or (at your option)
  10.    any later version.
  11.  
  12.    This program is distributed in the hope that it will be useful, but
  13.    WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.    General Public License for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License
  18.    along with this program; if not, write to the Free Software
  19.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21.  
  22. #ifndef lint
  23. static char *rcsid = "@(#)$Id: glbl.c,v 1.2 1994/01/20 06:50:53 alm Exp $";
  24. #endif /* not lint */
  25.  
  26. #include <sys/ioctl.h>
  27.  
  28. #include "ed.h"
  29.  
  30.  
  31. /* build_active_list:  add line matching a pattern to the global-active list */
  32. int
  33. build_active_list (isgcmd)
  34.      int isgcmd;
  35. {
  36.   pattern_t *pat;
  37.   line_t *lp;
  38.   long n;
  39.   char *s;
  40.   char delimiter;
  41.  
  42.   if ((delimiter = *ibufp) == ' ' || delimiter == '\n')
  43.     {
  44.       sprintf (errmsg, "invalid pattern delimiter");
  45.       return ERR;
  46.     }
  47.   else if ((pat = get_compiled_pattern ()) == NULL)
  48.     return ERR;
  49.   else if (*ibufp == delimiter)
  50.     ibufp++;
  51.   clear_active_list ();
  52.   lp = get_addressed_line_node (first_addr);
  53.   for (n = first_addr; n <= second_addr; n++, lp = lp->q_forw)
  54.     {
  55.       if ((s = get_sbuf_line (lp)) == NULL)
  56.     return ERR;
  57.       if (isbinary)
  58.     NUL_TO_NEWLINE (s, lp->len);
  59.       if (!regexec (pat, s, 0, NULL, 0) == isgcmd &&
  60.       set_active_node (lp) < 0)
  61.     return ERR;
  62.     }
  63.   return 0;
  64. }
  65.  
  66.  
  67. /* exec_global: apply command list in the command buffer to the active
  68.    lines in a range; return command status */
  69. long
  70. exec_global (interact, gflag)
  71.      int interact;
  72.      int gflag;
  73. {
  74.   static char *ocmd = NULL;
  75.   static int ocmdsz = 0;
  76.  
  77.   line_t *lp = NULL;
  78.   int status;
  79.   int n;
  80.   char *cmd = NULL;
  81.  
  82.   if (!interact)
  83.     if (traditional && !strcmp (ibufp, "\n"))
  84.       cmd = "p\n";        /* null cmd-list == `p' */
  85.     else if ((cmd = get_extended_line (&n, 0)) == NULL)
  86.       return ERR;
  87.   clear_undo_stack ();
  88.   while ((lp = next_active_node ()) != NULL)
  89.     {
  90.       if ((current_addr = get_line_node_addr (lp)) < 0)
  91.     return ERR;
  92.       if (interact)
  93.     {
  94.       /* print current_addr; get a command in global syntax */
  95.       if (display_lines (current_addr, current_addr, gflag) < 0)
  96.         return ERR;
  97.       while ((n = get_tty_line ()) > 0 &&
  98.          ibuf[n - 1] != '\n')
  99.         clearerr (stdin);
  100.       if (n < 0)
  101.         return ERR;
  102.       else if (n == 0)
  103.         {
  104.           sprintf (errmsg, "unexpected end-of-file");
  105.           return ERR;
  106.         }
  107.       else if (n == 1 && !strcmp (ibuf, "\n"))
  108.         continue;
  109.       else if (n == 2 && !strcmp (ibuf, "&\n"))
  110.         {
  111.           if (cmd == NULL)
  112.         {
  113.           sprintf (errmsg, "no previous command");
  114.           return ERR;
  115.         }
  116.           else
  117.         cmd = ocmd;
  118.         }
  119.       else if ((cmd = get_extended_line (&n, 0)) == NULL)
  120.         return ERR;
  121.       else
  122.         {
  123.           REALLOC (ocmd, ocmdsz, n + 1, ERR);
  124.           memcpy (ocmd, cmd, n + 1);
  125.           cmd = ocmd;
  126.         }
  127.  
  128.     }
  129.       ibufp = cmd;
  130.       for (; *ibufp;)
  131.     if ((status = extract_addr_range ()) < 0 ||
  132.         (status = exec_command ()) < 0 ||
  133.         status > 0 && (status = display_lines (
  134.                    current_addr, current_addr, status)) < 0)
  135.       return status;
  136.     }
  137.   return 0;
  138. }
  139.  
  140.  
  141. line_t **active_list;        /* list of lines active in a global command */
  142. long active_last;        /* index of last active line in active_list */
  143. long active_size;        /* size of active_list */
  144. long active_ptr;        /* active_list index (non-decreasing) */
  145. long active_ndx;        /* active_list index (modulo active_last) */
  146.  
  147. /* set_active_node: add a line node to the global-active list */
  148. int
  149. set_active_node (lp)
  150.      line_t *lp;
  151. {
  152.   if (active_last + 1 > active_size)
  153.     {
  154.       int ti = active_size;
  155.       line_t **ts;
  156.       SPL1 ();
  157.       if (active_list != NULL)
  158.     {
  159.       if ((ts = (line_t **) realloc (active_list,
  160.                 (ti += MINBUFSZ) * sizeof (line_t **))) == NULL)
  161.         {
  162.           fprintf (stderr, "%s\n", strerror (errno));
  163.           sprintf (errmsg, "out of memory");
  164.           SPL0 ();
  165.           return ERR;
  166.         }
  167.     }
  168.       else
  169.     {
  170.       if ((ts = (line_t **) malloc ((ti += MINBUFSZ) *
  171.                     sizeof (line_t **))) == NULL)
  172.         {
  173.           fprintf (stderr, "%s\n", strerror (errno));
  174.           sprintf (errmsg, "out of memory");
  175.           SPL0 ();
  176.           return ERR;
  177.         }
  178.     }
  179.       active_size = ti;
  180.       active_list = ts;
  181.       SPL0 ();
  182.     }
  183.   active_list[active_last++] = lp;
  184.   return 0;
  185. }
  186.  
  187.  
  188. /* unset_active_nodes: remove a range of lines from the global-active list */
  189. void
  190. unset_active_nodes (np, mp)
  191.      line_t *np, *mp;
  192. {
  193.   line_t *lp;
  194.   long i;
  195.  
  196.   for (lp = np; lp != mp; lp = lp->q_forw)
  197.     for (i = 0; i < active_last; i++)
  198.       if (active_list[active_ndx] == lp)
  199.     {
  200.       active_list[active_ndx] = NULL;
  201.       active_ndx = INC_MOD (active_ndx, active_last - 1);
  202.       break;
  203.     }
  204.       else
  205.     active_ndx = INC_MOD (active_ndx, active_last - 1);
  206. }
  207.  
  208.  
  209. /* next_active_node: return the next global-active line node */
  210. line_t *
  211. next_active_node ()
  212. {
  213.   while (active_ptr < active_last && active_list[active_ptr] == NULL)
  214.     active_ptr++;
  215.   return (active_ptr < active_last) ? active_list[active_ptr++] : NULL;
  216. }
  217.  
  218.  
  219. /* clear_active_list: clear the global-active list */
  220. void
  221. clear_active_list ()
  222. {
  223.   SPL1 ();
  224.   active_size = active_last = active_ptr = active_ndx = 0;
  225.   if (active_list != NULL)
  226.       free (active_list);
  227.   active_list = NULL;
  228.   SPL0 ();
  229. }
  230.