home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume37 / ed / part02 / buf.c next >
Encoding:
C/C++ Source or Header  |  1993-06-01  |  5.9 KB  |  247 lines

  1. /* buf.c: This file contains the scratch-file buffer rountines for the
  2.    ed line editor. */
  3. /*-
  4.  * Copyright (c) 1992 The Regents of the University of California.
  5.  * All rights reserved.
  6.  *
  7.  * This code is derived from software contributed to Berkeley by
  8.  * Rodney Ruddock of the University of Guelph.
  9.  *
  10.  * Redistribution and use in source and binary forms, with or without
  11.  * modification, are permitted provided that the following conditions
  12.  * are met:
  13.  * 1. Redistributions of source code must retain the above copyright
  14.  *    notice, this list of conditions and the following disclaimer.
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in the
  17.  *    documentation and/or other materials provided with the distribution.
  18.  * 3. All advertising materials mentioning features or use of this software
  19.  *    must display the following acknowledgement:
  20.  *    This product includes software developed by the University of
  21.  *    California, Berkeley and its contributors.
  22.  * 4. Neither the name of the University nor the names of its contributors
  23.  *    may be used to endorse or promote products derived from this software
  24.  *    without specific prior written permission.
  25.  *
  26.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  27.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  30.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  32.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  33.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  34.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  35.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  36.  * SUCH DAMAGE.
  37.  */
  38.  
  39. #ifndef lint
  40. static char sccsid[] = "@(#)buf.c    5.5 (Berkeley) 3/28/93";
  41. #endif /* not lint */
  42.  
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <string.h>
  46. #include <sys/file.h>
  47. #include <unistd.h>
  48.  
  49. #include "ed.h"
  50.  
  51. extern char errmsg[];
  52. extern line_t line0;
  53.  
  54. FILE *sfp;                /* scratch file pointer */
  55. char *sfbuf = NULL;            /* scratch file input buffer */
  56. int sfbufsz = 0;            /* scratch file input buffer size */
  57. off_t sfseek;                /* scratch file position */
  58. int seek_write;                /* seek before writing */
  59.  
  60. /* gettxt: get a line of text from the scratch file; return pointer
  61.    to the text */
  62. char *
  63. gettxt(lp)
  64.     line_t *lp;
  65. {
  66.     int len, ct;
  67.  
  68.     if (lp == &line0)
  69.         return NULL;
  70.     seek_write = 1;                /* force seek on write */
  71.     /* out of position */
  72.     if (sfseek != lp->seek) {
  73.         sfseek = lp->seek;
  74.         if (fseek(sfp, sfseek, SEEK_SET) < 0) {
  75.             fprintf(stderr, "%s\n", strerror(errno));
  76.             sprintf(errmsg, "cannot seek temp file");
  77.             return NULL;
  78.         }
  79.     }
  80.     len = lp->len & ~ACTV;
  81.     CKBUF(sfbuf, sfbufsz, len + 1, NULL);
  82.     if ((ct = fread(sfbuf, sizeof(char), len, sfp)) <  0 || ct != len) {
  83.         fprintf(stderr, "%s\n", strerror(errno));
  84.         sprintf(errmsg, "cannot read temp file");
  85.         return NULL;
  86.     }
  87.     sfseek += len;                /* update file position */
  88.     sfbuf[len] = '\0';
  89.     return sfbuf;
  90. }
  91.  
  92.  
  93. extern long curln;
  94. extern long lastln;
  95.  
  96. /* puttxt: write a line of text to the scratch file and add a line node
  97.    to the editor buffer;  return a pointer to the end of the text */
  98. char *
  99. puttxt(cs)
  100.     char *cs;
  101. {
  102.     line_t *lp;
  103.     int len, ct;
  104.     char *s;
  105.  
  106.     if ((lp = (line_t *) malloc(sizeof(line_t))) == NULL) {
  107.         fprintf(stderr, "%s\n", strerror(errno));
  108.         sprintf(errmsg, "out of memory");
  109.         return NULL;
  110.     }
  111.     /* assert: cs is '\n' terminated */
  112.     for (s = cs; *s != '\n'; s++)
  113.         ;
  114.     if (s - cs >= LINECHARS) {
  115.         sprintf(errmsg, "line too long");
  116.         return NULL;
  117.     }
  118.     len = (s - cs) & ~ACTV;
  119.     /* out of position */
  120.     if (seek_write) {
  121.         if (fseek(sfp, 0L, SEEK_END) < 0) {
  122.             fprintf(stderr, "%s\n", strerror(errno));
  123.             sprintf(errmsg, "cannot seek temp file");
  124.             return NULL;
  125.         }
  126.         sfseek = ftell(sfp);
  127.         seek_write = 0;
  128.     }
  129.     /* assert: spl1() */
  130.     if ((ct = fwrite(cs, sizeof(char), len, sfp)) < 0 || ct != len) {
  131.         sfseek = -1;
  132.         fprintf(stderr, "%s\n", strerror(errno));
  133.         sprintf(errmsg, "cannot write temp file");
  134.         return NULL;
  135.     }
  136.     lp->len = len;
  137.     lp->seek  = sfseek;
  138.     lpqueue(lp);
  139.     sfseek += len;            /* update file position */
  140.     return ++s;
  141. }
  142.  
  143.  
  144. /* lpqueue: add a line node in the editor buffer after the current line */
  145. void
  146. lpqueue(lp)
  147.     line_t *lp;
  148. {
  149.     line_t *cp;
  150.  
  151.     cp = getlp(curln);                /* this getlp last! */
  152.     insqueue(lp, cp);
  153.     lastln++;
  154.     curln++;
  155. }
  156.  
  157.  
  158. /* getaddr: return line number of pointer */
  159. long
  160. getaddr(lp)
  161.     line_t *lp;
  162. {
  163.     line_t *cp = &line0;
  164.     long n = 0;
  165.  
  166.     while (cp != lp && (cp = cp->next) != &line0)
  167.         n++;
  168.     return (cp != &line0) ? n : 0;
  169. }
  170.  
  171.  
  172. /* getlp: return pointer to a line node in the editor buffer */
  173. line_t *
  174. getlp(n)
  175.     long n;
  176. {
  177.     static line_t *lp = &line0;
  178.     static long on = 0;
  179.  
  180.     spl1();
  181.     if (n > on)
  182.         if (n <= (on + lastln) >> 1)
  183.             for (; on < n; on++)
  184.                 lp = lp->next;
  185.         else {
  186.             lp = line0.prev;
  187.             for (on = lastln; on > n; on--)
  188.                 lp = lp->prev;
  189.         }
  190.     else
  191.         if (n >= on >> 1)
  192.             for (; on > n; on--)
  193.                 lp = lp->prev;
  194.         else {
  195.             lp = &line0;
  196.             for (on = 0; on < n; on++)
  197.                 lp = lp->next;
  198.         }
  199.     spl0();
  200.     return lp;
  201. }
  202.  
  203.  
  204. char sfn[15] = "";                /* scratch file name */
  205.  
  206. /* sbopen: open scratch file */
  207. sbopen()
  208. {
  209.     strcpy(sfn, "/tmp/ed.XXXXXX");
  210.     if (mktemp(sfn) == NULL || (sfp = fopen(sfn, "w+")) == NULL) {
  211.         fprintf(stderr, "%s: %s\n", sfn, strerror(errno));
  212.         sprintf(errmsg, "cannot open temp file");
  213.         return ERR;
  214.     }
  215.     return 0;
  216. }
  217.  
  218.  
  219. /* sbclose: close scratch file */
  220. sbclose()
  221. {
  222.     if (sfp) {
  223.         if (fclose(sfp) < 0) {
  224.             fprintf(stderr, "%s: %s\n", sfn, strerror(errno));
  225.             sprintf(errmsg, "cannot close temp file");
  226.             return ERR;
  227.         }
  228.         sfp = NULL;
  229.         unlink(sfn);
  230.     }
  231.     sfseek = seek_write = 0;
  232.     return 0;
  233. }
  234.  
  235.  
  236. /* quit: remove scratch file and exit */
  237. void
  238. quit(n)
  239.     int n;
  240. {
  241.     if (sfp) {
  242.         fclose(sfp);
  243.         unlink(sfn);
  244.     }
  245.     exit(n);
  246. }
  247.