* clear out some warnings by gcc 9.3.1.
[alpine.git] / pico / buffer.c
blob741c969f8810b93a82cfa80d1a7e2ed7381ed4cb
1 #if !defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: buffer.c 761 2007-10-23 22:35:18Z hubert@u.washington.edu $";
3 #endif
5 /*
6 * ========================================================================
7 * Copyright 2006 University of Washington
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * ========================================================================
17 * Program: Buffer management routines
21 * Buffer management.
22 * Some of the functions are internal,
23 * and some are actually attached to user
24 * keys. Like everyone else, they set hints
25 * for the display system.
27 #include "headers.h"
29 int sgetline(char **, int *, char *, int);
33 * Look through the list of
34 * buffers. Return TRUE if there
35 * are any changed buffers. Buffers
36 * that hold magic internal stuff are
37 * not considered; who cares if the
38 * list of buffer names is hacked.
39 * Return FALSE if no buffers
40 * have been changed.
42 int
43 anycb(void)
45 register BUFFER *bp;
47 bp = bheadp;
48 while (bp != NULL) {
49 if ((bp->b_flag&BFTEMP)==0 && (bp->b_flag&BFCHG)!=0)
50 return (TRUE);
51 bp = bp->b_bufp;
53 return (FALSE);
57 * Find a buffer, by name. Return a pointer
58 * to the BUFFER structure associated with it. If
59 * the named buffer is found, but is a TEMP buffer (like
60 * the buffer list) conplain. If the buffer is not found
61 * and the "cflag" is TRUE, create it. The "bflag" is
62 * the settings for the flags in in buffer.
64 BUFFER *
65 bfind(char *bname, int cflag, int bflag)
67 register BUFFER *bp;
68 register BUFFER *sb; /* buffer to insert after */
69 register LINE *lp;
71 bp = bheadp;
72 while (bp != NULL) {
73 if (strcmp(bname, bp->b_bname) == 0) {
74 if ((bp->b_flag&BFTEMP) != 0) {
75 mlwrite_utf8("Cannot select builtin buffer", NULL);
76 return (NULL);
78 return (bp);
80 bp = bp->b_bufp;
82 if (cflag != FALSE) {
83 if ((bp=(BUFFER *)malloc(sizeof(BUFFER))) == NULL)
84 return (NULL);
85 if ((lp=lalloc(0)) == NULL) {
86 free((char *) bp);
87 return (NULL);
89 /* find the place in the list to insert this buffer */
90 if (bheadp == NULL || strcmp(bheadp->b_bname, bname) > 0) {
91 /* insert at the beginning */
92 bp->b_bufp = bheadp;
93 bheadp = bp;
94 } else {
95 sb = bheadp;
96 while (sb->b_bufp != NULL) {
97 if (strcmp(sb->b_bufp->b_bname, bname) > 0)
98 break;
99 sb = sb->b_bufp;
102 /* and insert it */
103 bp->b_bufp = sb->b_bufp;
104 sb->b_bufp = bp;
107 /* and set up the other buffer fields */
108 bp->b_active = TRUE;
109 bp->b_dotp = lp;
110 bp->b_doto = 0;
111 bp->b_markp = NULL;
112 bp->b_marko = 0;
113 bp->b_flag = bflag;
114 bp->b_mode = gmode;
115 bp->b_nwnd = 0;
116 bp->b_linep = lp;
117 strncpy(bp->b_fname, "", sizeof(bp->b_fname));
118 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
119 strncpy(bp->b_bname, bname, sizeof(bp->b_bname));
120 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
121 lp->l_fp = lp;
122 lp->l_bp = lp;
124 return (bp);
128 * This routine blows away all of the text
129 * in a buffer. If the buffer is marked as changed
130 * then we ask if it is ok to blow it away; this is
131 * to save the user the grief of losing text. The
132 * window chain is nearly always wrong if this gets
133 * called; the caller must arrange for the updates
134 * that are required. Return TRUE if everything
135 * looks good.
138 bclear(BUFFER *bp)
140 register LINE *lp;
141 register int s = FALSE;
143 if(Pmaster){
144 if ((bp->b_flag&BFTEMP) == 0 /* Not scratch buffer. */
145 && (bp->b_flag&BFCHG) != 0){ /* Something changed */
146 emlwrite("buffer lines not freed.", NULL);
147 return (s);
150 else{
151 if ((bp->b_flag&BFTEMP) == 0 /* Not scratch buffer. */
152 && (bp->b_flag&BFCHG) != 0 /* Something changed */
153 /* TRANSLATORS: A question asking whether to forget about
154 the changes and revert to the unchanged version. */
155 && (s=mlyesno_utf8(_("Discard changes"), -1)) != TRUE){
156 return (s);
160 bp->b_flag &= ~BFCHG; /* Not changed */
161 while ((lp=lforw(bp->b_linep)) != bp->b_linep)
162 lfree(lp);
163 bp->b_dotp = bp->b_linep; /* Fix "." */
164 bp->b_doto = 0;
165 bp->b_markp = NULL; /* Invalidate "mark" */
166 bp->b_marko = 0;
167 return (TRUE);
172 * packbuf - will pack up the main buffer in the buffer provided
173 * to be returned to the program that called pico.
174 * if need be, allocate memory for the new message.
175 * will also free the memory associated with the editor
176 * buffer, by calling zotedit.
179 packbuf(char **buf,
180 int *blen,
181 int lcrlf) /* EOLs are local or CRLF */
183 register int i = 0;
184 register LINE *lp;
185 register int retval = 0;
186 register char *bufp;
187 register char *eobuf;
189 if(anycb() != FALSE){
191 lp = lforw(curbp->b_linep);
192 do{ /* how many chars? */
193 i += llength(lp);
195 * add extra for new lines to be inserted later
197 i += 2;
198 lp = lforw(lp);
200 while(lp != curbp->b_linep);
202 if(i > *blen){ /* new buffer ? */
204 * don't forget to add one for the null terminator!!!
206 if((bufp = (char *)malloc((i+1)*sizeof(char))) == NULL){
207 zotedit(); /* bag it! */
208 return(COMP_FAILED);
210 free(*buf);
211 *buf = bufp;
212 *blen = i;
214 else{
215 bufp = *buf;
218 eobuf = bufp + *blen;
219 lp = lforw(curbp->b_linep); /* First line. */
220 do {
221 for (i = 0; i < llength(lp); i++){ /* copy into buffer */
222 if((bufp+1) < eobuf){
223 *bufp++ = (lp->l_text[i].c & 0xFF);
225 else{
227 * the idea is to malloc enough space for the new
228 * buffer...
230 *bufp = '\0';
231 zotedit();
232 return(BUF_CHANGED|COMP_FAILED);
235 if(lcrlf){
236 *bufp++ = '\n'; /* EOLs use local convention */
238 else{
239 *bufp++ = 0x0D; /* EOLs use net standard */
240 *bufp++ = 0x0A;
242 lp = lforw(lp);
244 while (lp != curbp->b_linep);
245 if(lcrlf)
246 *--bufp = '\0';
247 else
248 *bufp = '\0';
249 retval = BUF_CHANGED;
252 zotedit();
253 return(retval);
258 * readbuf - reads in a buffer.
260 void
261 readbuf(char **buf)
263 register LINE *lp1;
264 register LINE *lp2;
265 register BUFFER *bp;
266 register WINDOW *wp;
267 register int i;
268 register int s;
269 char *sptr; /* pointer into buffer string */
270 int nbytes;
271 char line[NLINE];
272 CELL ac;
274 bp = curbp;
275 bp->b_flag &= ~(BFTEMP|BFCHG);
276 sptr = *buf;
277 ac.a = 0;
279 while((s=sgetline(&sptr,&nbytes,line,NLINE)) == FIOSUC || s == FIOLNG){
281 if ((lp1=lalloc(nbytes)) == NULL) {
282 s = FIOERR; /* Keep message on the */
283 break; /* display. */
285 lp2 = lback(curbp->b_linep);
286 lp2->l_fp = lp1;
287 lp1->l_fp = curbp->b_linep;
288 lp1->l_bp = lp2;
289 curbp->b_linep->l_bp = lp1;
290 for (i=0; i<nbytes; ++i){
291 ac.c = line[i];
292 lputc(lp1, i, ac);
296 for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
297 if (wp->w_bufp == curbp) {
298 wheadp->w_linep = lforw(curbp->b_linep);
299 wheadp->w_dotp = lback(curbp->b_linep);
300 wheadp->w_doto = 0;
301 wheadp->w_markp = NULL;
302 wheadp->w_marko = 0;
303 wheadp->w_flag |= WFHARD;
307 strncpy(bp->b_bname, "main", sizeof(bp->b_bname));
308 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
309 strncpy(bp->b_fname, "", sizeof(bp->b_fname));
310 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
312 bp->b_dotp = bp->b_linep;
313 bp->b_doto = 0;
318 * sgetline - copy characters from ibuf to obuf, ending at the first
319 * newline. return with ibuf pointing to first char after
320 * newline.
323 sgetline(char **ibuf, int *nchars, char *obuf, int blen)
325 register char *len;
326 register char *cbuf = *ibuf;
327 register char *bufp = obuf;
328 register int retval = FIOSUC;
329 #define CR '\015'
330 #define LF '\012'
332 *nchars = 0;
333 if(*cbuf == '\0'){
334 retval = FIOEOF;
336 else{
337 len = obuf + blen;
338 while (*cbuf != CR && *cbuf != LF && *cbuf != '\0'){
339 if(bufp < len){
340 *bufp++ = *cbuf++;
341 (*nchars)++;
343 else{
344 *bufp = '\0';
345 retval = FIOLNG;
346 break;
350 *bufp = '\0'; /* end returned line */
351 *ibuf = (*cbuf == CR) ? ++cbuf : cbuf;
352 *ibuf = (*cbuf == LF) ? ++cbuf : cbuf;
353 return(retval);