* Implement a different way to delete a password from the cache.
[alpine.git] / pico / buffer.c
blobde9e2cc06db0ea8fe4a6ddaa9574eac264d92e9b
1 /*
2 * ========================================================================
3 * Copyright 2006 University of Washington
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * ========================================================================
13 * Program: Buffer management routines
17 * Buffer management.
18 * Some of the functions are internal,
19 * and some are actually attached to user
20 * keys. Like everyone else, they set hints
21 * for the display system.
23 #include "headers.h"
25 int sgetline(char **, int *, char *, int);
29 * Look through the list of
30 * buffers. Return TRUE if there
31 * are any changed buffers. Buffers
32 * that hold magic internal stuff are
33 * not considered; who cares if the
34 * list of buffer names is hacked.
35 * Return FALSE if no buffers
36 * have been changed.
38 int
39 anycb(void)
41 register BUFFER *bp;
43 bp = bheadp;
44 while (bp != NULL) {
45 if ((bp->b_flag&BFTEMP)==0 && (bp->b_flag&BFCHG)!=0)
46 return (TRUE);
47 bp = bp->b_bufp;
49 return (FALSE);
53 * Find a buffer, by name. Return a pointer
54 * to the BUFFER structure associated with it. If
55 * the named buffer is found, but is a TEMP buffer (like
56 * the buffer list) conplain. If the buffer is not found
57 * and the "cflag" is TRUE, create it. The "bflag" is
58 * the settings for the flags in in buffer.
60 BUFFER *
61 bfind(char *bname, int cflag, int bflag)
63 register BUFFER *bp;
64 register BUFFER *sb; /* buffer to insert after */
65 register LINE *lp;
67 bp = bheadp;
68 while (bp != NULL) {
69 if (strcmp(bname, bp->b_bname) == 0) {
70 if ((bp->b_flag&BFTEMP) != 0) {
71 mlwrite_utf8("Cannot select builtin buffer", NULL);
72 return (NULL);
74 return (bp);
76 bp = bp->b_bufp;
78 if (cflag != FALSE) {
79 if ((bp=(BUFFER *)malloc(sizeof(BUFFER))) == NULL)
80 return (NULL);
81 if ((lp=lalloc(0)) == NULL) {
82 free((char *) bp);
83 return (NULL);
85 /* find the place in the list to insert this buffer */
86 if (bheadp == NULL || strcmp(bheadp->b_bname, bname) > 0) {
87 /* insert at the beginning */
88 bp->b_bufp = bheadp;
89 bheadp = bp;
90 } else {
91 sb = bheadp;
92 while (sb->b_bufp != NULL) {
93 if (strcmp(sb->b_bufp->b_bname, bname) > 0)
94 break;
95 sb = sb->b_bufp;
98 /* and insert it */
99 bp->b_bufp = sb->b_bufp;
100 sb->b_bufp = bp;
103 /* and set up the other buffer fields */
104 bp->b_active = TRUE;
105 bp->b_dotp = lp;
106 bp->b_doto = 0;
107 bp->b_markp = NULL;
108 bp->b_marko = 0;
109 bp->b_flag = bflag;
110 bp->b_mode = gmode;
111 bp->b_nwnd = 0;
112 bp->b_linep = lp;
113 strncpy(bp->b_fname, "", sizeof(bp->b_fname));
114 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
115 strncpy(bp->b_bname, bname, sizeof(bp->b_bname));
116 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
117 lp->l_fp = lp;
118 lp->l_bp = lp;
120 return (bp);
124 * This routine blows away all of the text
125 * in a buffer. If the buffer is marked as changed
126 * then we ask if it is ok to blow it away; this is
127 * to save the user the grief of losing text. The
128 * window chain is nearly always wrong if this gets
129 * called; the caller must arrange for the updates
130 * that are required. Return TRUE if everything
131 * looks good.
134 bclear(BUFFER *bp)
136 register LINE *lp;
137 register int s = FALSE;
139 if(Pmaster){
140 if ((bp->b_flag&BFTEMP) == 0 /* Not scratch buffer. */
141 && (bp->b_flag&BFCHG) != 0){ /* Something changed */
142 emlwrite("buffer lines not freed.", NULL);
143 return (s);
146 else{
147 if ((bp->b_flag&BFTEMP) == 0 /* Not scratch buffer. */
148 && (bp->b_flag&BFCHG) != 0 /* Something changed */
149 /* TRANSLATORS: A question asking whether to forget about
150 the changes and revert to the unchanged version. */
151 && (s=mlyesno_utf8(_("Discard changes"), -1)) != TRUE){
152 return (s);
156 bp->b_flag &= ~BFCHG; /* Not changed */
157 while ((lp=lforw(bp->b_linep)) != bp->b_linep)
158 lfree(lp);
159 bp->b_dotp = bp->b_linep; /* Fix "." */
160 bp->b_doto = 0;
161 bp->b_markp = NULL; /* Invalidate "mark" */
162 bp->b_marko = 0;
163 return (TRUE);
168 * packbuf - will pack up the main buffer in the buffer provided
169 * to be returned to the program that called pico.
170 * if need be, allocate memory for the new message.
171 * will also free the memory associated with the editor
172 * buffer, by calling zotedit.
175 packbuf(char **buf,
176 int *blen,
177 int lcrlf) /* EOLs are local or CRLF */
179 register int i = 0;
180 register LINE *lp;
181 register int retval = 0;
182 register char *bufp;
183 register char *eobuf;
185 if(anycb() != FALSE){
187 lp = lforw(curbp->b_linep);
188 do{ /* how many chars? */
189 i += llength(lp);
191 * add extra for new lines to be inserted later
193 i += 2;
194 lp = lforw(lp);
196 while(lp != curbp->b_linep);
198 if(i > *blen){ /* new buffer ? */
200 * don't forget to add one for the null terminator!!!
202 if((bufp = (char *)malloc((i+1)*sizeof(char))) == NULL){
203 zotedit(); /* bag it! */
204 return(COMP_FAILED);
206 free(*buf);
207 *buf = bufp;
208 *blen = i;
210 else{
211 bufp = *buf;
214 eobuf = bufp + *blen;
215 lp = lforw(curbp->b_linep); /* First line. */
216 do {
217 for (i = 0; i < llength(lp); i++){ /* copy into buffer */
218 if((bufp+1) < eobuf){
219 *bufp++ = (lp->l_text[i].c & 0xFF);
221 else{
223 * the idea is to malloc enough space for the new
224 * buffer...
226 *bufp = '\0';
227 zotedit();
228 return(BUF_CHANGED|COMP_FAILED);
231 if(lcrlf){
232 *bufp++ = '\n'; /* EOLs use local convention */
234 else{
235 *bufp++ = 0x0D; /* EOLs use net standard */
236 *bufp++ = 0x0A;
238 lp = lforw(lp);
240 while (lp != curbp->b_linep);
241 if(lcrlf)
242 *--bufp = '\0';
243 else
244 *bufp = '\0';
245 retval = BUF_CHANGED;
248 zotedit();
249 return(retval);
254 * readbuf - reads in a buffer.
256 void
257 readbuf(char **buf)
259 register LINE *lp1;
260 register LINE *lp2;
261 register BUFFER *bp;
262 register WINDOW *wp;
263 register int i;
264 register int s;
265 char *sptr; /* pointer into buffer string */
266 int nbytes;
267 char line[NLINE];
268 CELL ac;
270 bp = curbp;
271 bp->b_flag &= ~(BFTEMP|BFCHG);
272 sptr = *buf;
273 ac.a = 0;
275 while((s=sgetline(&sptr,&nbytes,line,NLINE)) == FIOSUC || s == FIOLNG){
277 if ((lp1=lalloc(nbytes)) == NULL) {
278 s = FIOERR; /* Keep message on the */
279 break; /* display. */
281 lp2 = lback(curbp->b_linep);
282 lp2->l_fp = lp1;
283 lp1->l_fp = curbp->b_linep;
284 lp1->l_bp = lp2;
285 curbp->b_linep->l_bp = lp1;
286 for (i=0; i<nbytes; ++i){
287 ac.c = line[i];
288 lputc(lp1, i, ac);
292 for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
293 if (wp->w_bufp == curbp) {
294 wheadp->w_linep = lforw(curbp->b_linep);
295 wheadp->w_dotp = lback(curbp->b_linep);
296 wheadp->w_doto = 0;
297 wheadp->w_markp = NULL;
298 wheadp->w_marko = 0;
299 wheadp->w_flag |= WFHARD;
303 strncpy(bp->b_bname, "main", sizeof(bp->b_bname));
304 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
305 strncpy(bp->b_fname, "", sizeof(bp->b_fname));
306 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
308 bp->b_dotp = bp->b_linep;
309 bp->b_doto = 0;
314 * sgetline - copy characters from ibuf to obuf, ending at the first
315 * newline. return with ibuf pointing to first char after
316 * newline.
319 sgetline(char **ibuf, int *nchars, char *obuf, int blen)
321 register char *len;
322 register char *cbuf = *ibuf;
323 register char *bufp = obuf;
324 register int retval = FIOSUC;
325 #define CR '\015'
326 #define LF '\012'
328 *nchars = 0;
329 if(*cbuf == '\0'){
330 retval = FIOEOF;
332 else{
333 len = obuf + blen - 1;
334 while (*cbuf != CR && *cbuf != LF && *cbuf != '\0'){
335 if(bufp < len){
336 *bufp++ = *cbuf++;
337 (*nchars)++;
339 else{
340 *bufp = '\0';
341 retval = FIOLNG;
342 break;
346 *bufp = '\0'; /* end returned line */
347 *ibuf = (*cbuf == CR) ? ++cbuf : cbuf;
348 *ibuf = (*cbuf == LF) ? ++cbuf : cbuf;
349 return(retval);