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

  1. /* buf.c: This file contains the scratch-file buffer rountines for the
  2.    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: buf.c,v 1.6 1994/04/19 06:23:59 alm Exp alm $";
  24. #endif /* not lint */
  25.  
  26. #include "ed.h"
  27.  
  28. #include <sys/file.h>
  29. #include <sys/stat.h>
  30.  
  31.  
  32. FILE *sfp;            /* scratch file pointer */
  33. off_t sfseek;            /* scratch file position */
  34. int seek_write;            /* seek before writing */
  35. line_t buffer_head;        /* incore buffer */
  36.  
  37. /* get_sbuf_line: get a line of text from the scratch file; return pointer
  38.    to the text */
  39. char *
  40. get_sbuf_line (lp)
  41.      line_t *lp;
  42. {
  43.   static char *sfbuf = NULL;    /* buffer */
  44.   static int sfbufsz = 0;    /* buffer size */
  45.  
  46.   int len, ct;
  47.  
  48.   if (lp == &buffer_head)
  49.     return NULL;
  50.   seek_write = 1;        /* force seek on write */
  51.   /* out of position */
  52.   if (sfseek != lp->seek)
  53.     {
  54.       sfseek = lp->seek;
  55.       if (fseek (sfp, sfseek, SEEK_SET) < 0)
  56.     {
  57.       fprintf (stderr, "%s\n", strerror (errno));
  58.       sprintf (errmsg, "cannot seek temp file");
  59.       return NULL;
  60.     }
  61.     }
  62.   len = lp->len;
  63.   REALLOC (sfbuf, sfbufsz, len + 1, NULL);
  64.   if ((ct = fread (sfbuf, sizeof (char), len, sfp)) < 0 || ct != len)
  65.     {
  66.       fprintf (stderr, "%s\n", strerror (errno));
  67.       sprintf (errmsg, "cannot read temp file");
  68.       return NULL;
  69.     }
  70.   sfseek += len;        /* update file position */
  71.   sfbuf[len] = '\0';
  72.   return sfbuf;
  73. }
  74.  
  75.  
  76. /* put_sbuf_line: write a line of text to the scratch file and add a line node
  77.    to the editor buffer;  return a pointer to the end of the text */
  78. char *
  79. put_sbuf_line (cs)
  80.      char *cs;
  81. {
  82.   line_t *lp;
  83.   int len, ct;
  84.   char *s;
  85.  
  86.   if ((lp = (line_t *) malloc (sizeof (line_t))) == NULL)
  87.     {
  88.       fprintf (stderr, "%s\n", strerror (errno));
  89.       sprintf (errmsg, "out of memory");
  90.       return NULL;
  91.     }
  92.   /* assert: cs is '\n' terminated */
  93.   for (s = cs; *s != '\n'; s++)
  94.     ;
  95.   if (s - cs >= LINECHARS)
  96.     {
  97.       sprintf (errmsg, "line too long");
  98.       return NULL;
  99.     }
  100.   len = s - cs;
  101.   /* out of position */
  102.   if (seek_write)
  103.     {
  104.       if (fseek (sfp, 0L, SEEK_END) < 0)
  105.     {
  106.       fprintf (stderr, "%s\n", strerror (errno));
  107.       sprintf (errmsg, "cannot seek temp file");
  108.       return NULL;
  109.     }
  110.       sfseek = ftell (sfp);
  111.       seek_write = 0;
  112.     }
  113.   /* assert: SPL1() */
  114.   if ((ct = fwrite (cs, sizeof (char), len, sfp)) < 0 || ct != len)
  115.     {
  116.       sfseek = -1;
  117.       fprintf (stderr, "%s\n", strerror (errno));
  118.       sprintf (errmsg, "cannot write temp file");
  119.       return NULL;
  120.     }
  121.   lp->len = len;
  122.   lp->seek = sfseek;
  123.   add_line_node (lp);
  124.   sfseek += len;        /* update file position */
  125.   return ++s;
  126. }
  127.  
  128.  
  129. /* add_line_node: add a line node in the editor buffer after the current line */
  130. void
  131. add_line_node (lp)
  132.      line_t *lp;
  133. {
  134.   line_t *cp;
  135.  
  136.   cp = get_addressed_line_node (current_addr);    /* this get_addressed_line_node last! */
  137.   INSQUE (lp, cp);
  138.   addr_last++;
  139.   current_addr++;
  140. }
  141.  
  142.  
  143. /* get_line_node_addr: return line number of pointer */
  144. long
  145. get_line_node_addr (lp)
  146.      line_t *lp;
  147. {
  148.   line_t *cp = &buffer_head;
  149.   long n = 0;
  150.  
  151.   while (cp != lp && (cp = cp->q_forw) != &buffer_head)
  152.     n++;
  153.   if (n && cp == &buffer_head)
  154.     {
  155.       sprintf (errmsg, "invalid address");
  156.       return ERR;
  157.     }
  158.   return n;
  159. }
  160.  
  161.  
  162. /* get_addressed_line_node: return pointer to a line node in the editor buffer */
  163. line_t *
  164. get_addressed_line_node (n)
  165.      long n;
  166. {
  167.   static line_t *lp = &buffer_head;
  168.   static long on = 0;
  169.  
  170.   SPL1 ();
  171.   if (n > on)
  172.     if (n <= (on + addr_last) >> 1)
  173.       for (; on < n; on++)
  174.     lp = lp->q_forw;
  175.     else
  176.       {
  177.     lp = buffer_head.q_back;
  178.     for (on = addr_last; on > n; on--)
  179.       lp = lp->q_back;
  180.       }
  181.   else if (n >= on >> 1)
  182.     for (; on > n; on--)
  183.       lp = lp->q_back;
  184.   else
  185.     {
  186.       lp = &buffer_head;
  187.       for (on = 0; on < n; on++)
  188.     lp = lp->q_forw;
  189.     }
  190.   SPL0 ();
  191.   return lp;
  192. }
  193.  
  194.  
  195. extern int newline_added;
  196.  
  197. char sfn[15] = "";        /* scratch file name */
  198.  
  199. /* open_sbuf: open scratch file */
  200. int
  201. open_sbuf ()
  202. {
  203.   char *mktemp ();
  204.   int u;
  205.  
  206.   isbinary = newline_added = 0;
  207.   u = umask(077);
  208.   strcpy (sfn, "/tmp/ed.XXXXXX");
  209.   if (mktemp (sfn) == NULL || (sfp = fopen (sfn, "w+")) == NULL)
  210.     {
  211.       fprintf (stderr, "%s: %s\n", sfn, strerror (errno));
  212.       sprintf (errmsg, "cannot open temp file");
  213.       umask(u);
  214.       return ERR;
  215.     }
  216.   umask(u);
  217.   return 0;
  218. }
  219.  
  220.  
  221. /* close_sbuf: close scratch file */
  222. int
  223. close_sbuf ()
  224. {
  225.   if (sfp)
  226.     {
  227.       if (fclose (sfp) < 0)
  228.     {
  229.       fprintf (stderr, "%s: %s\n", sfn, strerror (errno));
  230.       sprintf (errmsg, "cannot close temp file");
  231.       return ERR;
  232.     }
  233.       sfp = NULL;
  234.       unlink (sfn);
  235.     }
  236.   sfseek = seek_write = 0;
  237.   return 0;
  238. }
  239.  
  240.  
  241. /* quit: remove_lines scratch file and exit */
  242. void
  243. quit (n)
  244.      int n;
  245. {
  246.   if (sfp)
  247.     {
  248.       fclose (sfp);
  249.       unlink (sfn);
  250.     }
  251.   exit (n);
  252. }
  253.  
  254.  
  255. extern char *old_filename;
  256. unsigned char ctab[256];    /* character translation table */
  257.  
  258. /* init_buffers: open scratch buffer; initialize line queue */
  259. void
  260. init_buffers ()
  261. {
  262.   int i = 0;
  263.  
  264.   /* Read stdin one character at a time to avoid i/o contention
  265.      with shell escapes invoked by nonterminal input, e.g.,
  266.      ed - <<EOF
  267.      !cat
  268.      hello, world
  269.      EOF */
  270. #ifdef HAVE_SETBUFFER
  271.   setbuffer (stdin, stdinbuf, 1);
  272. #else
  273.   setvbuf (stdin, stdinbuf, _IONBF, 0);
  274. #endif
  275.   if ((errmsg = (char *) malloc (ERRSZ)) == NULL ||
  276.       (old_filename = (char *) malloc (PATH_MAX + 1)) == NULL)
  277.     {
  278.       fprintf (stderr, "%s\n", strerror (errno));
  279.       quit (2);
  280.     }
  281.   old_filename[0] = '\0';
  282.   if (open_sbuf () < 0)
  283.     quit (2);
  284.   REQUE (&buffer_head, &buffer_head);
  285.   for (i = 0; i < 256; i++)
  286.     ctab[i] = i;
  287.  
  288. }
  289.  
  290.  
  291. /* translit_text: translate characters in a string */
  292. char *
  293. translit_text (s, len, from, to)
  294.      char *s;
  295.      int len;
  296.      int from;
  297.      int to;
  298. {
  299.   static int i = 0;
  300.  
  301.   unsigned char *us;
  302.  
  303.   ctab[i] = i;            /* restore table to initial state */
  304.   ctab[i = from] = to;
  305.   for (us = (unsigned char *) s; len-- > 0; us++)
  306.     *us = ctab[*us];
  307.   return s;
  308. }
  309.