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

  1. /* re.c: This file contains the regular expression interface routines for
  2.    the ed line 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: re.c,v 1.3 1994/02/20 03:27:53 alm Exp $";
  24. #endif /* not lint */
  25.  
  26. #include "ed.h"
  27.  
  28.  
  29. extern int patlock;
  30.  
  31. /* get_compiled_pattern: return pointer to compiled pattern from command
  32.    buffer */
  33. pattern_t *
  34. get_compiled_pattern ()
  35. {
  36.   static pattern_t *exp = NULL;
  37.  
  38.   char *exps;
  39.   char delimiter;
  40.   int n;
  41.  
  42.   if ((delimiter = *ibufp) == ' ')
  43.     {
  44.       sprintf (errmsg, "invalid pattern delimiter");
  45.       return NULL;
  46.     }
  47.   else if (delimiter == '\n' || *++ibufp == '\n' || *ibufp == delimiter)
  48.     {
  49.       if (!exp)
  50.     sprintf (errmsg, "no previous pattern");
  51.       return exp;
  52.     }
  53.   else if ((exps = extract_pattern (delimiter)) == NULL)
  54.     return NULL;
  55.   /* buffer alloc'd && not reserved */
  56.   if (exp && !patlock)
  57.     regfree (exp);
  58.   else if ((exp = (pattern_t *) malloc (sizeof (pattern_t))) == NULL)
  59.     {
  60.       fprintf (stderr, "%s\n", strerror (errno));
  61.       sprintf (errmsg, "out of memory");
  62.       return NULL;
  63.     }
  64.   patlock = 0;
  65.   if (n = regcomp (exp, exps, 0))
  66.     {
  67.       regerror (n, exp, errmsg, ERRSZ);
  68.       free (exp);
  69.       return exp = NULL;
  70.     }
  71.   return exp;
  72. }
  73.  
  74.  
  75. /* extract_pattern: copy a pattern string from the command buffer; return
  76.    pointer to the copy */
  77. char *
  78. extract_pattern (delimiter)
  79.      int delimiter;
  80. {
  81.   static char *lhbuf = NULL;    /* buffer */
  82.   static int lhbufsz = 0;    /* buffer size */
  83.  
  84.   char *nd;
  85.   int len;
  86.  
  87.   for (nd = ibufp; *nd != delimiter && *nd != '\n'; nd++)
  88.     switch (*nd)
  89.       {
  90.       default:
  91.     break;
  92.       case '[':
  93.     if ((nd = parse_char_class (++nd)) == NULL)
  94.       {
  95.         sprintf (errmsg, "unbalanced brackets ([])");
  96.         return NULL;
  97.       }
  98.     break;
  99.       case '\\':
  100.     if (*++nd == '\n')
  101.       {
  102.         sprintf (errmsg, "trailing backslash (\\)");
  103.         return NULL;
  104.       }
  105.     break;
  106.       }
  107.   len = nd - ibufp;
  108.   REALLOC (lhbuf, lhbufsz, len + 1, NULL);
  109.   memcpy (lhbuf, ibufp, len);
  110.   lhbuf[len] = '\0';
  111.   ibufp = nd;
  112.   return (isbinary) ? NUL_TO_NEWLINE (lhbuf, len) : lhbuf;
  113. }
  114.  
  115.  
  116. /* parse_char_class: expand a POSIX character class */
  117. char *
  118. parse_char_class (s)
  119.      char *s;
  120. {
  121.   int c, d;
  122.  
  123.   if (*s == '^')
  124.     s++;
  125.   if (*s == ']')
  126.     s++;
  127.   for (; *s != ']' && *s != '\n'; s++)
  128.     if (*s == '[' && ((d = *(s + 1)) == '.' || d == ':' || d == '='))
  129.       for (s++, c = *++s; *s != ']' || c != d; s++)
  130.     if ((c = *s) == '\n')
  131.       return NULL;
  132.   return (*s == ']') ? s : NULL;
  133. }
  134.