1 /*- 2 * Copyright (c) 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Rodney Ruddock of the University of Guelph. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 static char sccsid[] = "@(#)w.c 5.4 (Berkeley) 03/08/93"; 13 #endif /* not lint */ 14 15 #include <sys/types.h> 16 17 #include <regex.h> 18 #include <setjmp.h> 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <string.h> 22 23 #ifdef DBI 24 #include <db.h> 25 #endif 26 27 #include "ed.h" 28 #include "extern.h" 29 30 /* 31 * Write the contents of the buffer out to the real file (spec'd or 32 * remembered). If 'w' then overwrite, if 'W' append to the file. 'W' 33 * is probably _the_ command that most editors don't have, and it's 34 * so(!) useful. The 'wq' works as 'w' but 'q' immediately follows. 35 * Shame on POSIX for not including 'W' and 'wq', they're not that 36 * hard to implement; yaaa! BSD for keeping it! :-) 37 */ 38 void 39 w(inputt, errnum) 40 FILE *inputt; 41 int *errnum; 42 { 43 FILE *fp; 44 int l_ttl = 0, l_q_flag = 0, l_sl; 45 char *filename_read=NULL, *temp; 46 47 if (Start_default && End_default) { 48 Start = top; 49 End = bottom; 50 } else 51 if (Start_default) 52 Start = End; 53 if (Start == NULL) { 54 strcpy(help_msg, "buffer empty"); 55 *errnum = -1; 56 return; 57 } 58 Start_default = End_default = 0; 59 60 l_sl = ss; 61 ss = getc(inputt); 62 63 if (ss == 'q') /* "wq" and "Wq" command */ 64 l_q_flag = 1; 65 else 66 ungetc(ss, inputt); 67 68 temp = filename(inputt, errnum); 69 if (*errnum == 1) 70 filename_read = temp; 71 else 72 if (*errnum == -2) { 73 while (((ss = getc(inputt)) != '\n') || (ss == EOF)); 74 filename_read = filename_current; 75 } else 76 if (*errnum < 0) 77 return; 78 *errnum = 0; 79 80 if (filename_current == NULL) { 81 if (filename_read == NULL) { 82 strcpy(help_msg, "no filename given"); 83 *errnum = -1; 84 ungetc('\n', inputt); 85 return; 86 } else 87 filename_current = filename_read; 88 } 89 sigspecial++; 90 if (l_sl == 'W') 91 fp = fopen(filename_read, "a"); 92 else 93 fp = fopen(filename_read, "w"); 94 95 if (fp == NULL) { 96 strcpy(help_msg, "cannot write to file"); 97 *errnum = -1; 98 ungetc('\n', inputt); 99 return; 100 } 101 sigspecial--; 102 if (sigint_flag && (!sigspecial)) 103 goto point; 104 105 /* Write it out and get a report on the number of bytes written. */ 106 l_ttl = edwrite(fp, Start, End); 107 if (explain_flag != 0) /* For -s option. */ 108 printf("%d\n", l_ttl); 109 110 point: fclose(fp); 111 if (filename_read != filename_current) 112 free(filename_read); 113 change_flag = 0L; 114 *errnum = 1; 115 if (l_q_flag) { /* For "wq" and "Wq". */ 116 ungetc('\n', inputt); 117 ss = (int) 'q'; 118 q(inputt, errnum); 119 } 120 } 121 122 /* 123 * Actually writes out the contents of the buffer to the specified 124 * STDIO file pointer for the range of lines specified. 125 */ 126 int 127 edwrite(fp, begi, fini) 128 FILE *fp; 129 LINE *begi, *fini; 130 { 131 register int l_ttl = 0; 132 133 for (;;) { 134 get_line(begi->handle, begi->len); 135 if (sigint_flag && (!sigspecial)) 136 break; 137 138 sigspecial++; 139 /* Fwrite is about 20+% faster than fprintf -- no surprise. */ 140 fwrite(text, sizeof(char), begi->len, fp); 141 fputc('\n', fp); 142 l_ttl = l_ttl + (begi->len) + 1; 143 if (begi == fini) 144 break; 145 else 146 begi = begi->below; 147 sigspecial--; 148 if (sigint_flag && (!sigspecial)) 149 break; 150 } 151 return (l_ttl); 152 } 153