Logo Search packages:      
Sourcecode: ed version File versions  Download package

glbl.c

/* glbl.c: This file contains the global command routines for the ed line
   editor */
/* ed line editor.
   Copyright (C) 1993, 1994 Andrew Moore, Talke Studio
   All Rights Reserved

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef lint
static char *rcsid = "@(#)$Id: glbl.c,v 1.7 1994/11/13 04:25:44 alm Exp $";
#endif /* not lint */

#include "ed.h"


/* build_active_list:  add line matching a pattern to the global-active list */
int
build_active_list (isgcmd)
     int isgcmd;
{
  pattern_t *pat;
  line_t *lp;
  long n;
  char *s;
  char delimiter;

  if ((delimiter = *ibufp) == ' ' || delimiter == '\n')
    {
      sprintf (errmsg, "Invalid pattern delimiter");
      return ERR;
    }
  else if ((pat = get_compiled_pattern ()) == NULL)
    return ERR;
  else if (*ibufp == delimiter)
    ibufp++;
  clear_active_list ();
  lp = get_addressed_line_node (first_addr);
  for (n = first_addr; n <= second_addr; n++, lp = lp->q_forw)
    {
      if ((s = get_sbuf_line (lp)) == NULL)
      return ERR;
      if (isbinary)
      NUL_TO_NEWLINE (s, lp->len);
      if (!regexec (pat, s, 0, NULL, 0) == isgcmd &&
        set_active_node (lp) < 0)
      return ERR;
    }
  return 0;
}


/* exec_global: apply command list in the command buffer to the active
   lines in a range; return command status */
long
exec_global (interact, gflag)
     int interact;
     int gflag;
{
  static char *ocmd = NULL;
  static int ocmdsz = 0;

  line_t *lp = NULL;
  int status;
  int n;
  char *cmd = NULL;

  if (!interact)
    if (traditional && !strcmp (ibufp, "\n"))
      cmd = "p\n";            /* null cmd-list == `p' */
    else if ((cmd = get_extended_line (&n, 0)) == NULL)
      return ERR;
  clear_undo_stack ();
  while ((lp = next_active_node ()) != NULL)
    {
      if ((current_addr = get_line_node_addr (lp)) < 0)
      return ERR;
      if (interact)
      {
        /* print current_addr; get a command in global syntax */
        if (display_lines (current_addr, current_addr, gflag) < 0)
          return ERR;
        while ((n = get_tty_line ()) > 0 &&
             ibuf[n - 1] != '\n')
          clearerr (stdin);
        if (n < 0)
          return ERR;
        else if (n == 0)
          {
            sprintf (errmsg, "Unexpected end-of-file");
            return ERR;
          }
        else if (n == 1 && !strcmp (ibuf, "\n"))
          continue;
        else if (n == 2 && !strcmp (ibuf, "&\n"))
          {
            if (cmd == NULL)
            {
              sprintf (errmsg, "No previous command");
              return ERR;
            }
            else
            cmd = ocmd;
          }
        else if ((cmd = get_extended_line (&n, 0)) == NULL)
          return ERR;
        else
          {
            REALLOC (ocmd, ocmdsz, n + 1, ERR);
            memcpy (ocmd, cmd, n + 1);
            cmd = ocmd;
          }

      }
      ibufp = cmd;
      for (; *ibufp;)
      if ((status = extract_addr_range ()) < 0 ||
          (status = exec_command ()) < 0 ||
          status > 0 && (status = display_lines (
                           current_addr, current_addr, status)) < 0)
        return status;
    }
  return 0;
}


line_t **active_list;         /* list of lines active in a global command */
long active_last;       /* index of last active line in active_list */
long active_size;       /* size of active_list */
long active_ptr;        /* active_list index (non-decreasing) */
long active_ndx;        /* active_list index (modulo active_last) */

/* set_active_node: add a line node to the global-active list */
int
set_active_node (lp)
     line_t *lp;
{
  if (active_last + 1 > active_size)
    {
      int ti = active_size;
      line_t **ts;
      SPL1 ();
      if (active_list != NULL)
      {
        if ((ts = (line_t **) realloc (active_list,
                      (ti += MINBUFSZ) * sizeof (line_t **))) == NULL)
          {
            fprintf (stderr, "%s\n", strerror (errno));
            sprintf (errmsg, "Out of memory");
            SPL0 ();
            return ERR;
          }
      }
      else
      {
        if ((ts = (line_t **) malloc ((ti += MINBUFSZ) *
                              sizeof (line_t **))) == NULL)
          {
            fprintf (stderr, "%s\n", strerror (errno));
            sprintf (errmsg, "Out of memory");
            SPL0 ();
            return ERR;
          }
      }
      active_size = ti;
      active_list = ts;
      SPL0 ();
    }
  active_list[active_last++] = lp;
  return 0;
}


/* unset_active_nodes: remove a range of lines from the global-active list */
void
unset_active_nodes (np, mp)
     line_t *np, *mp;
{
  line_t *lp;
  long i;

  for (lp = np; lp != mp; lp = lp->q_forw)
    for (i = 0; i < active_last; i++)
      if (active_list[active_ndx] == lp)
      {
        active_list[active_ndx] = NULL;
        active_ndx = INC_MOD (active_ndx, active_last - 1);
        break;
      }
      else
      active_ndx = INC_MOD (active_ndx, active_last - 1);
}


/* next_active_node: return the next global-active line node */
line_t *
next_active_node ()
{
  while (active_ptr < active_last && active_list[active_ptr] == NULL)
    active_ptr++;
  return (active_ptr < active_last) ? active_list[active_ptr++] : NULL;
}


/* clear_active_list: clear the global-active list */
void
clear_active_list ()
{
  SPL1 ();
  active_size = active_last = active_ptr = active_ndx = 0;
  if (active_list != NULL)
      free (active_list);
  active_list = NULL;
  SPL0 ();
}

Generated by  Doxygen 1.6.0   Back to index