buf.c revision 49
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 40static 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 51extern char errmsg[]; 52extern line_t line0; 53 54FILE *sfp; /* scratch file pointer */ 55char *sfbuf = NULL; /* scratch file input buffer */ 56int sfbufsz = 0; /* scratch file input buffer size */ 57off_t sfseek; /* scratch file position */ 58int seek_write; /* seek before writing */ 59 60/* gettxt: get a line of text from the scratch file; return pointer 61 to the text */ 62char * 63gettxt(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 93extern long curln; 94extern 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 */ 98char * 99puttxt(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 */ 145void 146lpqueue(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 */ 159long 160getaddr(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 if (n && cp == &line0) { 169 sprintf(errmsg, "invalid address"); 170 return ERR; 171 } 172 return n; 173} 174 175 176/* getlp: return pointer to a line node in the editor buffer */ 177line_t * 178getlp(n) 179 long n; 180{ 181 static line_t *lp = &line0; 182 static long on = 0; 183 184 spl1(); 185 if (n > on) 186 if (n <= (on + lastln) >> 1) 187 for (; on < n; on++) 188 lp = lp->next; 189 else { 190 lp = line0.prev; 191 for (on = lastln; on > n; on--) 192 lp = lp->prev; 193 } 194 else 195 if (n >= on >> 1) 196 for (; on > n; on--) 197 lp = lp->prev; 198 else { 199 lp = &line0; 200 for (on = 0; on < n; on++) 201 lp = lp->next; 202 } 203 spl0(); 204 return lp; 205} 206 207 208char sfn[15] = ""; /* scratch file name */ 209 210/* sbopen: open scratch file */ 211sbopen() 212{ 213 strcpy(sfn, "/tmp/ed.XXXXXX"); 214 if (mktemp(sfn) == NULL || (sfp = fopen(sfn, "w+")) == NULL) { 215 fprintf(stderr, "%s: %s\n", sfn, strerror(errno)); 216 sprintf(errmsg, "cannot open temp file"); 217 return ERR; 218 } 219 return 0; 220} 221 222 223/* sbclose: close scratch file */ 224sbclose() 225{ 226 if (sfp) { 227 if (fclose(sfp) < 0) { 228 fprintf(stderr, "%s: %s\n", sfn, strerror(errno)); 229 sprintf(errmsg, "cannot close temp file"); 230 return ERR; 231 } 232 sfp = NULL; 233 unlink(sfn); 234 } 235 sfseek = seek_write = 0; 236 return 0; 237} 238 239 240/* quit: remove scratch file and exit */ 241void 242quit(n) 243 int n; 244{ 245 if (sfp) { 246 fclose(sfp); 247 unlink(sfn); 248 } 249 exit(n); 250} 251