changeset 994:bef1844de0dc

The ED editor ported from Minix
author roug
date Sun, 23 Feb 2003 21:11:37 +0000
parents 57b5e715a417
children 48c646212b1c
files 3rdparty/packages/ed/README 3rdparty/packages/ed/amatch.c 3rdparty/packages/ed/append.c 3rdparty/packages/ed/bitmap.c 3rdparty/packages/ed/catsub.c 3rdparty/packages/ed/ckglob.c 3rdparty/packages/ed/compile 3rdparty/packages/ed/deflt.c 3rdparty/packages/ed/del.c 3rdparty/packages/ed/docmd.c 3rdparty/packages/ed/dodash.c 3rdparty/packages/ed/doglob.c 3rdparty/packages/ed/doprnt.c 3rdparty/packages/ed/doread.c 3rdparty/packages/ed/dowrite.c 3rdparty/packages/ed/ed.c 3rdparty/packages/ed/ed.h 3rdparty/packages/ed/ed.refentry 3rdparty/packages/ed/egets.c 3rdparty/packages/ed/esc.c 3rdparty/packages/ed/find.c 3rdparty/packages/ed/getfn.c 3rdparty/packages/ed/getlst.c 3rdparty/packages/ed/getnum.c 3rdparty/packages/ed/getone.c 3rdparty/packages/ed/getpat.c 3rdparty/packages/ed/getptr.c 3rdparty/packages/ed/getrhs.c 3rdparty/packages/ed/gettxt.c 3rdparty/packages/ed/ins.c 3rdparty/packages/ed/join.c 3rdparty/packages/ed/makeed 3rdparty/packages/ed/makelib 3rdparty/packages/ed/makepat.c 3rdparty/packages/ed/maksub.c 3rdparty/packages/ed/matchs.c 3rdparty/packages/ed/move.c 3rdparty/packages/ed/omatch.c 3rdparty/packages/ed/optpat.c 3rdparty/packages/ed/set.c 3rdparty/packages/ed/setbuf.c 3rdparty/packages/ed/subst.c 3rdparty/packages/ed/tools.h 3rdparty/packages/ed/unmkpat.c
diffstat 44 files changed, 2262 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/README	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,13 @@
+The Unix ed-editor ported from Minix to OS9 Level One.
+
+Old UNIX-hands will recognize this simple editor. What makes this editor
+still relevant is that it fits in the memory space of OS9 Level One,
+it is completely independent of terminal command sequences and it can
+be fed instructions from a script.
+
+To build it on OS9 type:
+
+shell compile
+shell makelib
+shell makeed
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/amatch.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,129 @@
+/*      amatch.c        */
+#include <stdio.h>
+#include "tools.h"
+
+/*     Scans throught the pattern template looking for a match
+ * with lin.  Each element of lin is compared with the template
+ * until either a mis-match is found or the end of the template
+ * is reached.  In the former case a 0 is returned; in the latter,
+ * a pointer into lin (pointing to the character following the
+ * matched pattern) is returned.
+ *
+ *      "lin"   is a pointer to the line being searched.
+ *      "pat"   is a pointer to a template made by makepat().
+ *      "boln"  is a pointer into "lin" which points at the
+ *                      character at the beginning of the line.
+ */
+static char *match(); /* Predeclaration */
+
+char *paropen[9], *parclose[9];
+int between, parnum;
+
+char *amatch(lin, pat, boln)
+char *lin;
+TOKEN *pat;
+char *boln;
+{
+  between = 0;
+  parnum = 0;
+
+  lin = match(lin, pat, boln);
+
+  if (between) return 0;
+
+  while (parnum < 9) {
+        paropen[parnum] = parclose[parnum] = "";
+        parnum++;
+  }
+  return lin;
+}
+
+static char *match(lin, pat, boln)
+char *lin;
+TOKEN *pat;
+char *boln;
+{
+  register char *bocl, *rval, *strstart;
+
+  if (pat == 0) return 0;
+
+  strstart = lin;
+
+  while (pat) {
+        if (pat->tok == CLOSURE && pat->next) {
+                /* Process a closure: first skip over the closure
+                 * token to the object to be repeated.  This object
+                 * can be a character class. */
+
+                pat = pat->next;
+
+                /* Now match as many occurrences of the closure
+                 * pattern as possible. */
+                bocl = lin;
+
+                while (*lin && omatch(&lin, pat, boln));
+
+                /* 'Lin' now points to the character that made made
+                 * us fail.  Now go on to process the rest of the
+                 * string.  A problem here is a character following
+                 * the closure which could have been in the closure.
+                 * For example, in the pattern "[a-z]*t" (which
+                 * matches any lower-case word ending in a t), the
+                 * final 't' will be sucked up in the while loop.
+                 * So, if the match fails, we back up a notch and try
+                 * to match the rest of the string again, repeating
+                 * this process recursively until we get back to the
+                 * beginning of the closure.  The recursion goes, at
+                 * most two levels deep. */
+
+                if (pat = pat->next) {
+                        int savbtwn = between;
+                        int savprnm = parnum;
+
+                        while (bocl <= lin) {
+                                if (rval = match(lin, pat, boln)) {
+                                        /* Success */
+                                        return(rval);
+                                } else {
+                                        --lin;
+                                        between = savbtwn;
+                                        parnum = savprnm;
+                                }
+                        }
+                        return(0);      /* match failed */
+                }
+        } else if (pat->tok == OPEN) {
+                if (between || parnum >= 9) return 0;
+                paropen[parnum] = lin;
+                between = 1;
+                pat = pat->next;
+        } else if (pat->tok == CLOSE) {
+                if (!between) return 0;
+                parclose[parnum++] = lin;
+                between = 0;
+                pat = pat->next;
+        } else if (omatch(&lin, pat, boln)) {
+                pat = pat->next;
+        } else {
+                return(0);
+        }
+  }
+
+  /* Note that omatch() advances lin to point at the next character to
+   * be matched.  Consequently, when we reach the end of the template,
+   * lin will be pointing at the character following the last character
+   * matched.  The exceptions are templates containing only a BOLN or
+   * EOLN token.  In these cases omatch doesn't advance.
+   *
+   * A philosophical point should be mentioned here.  Is $ a position or a
+   * character? (i.e. does $ mean the EOL character itself or does it
+   * mean the character at the end of the line.)  I decided here to
+   * make it mean the former, in order to make the behavior of match()
+   * consistent.  If you give match the pattern ^$ (match all lines
+   * consisting only of an end of line) then, since something has to be
+   * returned, a pointer to the end of line character itself is
+   * returned. */
+
+  return((char *) max(strstart, lin));
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/append.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,24 @@
+/*      append.c        */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+int append(line, glob)
+int line, glob;
+{
+  int stat;
+  char lin[MAXLINE];
+
+  if (glob) return(ERR);
+  curln = line;
+  while (1) {
+        if (nflg) printf("%6d. ", curln + 1);
+
+        if (fgets(lin, MAXLINE, stdin) == NULL) return(EOF);
+        if (lin[0] == '.' && lin[1] == '\n') return (0);
+        stat = ins(lin);
+        if (stat < 0) return(ERR);
+
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/bitmap.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,70 @@
+/*      bitmap.c        */
+/*
+ *      BITMAP.C -      makebitmap, setbit, testbit
+ *                      bit-map manipulation routines.
+ *
+ *      Copyright (c) Allen I. Holub, all rights reserved.  This program may
+ *              for copied for personal, non-profit use only.
+ *
+ */
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#include "tools.h"
+
+BITMAP *makebitmap(size)
+unsigned size;
+{
+  /* Make a bit map with "size" bits.  The first entry in the map is an
+   * "unsigned int" representing the maximum bit.  The map itself is
+   * concatenated to this integer. Return a pointer to a map on
+   * success, 0 if there's not enough memory. */
+
+  unsigned *map, numbytes;
+
+  numbytes = (size >> 3) + ((size & 0x07) ? 1 : 0);
+
+#ifdef DEBUG
+  printf("Making a %d bit map (%d bytes required)\n", size, numbytes);
+#endif
+
+  if (map = (unsigned *) malloc(numbytes + sizeof(unsigned))) *map = size;
+
+  return((BITMAP *) map);
+}
+
+int setbit(c, map, val)
+unsigned c, val;
+char *map;
+{
+  /* Set bit c in the map to val. If c > map-size, 0 is returned, else
+   * 1 is returned. */
+
+  if (c >= *(unsigned *) map)   /* if c >= map size */
+        return 0;
+
+  map += sizeof(unsigned);      /* skip past size */
+
+  if (val)
+        map[c >> 3] |= 1 << (c & 0x07);
+  else
+        map[c >> 3] &= ~(1 << (c & 0x07));
+
+  return 1;
+}
+
+int testbit(c, map)
+unsigned c;
+char *map;
+{
+  /* Return 1 if the bit corresponding to c in map is set. 0 if it is not. */
+
+  if (c >= *(unsigned *) map) return 0;
+
+  map += sizeof(unsigned);
+
+  return(map[c >> 3] & (1 << (c & 0x07)));
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/catsub.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,37 @@
+/*      catsub.c        */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+extern char *paropen[9], *parclose[9];
+
+char *catsub(from, to, sub, new, newend)
+char *from, *to, *sub, *new, *newend;
+{
+  char *cp, *cp2;
+
+  for (cp = new; *sub != EOS && cp < newend;) {
+        if (*sub == DITTO) for (cp2 = from; cp2 < to;) {
+                        *cp++ = *cp2++;
+                        if (cp >= newend) break;
+                }
+        else if (*sub == ESCAPE) {
+                sub++;
+                if ('1' <= *sub && *sub <= '9') {
+                        char *parcl = parclose[*sub - '1'];
+
+                        for (cp2 = paropen[*sub - '1']; cp2 < parcl;) {
+                                *cp++ = *cp2++;
+                                if (cp >= newend) break;
+                        }
+                } else
+                        *cp++ = *sub;
+        } else
+                *cp++ = *sub;
+
+        sub++;
+  }
+
+  return(cp);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/ckglob.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,43 @@
+/*      ckglob.c        */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+int ckglob()
+{
+  TOKEN *glbpat;
+  char c, delim;
+  char lin[MAXLINE];
+  int num;
+  LINE *ptr;
+
+  c = *inptr;
+
+  if (c != 'g' && c != 'v') return(0);
+
+  if (deflt(1, lastln) < 0) return(ERR);
+
+  delim = *++inptr;
+  if (delim <= ' ') return(ERR);
+
+  glbpat = optpat();
+
+  if (*inptr == delim) inptr++;
+
+  ptr = getptr(1);
+  for (num = 1; num <= lastln; num++) {
+        ptr->l_stat &= ~LGLOB;
+        if (line1 <= num && num <= line2) {
+                strcpy(lin, ptr->l_buff);
+                strcat(lin, "\n");
+                if (matchs(lin, glbpat, 0)) {
+                        if (c == 'g') ptr->l_stat |= LGLOB;
+                } else {
+                        if (c == 'v') ptr->l_stat |= LGLOB;
+                }
+        }
+        ptr = ptr->l_next;
+  }
+  return(1);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/compile	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,37 @@
+cc1 -r amatch.c
+cc1 -r append.c
+cc1 -r bitmap.c
+cc1 -r catsub.c
+cc1 -r ckglob.c
+cc1 -r deflt.c
+cc1 -r del.c
+cc1 -r docmd.c
+cc1 -r dodash.c
+cc1 -r doglob.c
+cc1 -r doprnt.c
+cc1 -r doread.c
+cc1 -r dowrite.c
+cc1 -r ed.c
+cc1 -r egets.c
+cc1 -r esc.c
+cc1 -r find.c
+cc1 -r getfn.c
+cc1 -r getlst.c
+cc1 -r getnum.c
+cc1 -r getone.c
+cc1 -r getpat.c
+cc1 -r getptr.c
+cc1 -r getrhs.c
+cc1 -r gettxt.c
+cc1 -r ins.c
+cc1 -r join.c
+cc1 -r makepat.c
+cc1 -r maksub.c
+cc1 -r matchs.c
+cc1 -r move.c
+cc1 -r omatch.c
+cc1 -r optpat.c
+cc1 -r set.c
+cc1 -r setbuf.c
+cc1 -r subst.c
+cc1 -r unmkpat.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/deflt.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,16 @@
+/*      deflt.c */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+int deflt(def1, def2)
+int def1, def2;
+{
+  if (nlines == 0) {
+        line1 = def1;
+        line2 = def2;
+  }
+  if (line1 > line2 || line1 <= 0) return(ERR);
+  return(0);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/del.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,25 @@
+/*      del.c   */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+int del(from, to)
+int from, to;
+{
+  LINE *first, *last, *next, *tmp;
+
+  if (from < 1) from = 1;
+  first = getptr(prevln(from));
+  last = getptr(nextln(to));
+  next = first->l_next;
+  while (next != last && next != &line0) {
+        tmp = next->l_next;
+        free((char *) next);
+        next = tmp;
+  }
+  relink(first, last, first, last);
+  lastln -= (to - from) + 1;
+  curln = prevln(from);
+  return(0);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/docmd.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,243 @@
+/*      docmd.c */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+char fname[MAXFNAME];
+int fchanged;
+extern int nofname;
+
+extern int mark[];
+
+int docmd(glob)
+int glob;
+{
+  static char rhs[MAXPAT];
+  TOKEN *subpat;
+  int c, err, line3;
+  int apflg, pflag, gflag;
+  int nchng;
+  char *fptr;
+
+  pflag = FALSE;
+  while (*inptr == SP && *inptr == HT) inptr++;
+
+  c = *inptr++;
+
+  switch (c) {
+      case NL:
+        if (nlines == 0) {
+                if ((line2 = nextln(curln)) == 0) return(ERR);
+        }
+        curln = line2;
+        return(1);
+        break;
+
+      case '=': printf("%d\n", line2);  break;
+
+      case 'a':
+        if (*inptr != NL || nlines > 1) return(ERR);
+
+        if (append(line1, glob) < 0) return(ERR);;
+        fchanged = TRUE;
+        break;
+
+      case 'c':
+        if (*inptr != NL) return(ERR);
+
+        if (deflt(curln, curln) < 0) return(ERR);
+
+        if (del(line1, line2) < 0) return(ERR);
+        if (append(curln, glob) < 0) return (ERR);
+        fchanged = TRUE;
+        break;
+
+      case 'd':
+        if (*inptr != NL) return(ERR);
+
+        if (deflt(curln, curln) < 0) return(ERR);
+
+        if (del(line1, line2) < 0) return(ERR);
+        if (nextln(curln) != 0) curln = nextln(curln);
+        fchanged = TRUE;
+        break;
+
+      case 'e':
+        if (nlines > 0) return(ERR);
+        if (fchanged) {
+                fchanged = FALSE;
+                return(ERR);
+        }
+
+        /* FALL THROUGH */
+      case 'E':
+        if (nlines > 0) return(ERR);
+
+        if (*inptr != ' ' && *inptr != HT && *inptr != NL) return(ERR);
+
+        if ((fptr = getfn()) == NULL) return(ERR);
+
+        clrbuf();
+        if ((err = doread(0, fptr)) < 0) return(err);
+
+        strcpy(fname, fptr);
+        fchanged = FALSE;
+        break;
+
+      case 'f':
+        if (nlines > 0) return(ERR);
+
+        if (*inptr != ' ' && *inptr != HT && *inptr != NL) return(ERR);
+
+        if ((fptr = getfn()) == NULL) return(ERR);
+
+        if (nofname)
+                printf("%s\n", fname);
+        else
+                strcpy(fname, fptr);
+        break;
+
+      case 'i':
+        if (*inptr != NL || nlines > 1) return(ERR);
+
+        if (append(prevln(line1), glob) < 0) return(ERR);
+        fchanged = TRUE;
+        break;
+
+      case 'j':
+        if (*inptr != NL || deflt(curln, curln + 1) < 0) return(ERR);
+
+        if (join(line1, line2) < 0) return(ERR);
+        break;
+
+      case 'k':
+        while (*inptr == ' ' || *inptr == HT) inptr++;
+
+        if (*inptr < 'a' || *inptr > 'z') return ERR;
+        c = *inptr++;
+
+        if (*inptr != ' ' && *inptr != HT && *inptr != NL) return(ERR);
+
+        mark[c - 'a'] = line1;
+        break;
+
+      case 'l':
+        if (*inptr != NL) return(ERR);
+        if (deflt(curln, curln) < 0) return (ERR);
+        if (dolst(line1, line2) < 0) return (ERR);
+        break;
+
+      case 'm':
+        if ((line3 = getone()) < 0) return(ERR);
+        if (deflt(curln, curln) < 0) return (ERR);
+        if (move(line3) < 0) return (ERR);
+        fchanged = TRUE;
+        break;
+
+      case 'P':
+      case 'p':
+        if (*inptr != NL) return(ERR);
+        if (deflt(curln, curln) < 0) return (ERR);
+        if (doprnt(line1, line2) < 0) return (ERR);
+        break;
+
+      case 'q':
+        if (fchanged) {
+                fchanged = FALSE;
+                return(ERR);
+        }
+
+        /* FALL THROUGH */
+      case 'Q':
+        if (*inptr == NL && nlines == 0 && !glob)
+                return(EOF);
+        else
+                return(ERR);
+
+      case 'r':
+        if (nlines > 1) return(ERR);
+
+        if (nlines == 0) line2 = lastln;
+
+        if (*inptr != ' ' && *inptr != HT && *inptr != NL) return(ERR);
+
+        if ((fptr = getfn()) == NULL) return(ERR);
+
+        if ((err = doread(line2, fptr)) < 0) return(err);
+        fchanged = TRUE;
+        break;
+
+      case 's':
+        if (*inptr == 'e') return(set());
+        while (*inptr == SP || *inptr == HT) inptr++;
+        if ((subpat = optpat()) == NULL) return (ERR);
+        if ((gflag = getrhs(rhs)) < 0) return (ERR);
+        if (*inptr == 'p') pflag++;
+        if (deflt(curln, curln) < 0) return (ERR);
+        if ((nchng = subst(subpat, rhs, gflag, pflag)) < 0) return (ERR);
+        if (nchng) fchanged = TRUE;
+        break;
+
+      case 't':
+        if ((line3 = getone()) < 0) return(ERR);
+        if (deflt(curln, curln) < 0) return (ERR);
+        if (transfer(line3) < 0) return (ERR);
+        fchanged = TRUE;
+        break;
+
+      case 'W':
+      case 'w':
+        apflg = (c == 'W');
+
+        if (*inptr != ' ' && *inptr != HT && *inptr != NL) return(ERR);
+
+        if ((fptr = getfn()) == NULL) return(ERR);
+
+        if (deflt(1, lastln) < 0) return(ERR);
+        if (dowrite(line1, line2, fptr, apflg) < 0) return (ERR);
+        fchanged = FALSE;
+        break;
+
+      case 'x':
+        if (*inptr == NL && nlines == 0 && !glob) {
+                if ((fptr = getfn()) == NULL) return(ERR);
+                if (dowrite(1, lastln, fptr, 0) >= 0) return (EOF);
+        }
+        return(ERR);
+
+      case 'z':
+        if (deflt(curln, curln) < 0) return(ERR);
+
+        switch (*inptr) {
+            case '-':
+                if (doprnt(line1 - 21, line1) < 0) return(ERR);
+                break;
+
+            case '.':
+                if (doprnt(line1 - 11, line1 + 10) < 0) return(ERR);
+                break;
+
+            case '+':
+            case '\n':
+                if (doprnt(line1, line1 + 21) < 0) return(ERR);
+                break;
+        }
+        break;
+
+      default:  return(ERR);
+}
+  return(0);
+}
+
+int dolst(line1, line2)
+int line1, line2;
+{
+  int oldlflg = lflg, p;
+
+  lflg = 1;
+  p = doprnt(line1, line2);
+  lflg = oldlflg;
+
+  return p;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/dodash.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,50 @@
+/*      dodash.c        */
+#include <stdio.h>
+#include "tools.h"
+
+/*      Expand the set pointed to by *src into dest.
+ *      Stop at delim.  Return 0 on error or size of
+ *      character class on success.  Update *src to
+ *      point at delim.  A set can have one element
+ *      {x} or several elements ( {abcdefghijklmnopqrstuvwxyz}
+ *      and {a-z} are equivalent ).  Note that the dash
+ *      notation is expanded as sequential numbers.
+ *      This means (since we are using the ASCII character
+ *      set) that a-Z will contain the entire alphabet
+ *      plus the symbols: [\]^_`.  The maximum number of
+ *      characters in a character class is defined by maxccl.
+ */
+char *dodash(delim, src, map)
+int delim;
+char *src, *map;
+{
+
+  register int first, last;
+  char *start;
+
+  start = src;
+
+  while (*src && *src != delim) {
+        if (*src != '-') setbit(esc(&src), map, 1);
+
+        else if (src == start || *(src + 1) == delim)
+                setbit('-', map, 1);
+        else {
+                src++;
+
+                if (*src < *(src - 2)) {
+                        first = *src;
+                        last = *(src - 2);
+                } else {
+                        first = *(src - 2);
+                        last = *src;
+                }
+
+                while (++first <= last) setbit(first, map, 1);
+
+        }
+        src++;
+  }
+  return(src);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/doglob.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,30 @@
+/*      doglob.c        */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+int doglob()
+{
+  int lin, stat;
+  char *cmd;
+  LINE *ptr;
+
+  cmd = inptr;
+
+  while (1) {
+        ptr = getptr(1);
+        for (lin = 1; lin <= lastln; lin++) {
+                if (ptr->l_stat & LGLOB) break;
+                ptr = ptr->l_next;
+        }
+        if (lin > lastln) break;
+
+        ptr->l_stat &= ~LGLOB;
+        curln = lin;
+        inptr = cmd;
+        if ((stat = getlst()) < 0) return(stat);
+        if ((stat = docmd(1)) < 0) return (stat);
+  }
+  return(curln);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/doprnt.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,65 @@
+/*      doprnt.c        */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+int doprnt(from, to)
+int from, to;
+{
+  int i;
+  LINE *lptr;
+
+  from = from < 1 ? 1 : from;
+  to = to > lastln ? lastln : to;
+
+  if (to != 0) {
+        lptr = getptr(from);
+        for (i = from; i <= to; i++) {
+                prntln(lptr->l_buff, lflg, (nflg ? i : 0));
+                lptr = lptr->l_next;
+        }
+        curln = to;
+  }
+  return(0);
+}
+
+prntln(str, vflg, lin)
+char *str;
+int vflg, lin;
+{
+  if (lin) printf("%7d ", lin);
+  while (*str && *str != NL) {
+        if (*str < ' ' || *str >= 0x7f) {
+                switch (*str) {
+                    case '\t':
+                        if (vflg)
+                                putcntl(*str, stdout);
+                        else
+                                putc(*str, stdout);
+                        break;
+
+                    case DEL:
+                        putc('^', stdout);
+                        putc('?', stdout);
+                        break;
+
+                    default:
+                        putcntl(*str, stdout);
+                        break;
+                }
+        } else
+                putc(*str, stdout);
+        str++;
+  }
+  if (vflg) putc('$', stdout);
+  putc('\n', stdout);
+}
+
+putcntl(c, stream)
+char c;
+FILE *stream;
+{
+  putc('^', stream);
+  putc((c & 31) | '@', stream);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/doread.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,47 @@
+/*      doread.c        */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+extern int diag;
+
+int doread(lin, fname)
+int lin;
+char *fname;
+{
+  FILE *fp;
+  int err;
+  long bytes;
+  int lines;
+  static char str[MAXLINE];
+
+  err = 0;
+  nonascii = nullchar = truncated = 0;
+
+  if (diag) printf("\"%s\" ", fname);
+  if ((fp = fopen(fname, "r")) == NULL) {
+        printf("file open err\n");
+        return(ERR);
+  }
+  curln = lin;
+  for (lines = 0, bytes = 0; (err = egets(str, MAXLINE, fp)) > 0;) {
+        bytes += strlen(str);
+        if (ins(str) < 0) {
+                printf("file insert error\n");
+                err++;
+                break;
+        }
+        lines++;
+  }
+  fclose(fp);
+  if (err < 0) return(err);
+  if (diag) {
+        printf("%d lines %ld bytes", lines, bytes);
+        if (nonascii) printf(" [%d non-ascii]", nonascii);
+        if (nullchar) printf(" [%d nul]", nullchar);
+        if (truncated) printf(" [%d lines truncated]", truncated);
+        printf("\n");
+  }
+  return(err);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/dowrite.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,45 @@
+/*      dowrite.c       */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+extern int diag;
+
+int dowrite(from, to, fname, apflg)
+int from, to;
+char *fname;
+int apflg;
+{
+  FILE *fp;
+  int lin, err;
+  int lines;
+  long bytes;
+  char *str;
+  LINE *lptr;
+
+  err = 0;
+
+  lines = bytes = 0;
+  if (diag) printf("\"%s\" ", fname);
+  if ((fp = fopen(fname, (apflg ? "a" : "w"))) == NULL) {
+        printf("file open error\n");
+        return(ERR);
+  }
+  lptr = getptr(from);
+  for (lin = from; lin <= to; lin++) {
+        str = lptr->l_buff;
+        lines++;
+        bytes += strlen(str) + 1;
+        if (fputs(str, fp) == EOF) {
+                printf("file write error\n");
+                err++;
+                break;
+        }
+        putc('\n', fp);
+        lptr = lptr->l_next;
+  }
+  if (diag) printf("%d lines %ld bytes\n", lines, bytes);
+  fclose(fp);
+  return(err);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/ed.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,99 @@
+/*      ed.c    */
+/* Copyright 1987 Brian Beattie Rights Reserved.
+ *
+ * Permission to copy and/or distribute granted under the
+ * following conditions:
+ *
+ * 1). No charge may be made other than resonable charges
+ *      for reproduction.
+ *
+ * 2). This notice must remain intact.
+ *
+ * 3). No further restrictions may be added.
+ *
+ */
+#include <stdio.h>
+#include <signal.h>
+#include "tools.h"
+#include "ed.h"
+#include <setjmp.h>
+jmp_buf env;
+
+#define isatty(fd) 1
+
+LINE line0;
+int curln = 0;
+int lastln = 0;
+char *inptr;
+static char inlin[MAXLINE];
+int nflg, lflg;
+int line1, line2, nlines;
+extern char fname[];
+int version = 1;
+int diag = 1;
+
+intr(sig)
+int sig;
+{
+  printf("?\n");
+  longjmp(env, 1);
+}
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+  int stat, i, doflush;
+
+  pflinit();
+  set_buf();
+  doflush = isatty(1);
+
+  if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 0) {
+        diag = 0;
+        argc--;
+        argv++;
+  }
+  if (argc > 1) {
+        for (i = 1; i < argc; i++) {
+                if (doread(0, argv[i]) == 0) {
+                        curln = 1;
+                        strcpy(fname, argv[i]);
+                        break;
+                }
+        }
+  }
+  while (1) {
+        setjmp(env);
+        if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, intr);
+
+        if (doflush) fflush(stdout);
+
+        if (fgets(inlin, sizeof(inlin), stdin) == NULL) {
+                break;
+        }
+        inptr = inlin;
+        if (getlst() >= 0)
+                if ((stat = ckglob()) != 0) {
+                        if (stat >= 0 && (stat = doglob()) >= 0) {
+                                curln = stat;
+                                continue;
+                        }
+                } else {
+                        if ((stat = docmd(0)) >= 0) {
+                                if (stat == 1) doprnt(curln, curln);
+                                continue;
+                        }
+                }
+        if (stat == EOF) {
+                exit(0);
+        }
+        if (stat == FATAL) {
+                fputs("FATAL ERROR\n", stderr);
+                exit(1);
+        }
+        printf("?\n");
+  }
+  return(0);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/ed.h	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,37 @@
+/*      ed.h    */
+#define FATAL   (ERR-1)
+struct line {
+  int l_stat;                   /* empty, mark */
+  struct line *l_prev;
+  struct line *l_next;
+  char l_buff[1];
+};
+
+typedef struct line LINE;
+
+#define LINFREE 1               /* entry not in use */
+#define LGLOB   2               /* line marked global */
+
+                                /* max number of chars per line */
+#define MAXLINE (sizeof(int) == 2 ? 256 : 8192)
+#define MAXPAT  256             /* max number of chars per replacement
+                                 * pattern */
+                                /* max file name size */
+#define MAXFNAME (sizeof(int) == 2 ? 256 : 1024)
+
+extern LINE line0;
+extern int curln, lastln, line1, line2, nlines;
+extern int nflg;                /* print line number flag */
+extern int lflg;                /* print line in verbose mode */
+extern char *inptr;             /* tty input buffer */
+extern char linbuf[], *linptr;  /* current line */
+extern int truncflg;            /* truncate long line flag */
+extern int eightbit;            /* save eighth bit */
+extern int nonascii;            /* count of non-ascii chars read */
+extern int nullchar;            /* count of null chars read */
+extern int truncated;           /* count of lines truncated */
+extern int fchanged;            /* file changed */
+
+#define nextln(l)       ((l)+1 > lastln ? 0 : (l)+1)
+#define prevln(l)       ((l)-1 < 0 ? lastln : (l)-1)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/ed.refentry	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,131 @@
+<refentry id="ed">
+<refnamediv>
+<refname>ED</refname>
+<refpurpose>editor</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+<cmdsynopsis>
+<command>ED</command>
+<arg choice="plain"><replaceable>file</replaceable></arg>
+<arg choice="opt">-</arg>
+</cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1><title>Options</title>
+<para>
+"-" Suppress line/byte count messages (for in scripts)
+</para>
+</refsect1>
+<refsect1><title>Examples</title>
+<screen>
+ed prog.c                Edit <filename>prog.c</filename>
+echo '1,$p' | ed - file  Odd way to write 'cat file'
+</screen>
+</refsect1>
+<refsect1><title>Description</title>
+<para>
+<command>Ed</command> is functionally equivalent to the standard UNIX V7 editor, ed.  
+It supports the following commands:
+</para>
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="0.7in"/>
+<colspec colwidth="2.95in"/>
+<tbody>
+<row>
+<entry>(.)</entry><entry>a: append</entry>
+</row>
+<row>
+<entry>(.,.)</entry><entry>c: change</entry>
+</row>
+<row>
+<entry>(.,.)</entry><entry>d: delete</entry>
+</row>
+<row>
+<entry></entry><entry>e: edit new file"</entry>
+</row>
+<row>
+<entry></entry><entry>f: print name of edited file"</entry>
+</row>
+<row>
+<entry>(1,$)</entry><entry>g: global command</entry>
+</row>
+<row>
+<entry>(.)</entry><entry>i: insert</entry>
+</row>
+<row>
+<entry>(.,.+1)</entry><entry>j: join lines together</entry>
+</row>
+<row>
+<entry>(.)</entry><entry>k: mark</entry>
+</row>
+<row>
+<entry>(.)</entry><entry>l: print with special characters in octal</entry>
+</row>
+<row>
+<entry>(.,.)</entry><entry>m: move</entry>
+</row>
+<row>
+<entry>(.,.)</entry><entry>p: print</entry>
+</row>
+<row>
+<entry></entry><entry>q: quit editor"</entry>
+</row>
+<row>
+<entry>(.)</entry><entry>r: read in new file</entry>
+</row>
+<row>
+<entry>(.,.)</entry><entry>s: substitute</entry>
+</row>
+<row>
+<entry>(1,$)</entry><entry>v: like g, except select lines that do not match</entry>
+</row>
+<row>
+<entry>(1,$)</entry><entry>w: write out edited file</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+Many of the commands can take one or two addresses, as indicated above.  The
+defaults are shown in parentheses.  Thus <command>a</command> appends to the current 
+line, and <command>g</command> works on the whole file as default.  
+The dot refers to the current line.
+Below is a sample editing session with comments given following the # symbol.
+</para>
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="1.3in"/>
+<colspec colwidth="3.5in"/>
+<tbody>
+<row>
+<entry>ed prog.c</entry><entry># Edit prog.c</entry>
+</row>
+<row>
+<entry>3,20p</entry><entry># Print lines 3 through 20</entry>
+</row>
+<row>
+<entry>/whole/</entry><entry># Find next occurence of <replaceable>whole</replaceable></entry>
+</row>
+<row>
+<entry>s/whole/while/</entry><entry># Replace <replaceable>whole</replaceable> by <replaceable>while</replaceable></entry>
+</row>
+<row>
+<entry>g/Buf/s//BUF/g</entry><entry># Replace <replaceable>Buf</replaceable> by <replaceable>BUF</replaceable> everywhere</entry>
+</row>
+<row>
+<entry>w</entry><entry># Write the file back</entry>
+</row>
+<row>
+<entry>q</entry><entry># Exit the editor</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<command>Ed</command> is provided for its sentimental value.
+</para>
+</refsect1>
+</refentry>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/egets.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,51 @@
+/*      egets.c */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+int eightbit = 1;               /* save eight bit */
+int nonascii, nullchar, truncated;
+int egets(str, size, stream)
+char *str;
+int size;
+FILE *stream;
+{
+  int c, count;
+  char *cp;
+
+  for (count = 0, cp = str; size > count;) {
+        c = getc(stream);
+        if (c == EOF) {
+                *cp++ = '\n';
+                *cp = EOS;
+                if (count) {
+                        printf("[Incomplete last line]\n");
+                }
+                return(count);
+        }
+        if (c == NL) {
+                *cp++ = c;
+                *cp = EOS;
+                return(++count);
+        }
+        if (c > 127) {
+                if (!eightbit)  /* if not saving eighth bit */
+                        c = c & 127;    /* strip eigth bit */
+                nonascii++;     /* count it */
+        }
+        if (c) {
+                *cp++ = c;      /* not null, keep it */
+                count++;
+        } else
+                nullchar++;     /* count nulls */
+  }
+  str[count - 1] = EOS;
+  if (c != NL) {
+        printf("truncating line\n");
+        truncated++;
+        while ((c = getc(stream)) != EOF)
+                if (c == NL) break;
+  }
+  return(count);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/esc.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,33 @@
+/*      esc.c   */
+#include <stdio.h>
+#include "tools.h"
+
+/* Map escape sequences into their equivalent symbols.  Returns the
+ * correct ASCII character.  If no escape prefix is present then s
+ * is untouched and *s is returned, otherwise **s is advanced to point
+ * at the escaped character and the translated character is returned.
+ */
+int esc(s)
+char **s;
+{
+  register int rval;
+
+  if (**s != ESCAPE) {
+        rval = **s;
+  } else {
+        (*s)++;
+
+        switch (toupper(**s)) {
+            case '\000':        rval = ESCAPE;  break;
+            case 'S':   rval = ' ';     break;
+            case 'N':   rval = '\n';    break;
+            case 'T':   rval = '\t';    break;
+            case 'B':   rval = '\b';    break;
+            case 'R':   rval = '\r';    break;
+            default:    rval = **s;     break;
+        }
+  }
+
+  return(rval);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/find.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,33 @@
+/*      find.c  */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+int find(pat, dir)
+TOKEN *pat;
+int dir;
+{
+  int i, num;
+  char lin[MAXLINE];
+  LINE *ptr;
+
+  num = curln;
+  ptr = getptr(curln);
+  num = (dir ? nextln(num) : prevln(num));
+  ptr = (dir ? ptr->l_next : ptr->l_prev);
+  for (i = 0; i < lastln; i++) {
+        if (num == 0) {
+                num = (dir ? nextln(num) : prevln(num));
+                ptr = (dir ? ptr->l_next : ptr->l_prev);
+        }
+        strcpy(lin, ptr->l_buff);
+        strcat(lin, "\n");
+        if (matchs(lin, pat, 0)) {
+                return(num);
+        }
+        num = (dir ? nextln(num) : prevln(num));
+        ptr = (dir ? ptr->l_next : ptr->l_prev);
+  }
+  return(ERR);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/getfn.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,39 @@
+/*      getfn.c */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+extern char fname[MAXFNAME];
+int nofname;
+
+char *getfn()
+{
+  static char file[256];
+  char *cp;
+
+  if (*inptr == NL) {
+        nofname = TRUE;
+        strcpy(file, fname);
+  } else {
+        nofname = FALSE;
+        while (*inptr == SP || *inptr == HT) inptr++;
+
+        cp = file;
+        while (*inptr && *inptr != NL && *inptr != SP && *inptr != HT) {
+                *cp++ = *inptr++;
+        }
+        *cp = '\0';
+
+        if (strlen(file) == 0) {
+                printf("bad file name\n");
+                return(NULL);
+        }
+  }
+
+  if (strlen(file) == 0) {
+        printf("no file name\n");
+        return(NULL);
+  }
+  return(file);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/getlst.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,28 @@
+/*      getlst.c        */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+int getlst()
+{
+  int num;
+
+  line2 = 0;
+  for (nlines = 0; (num = getone()) >= 0;) {
+        line1 = line2;
+        line2 = num;
+        nlines++;
+        if (*inptr != ',' && *inptr != ';') break;
+        if (*inptr == ';') curln = num;
+        inptr++;
+  }
+  nlines = min(nlines, 2);
+  if (nlines == 0) line2 = curln;
+  if (nlines <= 1) line1 = line2;
+
+  if (num == ERR)
+        return(num);
+  else
+        return(nlines);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/getnum.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,53 @@
+/*      getnum.c        */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+int mark['z' - 'a' + 1];
+
+int getnum(first)
+int first;
+{
+  TOKEN *srchpat;
+  int num;
+  char c;
+
+  while (*inptr == SP || *inptr == HT) inptr++;
+
+  if (*inptr >= '0' && *inptr <= '9') { /* line number */
+        for (num = 0; *inptr >= '0' && *inptr <= '9';) {
+                num = (num * 10) + *inptr - '0';
+                inptr++;
+        }
+        return num;
+  }
+  switch (c = *inptr) {
+      case '.':
+        inptr++;
+        return(curln);
+
+      case '$':
+        inptr++;
+        return(lastln);
+
+      case '/':
+      case '?':
+        srchpat = optpat();
+        if (*inptr == c) inptr++;
+        return(find(srchpat, c == '/' ? 1 : 0));
+
+      case '-':
+      case '+':
+        return(first ? curln : 1);
+
+      case '\'':
+        inptr++;
+        if (*inptr < 'a' || *inptr > 'z') return(EOF);
+
+        return mark[*inptr++ - 'a'];
+
+      default:
+        return(first ? EOF : 1);/* unknown address */
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/getone.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,31 @@
+/*      getone.c        */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+#define FIRST 1
+#define NOTFIRST 0
+
+int getone()
+{
+  int c, i, num;
+
+  if ((num = getnum(FIRST)) >= 0) {
+        while (1) {
+                while (*inptr == SP || *inptr == HT) inptr++;
+
+                if (*inptr != '+' && *inptr != '-') break;
+                c = *inptr++;
+
+                if ((i = getnum(NOTFIRST)) < 0) return(i);
+
+                if (c == '+') {
+                        num += i;
+                } else {
+                        num -= i;
+                }
+        }
+  }
+  return(num > lastln ? ERR : num);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/getpat.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,13 @@
+/*      getpat.c        */
+#include <stdio.h>
+#include "tools.h"
+
+/* Translate arg into a TOKEN string */
+TOKEN *
+ getpat(arg)
+char *arg;
+{
+
+  return(makepat(arg, '\000'));
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/getptr.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,22 @@
+/*      getptr.c        */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+LINE *
+ getptr(num)
+int num;
+{
+  LINE *ptr;
+  int j;
+
+  if (2 * num > lastln && num <= lastln) {      /* high line numbers */
+        ptr = line0.l_prev;
+        for (j = lastln; j > num; j--) ptr = ptr->l_prev;
+  } else {                      /* low line numbers */
+        ptr = &line0;
+        for (j = 0; j < num; j++) ptr = ptr->l_next;
+  }
+  return(ptr);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/getrhs.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,22 @@
+/*      getrhs.c        */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+int getrhs(sub)
+char *sub;
+{
+  if (inptr[0] == NL || inptr[1] == NL) /* check for eol */
+        return(ERR);
+
+  if (maksub(sub, MAXPAT) == NULL) return(ERR);
+
+  inptr++;                      /* skip over delimter */
+  while (*inptr == SP || *inptr == HT) inptr++;
+  if (*inptr == 'g') {
+        inptr++;
+        return(1);
+  }
+  return(0);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/gettxt.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,18 @@
+/*      gettxt.c        */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+char *
+ gettxt(num)
+int num;
+{
+  LINE *lin;
+  static char txtbuf[MAXLINE];
+
+  lin = getptr(num);
+  strcpy(txtbuf, lin->l_buff);
+  strcat(txtbuf, "\n");
+  return(txtbuf);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/ins.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,37 @@
+/*      ins.c   */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+int ins(str)
+char *str;
+{
+  char buf[MAXLINE], *cp;
+  LINE *new, *cur, *nxt;
+
+  cp = buf;
+  while (1) {
+        if ((*cp = *str++) == NL) *cp = EOS;
+        if (*cp) {
+                cp++;
+                continue;
+        }
+        if ((new = (LINE *) malloc(sizeof(LINE) + strlen(buf))) == NULL)
+                return(ERR);    /* no memory */
+
+        new->l_stat = 0;
+        strcpy(new->l_buff, buf);       /* build new line */
+        cur = getptr(curln);    /* get current line */
+        nxt = cur->l_next;      /* get next line */
+        relink(cur, new, new, nxt);     /* add to linked list */
+        relink(new, nxt, cur, new);
+        lastln++;
+        curln++;
+
+        if (*str == EOS)        /* end of line ? */
+                return(1);
+
+        cp = buf;
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/join.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,38 @@
+/*      join.c  */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+extern int fchanged;
+
+int join(first, last)
+int first, last;
+{
+  char buf[MAXLINE];
+  char *cp = buf, *str;
+  int num;
+
+  if (first <= 0 || first > last || last > lastln) return(ERR);
+  if (first == last) {
+        curln = first;
+        return 0;
+  }
+  for (num = first; num <= last; num++) {
+        str = gettxt(num);
+
+        while (*str != NL && cp < buf + MAXLINE - 1) *cp++ = *str++;
+
+        if (cp == buf + MAXLINE - 1) {
+                printf("line too long\n");
+                return(ERR);
+        }
+  }
+  *cp++ = NL;
+  *cp = EOS;
+  del(first, last);
+  curln = first - 1;
+  ins(buf);
+  fchanged = TRUE;
+  return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/makeed	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,1 @@
+cc1 ed.c objs.l -f=ed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/makelib	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,10 @@
+t
+-x
+* Create a library
+merge >objs.1 bitmap.r append.r catsub.r ckglob.r deflt.r del.r doprnt.r
+merge >objs.2 doread.r dowrite.r egets.r find.r getfn.r getlst.r getone.r
+merge >objs.3 getptr.r getrhs.r gettxt.r getnum.r ins.r join.r maksub.r
+merge >objs.4 move.r optpat.r set.r setbuf.r getpat.r matchs.r amatch.r unmkpat.r
+merge >objs.5 omatch.r makepat.r  dodash.r esc.r subst.r docmd.r doglob.r
+merge >objs.l objs.1 objs.2 objs.3 objs.4 objs.5
+del objs.1 objs.2 objs.3 objs.4 objs.5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/makepat.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,142 @@
+/*      makepat.c       */
+#include <stdio.h>
+#include "tools.h"
+
+/* Make a pattern template from the strinng pointed to by arg.  Stop
+ * when delim or '\000' or '\n' is found in arg.  Return a pointer to
+ * the pattern template.
+ *
+ * The pattern template used here are somewhat different than those
+ * used in the "Software Tools" book; each token is a structure of
+ * the form TOKEN (see tools.h).  A token consists of an identifier,
+ * a pointer to a string, a literal character and a pointer to another
+ * token.  This last is 0 if there is no subsequent token.
+ *
+ * The one strangeness here is caused (again) by CLOSURE which has
+ * to be put in front of the previous token.  To make this insertion a
+ * little easier, the 'next' field of the last to point at the chain
+ * (the one pointed to by 'tail) is made to point at the previous node.
+ * When we are finished, tail->next is set to 0.
+ */
+TOKEN *
+ makepat(arg, delim)
+char *arg;
+int delim;
+{
+  TOKEN *head, *tail, *ntok;
+  int error;
+
+  /* Check for characters that aren't legal at the beginning of a template. */
+
+  if (*arg == '\0' || *arg == delim || *arg == '\n' || *arg == CLOSURE)
+        return(0);
+
+  error = 0;
+  tail = head = NULL;
+
+  while (*arg && *arg != delim && *arg != '\n' && !error) {
+        ntok = (TOKEN *) malloc(TOKSIZE);
+        ntok->lchar = '\000';
+        ntok->next = 0;
+
+        switch (*arg) {
+            case ANY:   ntok->tok = ANY;        break;
+
+            case BOL:
+                if (head == 0)  /* then this is the first symbol */
+                        ntok->tok = BOL;
+                else
+                        ntok->tok = LITCHAR;
+                ntok->lchar = BOL;
+                break;
+
+            case EOL:
+                if (*(arg + 1) == delim || *(arg + 1) == '\000' ||
+                    *(arg + 1) == '\n') {
+                        ntok->tok = EOL;
+                } else {
+                        ntok->tok = LITCHAR;
+                        ntok->lchar = EOL;
+                }
+                break;
+
+            case CLOSURE:
+                if (head != 0) {
+                        switch (tail->tok) {
+                            case BOL:
+                            case EOL:
+                            case CLOSURE:
+                                return(0);
+
+                            default:
+                                ntok->tok = CLOSURE;
+                        }
+                }
+                break;
+
+            case CCL:
+
+                if (*(arg + 1) == NEGATE) {
+                        ntok->tok = NCCL;
+                        arg += 2;
+                } else {
+                        ntok->tok = CCL;
+                        arg++;
+                }
+
+                if (ntok->bitmap = makebitmap(CLS_SIZE))
+                        arg = dodash(CCLEND, arg, ntok->bitmap);
+                else {
+                        fprintf(stderr, "Not enough memory for pat\n");
+                        error = 1;
+                }
+                break;
+
+            default:
+                if (*arg == ESCAPE && *(arg + 1) == OPEN) {
+                        ntok->tok = OPEN;
+                        arg++;
+                } else if (*arg == ESCAPE && *(arg + 1) == CLOSE) {
+                        ntok->tok = CLOSE;
+                        arg++;
+                } else {
+                        ntok->tok = LITCHAR;
+                        ntok->lchar = esc(&arg);
+                }
+        }
+
+        if (error || ntok == 0) {
+                unmakepat(head);
+                return(0);
+        } else if (head == 0) {
+                /* This is the first node in the chain. */
+
+                ntok->next = 0;
+                head = tail = ntok;
+        } else if (ntok->tok != CLOSURE) {
+                /* Insert at end of list (after tail) */
+
+                tail->next = ntok;
+                ntok->next = tail;
+                tail = ntok;
+        } else if (head != tail) {
+                /* More than one node in the chain.  Insert the
+                 * CLOSURE node immediately in front of tail. */
+
+                (tail->next)->next = ntok;
+                ntok->next = tail;
+        } else {
+                /* Only one node in the chain,  Insert the CLOSURE
+                 * node at the head of the linked list. */
+
+                ntok->next = head;
+                tail->next = ntok;
+                head = ntok;
+        }
+        arg++;
+  }
+
+  tail->next = 0;
+  return(head);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/maksub.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,68 @@
+/*      maksub.c        */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+char *
+ maksub(sub, subsz)
+char *sub;
+int subsz;
+{
+  int size;
+  char delim, *cp;
+
+  size = 0;
+  cp = sub;
+
+  delim = *inptr++;
+  for (size = 0; *inptr != delim && *inptr != NL && size < subsz; size++) {
+        if (*inptr == '&') {
+                *cp++ = DITTO;
+                inptr++;
+        } else if ((*cp++ = *inptr++) == ESCAPE) {
+                if (size >= subsz) return(NULL);
+
+                switch (toupper(*inptr)) {
+                    case NL:    *cp++ = ESCAPE;         break;
+                        break;
+                    case 'S':
+                        *cp++ = SP;
+                        inptr++;
+                        break;
+                    case 'N':
+                        *cp++ = NL;
+                        inptr++;
+                        break;
+                    case 'T':
+                        *cp++ = HT;
+                        inptr++;
+                        break;
+                    case 'B':
+                        *cp++ = BS;
+                        inptr++;
+                        break;
+                    case 'R':
+                        *cp++ = CR;
+                        inptr++;
+                        break;
+                    case '0':{
+                                int i = 3;
+                                *cp = 0;
+                                do {
+                                        if (*++inptr < '0' || *inptr > '7')
+                                                break;
+
+                                        *cp = (*cp << 3) | (*inptr - '0');
+                                } while (--i != 0);
+                                cp++;
+                        } break;
+                    default:    *cp++ = *inptr++;       break;
+                }
+        }
+  }
+  if (size >= subsz) return(NULL);
+
+  *cp = EOS;
+  return(sub);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/matchs.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,88 @@
+/*      matchs.c        */
+#include <stdio.h>
+#include "tools.h"
+
+/* Compares line and pattern.  Line is a character string while pat
+ * is a pattern template made by getpat().
+ * Returns:
+ *      1. A zero if no match was found.
+ *
+ *      2. A pointer to the last character satisfing the match
+ *         if ret_endp is non-zero.
+ *
+ *      3. A pointer to the beginning of the matched string if
+ *         ret_endp is zero.
+ *
+ * e.g.:
+ *
+ *      matchs ("1234567890", getpat("4[0-9]*7), 0);
+ * will return a pointer to the '4', while:
+ *
+ *      matchs ("1234567890", getpat("4[0-9]*7), 1);
+ * will return a pointer to the '7'.
+ */
+char *
+ matchs(line, pat, ret_endp)
+char *line;
+TOKEN *pat;
+int ret_endp;
+{
+
+  char *rval, *bptr;
+  char *line2;
+  TOKEN *pat2;
+  char c;
+  short ok;
+
+  bptr = line;
+
+  while (*line) {
+
+        if (pat && pat->tok == LITCHAR) {
+                while (*line) {
+                        pat2 = pat;
+                        line2 = line;
+                        if (*line2 != pat2->lchar) {
+                                c = pat2->lchar;
+                                while (*line2 && *line2 != c) ++line2;
+                                line = line2;
+                                if (*line2 == '\0') break;
+                        }
+                        ok = 1;
+                        ++line2;
+                        pat2 = pat2->next;
+                        while (pat2 && pat2->tok == LITCHAR) {
+                                if (*line2 != pat2->lchar) {
+                                        ok = 0;
+                                        break;
+                                }
+                                ++line2;
+                                pat2 = pat2->next;
+                        }
+                        if (!pat2) {
+                                if (ret_endp)
+                                        return(--line2);
+                                else
+                                        return(line);
+                        } else if (ok)
+                                break;
+                        ++line;
+                }
+                if (*line == '\0') return(0);
+        } else {
+                line2 = line;
+                pat2 = pat;
+        }
+        if ((rval = amatch(line2, pat2, bptr)) == 0) {
+                if (pat && pat->tok == BOL) break;
+                line++;
+        } else {
+                if (rval > bptr && rval > line)
+                        rval--; /* point to last char matched */
+                rval = ret_endp ? rval : line;
+                break;
+        }
+  }
+  return(rval);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/move.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,60 @@
+/*      move.c  */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+int move(num)
+int num;
+{
+  LINE *k0, *k1, *k2, *k3;
+
+  if (line1 <= 0 || line2 < line1 || (line1 <= num && num <= line2))
+        return(ERR);
+  k0 = getptr(prevln(line1));
+  k1 = getptr(line1);
+  k2 = getptr(line2);
+  k3 = getptr(nextln(line2));
+
+  relink(k0, k3, k0, k3);
+  lastln -= line2 - line1 + 1;
+
+  if (num > line1) num -= line2 - line1 + 1;
+
+  curln = num + (line2 - line1 + 1);
+
+  k0 = getptr(num);
+  k3 = getptr(nextln(num));
+
+  relink(k0, k1, k2, k3);
+  relink(k2, k3, k0, k1);
+  lastln += line2 - line1 + 1;
+
+  return(1);
+}
+
+int transfer(num)
+int num;
+{
+  int mid, lin, ntrans;
+
+  if (line1 <= 0 || line1 > line2) return(ERR);
+
+  mid = num < line2 ? num : line2;
+
+  curln = num;
+  ntrans = 0;
+
+  for (lin = line1; lin <= mid; lin++) {
+        ins(gettxt(lin));
+        ntrans++;
+  }
+  lin += ntrans;
+  line2 += ntrans;
+
+  for (; lin <= line2; lin += 2) {
+        ins(gettxt(lin));
+        line2++;
+  }
+  return(1);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/omatch.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,53 @@
+/*      omatch.c        */
+#include <stdio.h>
+#include "tools.h"
+
+/* Match one pattern element, pointed at by pat, with the character at
+ * **linp.  Return non-zero on match.  Otherwise, return 0.  *Linp is
+ * advanced to skip over the matched character; it is not advanced on
+ * failure.  The amount of advance is 0 for patterns that match null
+ * strings, 1 otherwise.  "boln" should point at the position that will
+ * match a BOL token.
+ */
+int omatch(linp, pat, boln)
+char **linp;
+TOKEN *pat;
+char *boln;
+{
+
+  register int advance;
+
+  advance = -1;
+
+  if (**linp) {
+        switch (pat->tok) {
+            case LITCHAR:
+                if (**linp == pat->lchar) advance = 1;
+                break;
+
+            case BOL:
+                if (*linp == boln) advance = 0;
+                break;
+
+            case ANY:
+                if (**linp != '\n') advance = 1;
+                break;
+
+            case EOL:
+                if (**linp == '\n') advance = 0;
+                break;
+
+            case CCL:
+                if (testbit(**linp, pat->bitmap)) advance = 1;
+                break;
+
+            case NCCL:
+                if (!testbit(**linp, pat->bitmap)) advance = 1;
+                break;
+        }
+  }
+  if (advance >= 0) *linp += advance;
+
+  return(++advance);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/optpat.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,26 @@
+/*      optpat.c        */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+TOKEN *oldpat;
+
+TOKEN *
+ optpat()
+{
+  char delim, str[MAXPAT], *cp;
+
+  delim = *inptr++;
+  cp = str;
+  while (*inptr != delim && *inptr != NL) {
+        if (*inptr == ESCAPE && inptr[1] != NL) *cp++ = *inptr++;
+        *cp++ = *inptr++;
+  }
+
+  *cp = EOS;
+  if (*str == EOS) return(oldpat);
+  if (oldpat) unmakepat(oldpat);
+  oldpat = getpat(str);
+  return(oldpat);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/set.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,56 @@
+/*      set.c   */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+struct tbl {
+  char *t_str;
+  int *t_ptr;
+  int t_val;
+} *t, tbl[] = {
+
+  "number", &nflg, TRUE,
+  "nonumber", &nflg, FALSE,
+  "list", &lflg, TRUE,
+  "nolist", &lflg, FALSE,
+  "eightbit", &eightbit, TRUE,
+  "noeightbit", &eightbit, FALSE,
+  0
+};
+
+int set()
+{
+  char word[16];
+  int i;
+
+  inptr++;
+  if (*inptr != 't') {
+        if (*inptr != SP && *inptr != HT && *inptr != NL) return(ERR);
+  } else
+        inptr++;
+
+  if (*inptr == NL) return(show());
+  /* Skip white space */
+  while (*inptr == SP || *inptr == HT) inptr++;
+
+  for (i = 0; *inptr != SP && *inptr != HT && *inptr != NL;)
+        word[i++] = *inptr++;
+  word[i] = EOS;
+  for (t = tbl; t->t_str; t++) {
+        if (strcmp(word, t->t_str) == 0) {
+                *t->t_ptr = t->t_val;
+                return(0);
+        }
+  }
+  return(0);
+}
+
+int show()
+{
+  extern int version;
+
+  printf("ed version %d.%d\n", version / 100, version % 100);
+  printf("number %s, list %s\n", nflg ? "ON" : "OFF", lflg ? "ON" : "OFF");
+  return(0);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/setbuf.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,23 @@
+/*      setbuf.c        */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+relink(a, x, y, b)
+LINE *a, *x, *y, *b;
+{
+  x->l_prev = a;
+  y->l_next = b;
+}
+
+clrbuf()
+{
+  del(1, lastln);
+}
+
+set_buf()
+{
+  relink(&line0, &line0, &line0, &line0);
+  curln = lastln = 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/subst.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,53 @@
+/*      subst.c */
+#include <stdio.h>
+#include "tools.h"
+#include "ed.h"
+
+int subst(pat, sub, gflg, pflag)
+TOKEN *pat;
+char *sub;
+int gflg, pflag;
+{
+  int lin, chngd, nchngd;
+  char *txtptr, *txt;
+  char *lastm, *m, *new, buf[MAXLINE];
+
+  if (line1 <= 0) return(ERR);
+  nchngd = 0;                   /* reset count of lines changed */
+  for (lin = line1; lin <= line2; lin++) {
+        txt = txtptr = gettxt(lin);
+        new = buf;
+        chngd = 0;
+        lastm = NULL;
+        while (*txtptr) {
+                if (gflg || !chngd)
+                        m = amatch(txtptr, pat, txt);
+                else
+                        m = NULL;
+                if (m != NULL && lastm != m) {
+                        chngd++;
+                        new = catsub(txtptr, m, sub, new,
+                                     buf + MAXLINE);
+                        lastm = m;
+                }
+                if (m == NULL || m == txtptr) {
+                        *new++ = *txtptr++;
+                } else {
+                        txtptr = m;
+                }
+        }
+        if (chngd) {
+                if (new >= buf + MAXLINE) return(ERR);
+                *new++ = EOS;
+                del(lin, lin);
+                ins(buf);
+                nchngd++;
+                if (pflag) doprnt(curln, curln);
+        }
+  }
+  if (nchngd == 0 && !gflg) {
+        return(ERR);
+  }
+  return(nchngd);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/tools.h	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,97 @@
+/*      tools.h */
+/*
+ *      #defines for non-printing ASCII characters
+ */
+
+#define NUL     0x00            /* ^@ */
+#define EOS     0x00            /* end of string */
+#define SOH     0x01            /* ^A */
+#define STX     0x02            /* ^B */
+#define ETX     0x03            /* ^C */
+#define EOT     0x04            /* ^D */
+#define ENQ     0x05            /* ^E */
+#define ACK     0x06            /* ^F */
+#define BEL     0x07            /* ^G */
+#define BS      0x08            /* ^H */
+#define HT      0x09            /* ^I */
+#define LF      0x0a            /* ^J */
+#define NL      '\n'
+#define VT      0x0b            /* ^K */
+#define FF      0x0c            /* ^L */
+#define CR      0x0d            /* ^M */
+#define SO      0x0e            /* ^N */
+#define SI      0x0f            /* ^O */
+#define DLE     0x10            /* ^P */
+#define DC1     0x11            /* ^Q */
+#define DC2     0x12            /* ^R */
+#define DC3     0x13            /* ^S */
+#define DC4     0x14            /* ^T */
+#define NAK     0x15            /* ^U */
+#define SYN     0x16            /* ^V */
+#define ETB     0x17            /* ^W */
+#define CAN     0x18            /* ^X */
+#define EM      0x19            /* ^Y */
+#define SUB     0x1a            /* ^Z */
+#define ESC     0x1b            /* ^[ */
+#define FS      0x1c            /* ^\ */
+#define GS      0x1d            /* ^] */
+#define RS      0x1e            /* ^^ */
+#define US      0x1f            /* ^_ */
+#define SP      0x20            /* space */
+#define DEL     0x7f            /* DEL */
+
+#define TRUE    1
+#define FALSE   0
+#define ERR     -2
+
+/*      Definitions of meta-characters used in pattern matching
+ *      routines.  LITCHAR & NCCL are only used as token identifiers;
+ *      all the others are also both token identifier and actual symbol
+ *      used in the regular expression.
+ */
+
+#define BOL     '^'
+#define EOL     '$'
+#define ANY     '.'
+#define LITCHAR 'L'
+#define ESCAPE  '\\'
+#define CCL     '['             /* Character class: [...] */
+#define CCLEND  ']'
+#define NEGATE  '~'
+#define NCCL    '!'             /* Negative character class [^...] */
+#define CLOSURE '*'
+#define OR_SYM  '|'
+#define DITTO   '&'
+#define OPEN    '('
+#define CLOSE   ')'
+
+/* Largest permitted size for an expanded character class.  (i.e. the class
+ * [a-z] will expand into 26 symbols; [a-z0-9] will expand into 36.)
+ */
+#define CLS_SIZE        128
+
+/*
+ *      Tokens are used to hold pattern templates. (see makepat())
+ */
+typedef char BITMAP;
+
+typedef struct token {
+  char tok;
+  char lchar;
+  BITMAP *bitmap;
+  struct token *next;
+} TOKEN;
+
+#define TOKSIZE sizeof (TOKEN)
+
+/*
+ *      An absolute maximun for strings.
+ */
+
+#define MAXSTR  132             /* Maximum numbers of characters in a line */
+
+/* Macros */
+#define max(a,b)        ((a>b)?a:b)
+#define min(a,b)        ((a<b)?a:b)
+#define toupper(c)      (c>='a'&&c<='z'?c-32:c)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/ed/unmkpat.c	Sun Feb 23 21:11:37 2003 +0000
@@ -0,0 +1,26 @@
+/*      unmkpat.c       */
+#include <stdio.h>
+#include "tools.h"
+
+/* Free up the memory usde for token string */
+unmakepat(head)
+TOKEN *head;
+{
+
+  register TOKEN *old_head;
+
+  while (head) {
+        switch (head->tok) {
+            case CCL:
+            case NCCL:
+                free(head->bitmap);
+                /* Fall through to default */
+
+            default:
+                old_head = head;
+                head = head->next;
+                free((char *) old_head);
+                break;
+        }
+  }
+}