1 /***********************************************************************/
5 /* Developed by Jacob Navia. */
6 /* Copyright 2001 Institut National de Recherche en Informatique et */
7 /* en Automatique. All rights reserved. This file is distributed */
8 /* under the terms of the GNU Library General Public License, with */
9 /* the special exception on linking described in file ../LICENSE. */
11 /***********************************************************************/
13 /***********************************************************************/
14 /* Changes made by Chris Watford to enhance the source editor */
15 /* Began 14 Sept 2003 - watford@uiuc.edu */
16 /***********************************************************************/
23 /*------------------------------------------------------------------------
24 Procedure: editbuffer_addline ID:1
25 Author: Chris Watford watford@uiuc.edu
26 Purpose: Adds a line to the current edit buffer
27 Input: Line of text to append to the end
30 --------------------------------------------------------------------------
32 18 Sept 2003 - Chris Watford watford@uiuc.edu
33 - Corrected doubly linked list issue
34 ------------------------------------------------------------------------*/
35 BOOL
editbuffer_addline(EditBuffer
* edBuf
, char* line
)
37 LineList
*tail
= NULL
; //head of the edit buffer line list
38 LineList
*newline
= NULL
;
46 // perform edit buffer sanity checks
47 if((edBuf
->LineCount
< 0) || (edBuf
->Lines
== NULL
))
52 // move to the end of the line list in the edit buffer
53 if((tail
= edBuf
->Lines
) != NULL
)
54 for( ; tail
->Next
!= NULL
; tail
= tail
->Next
);
56 // create the new line entry
57 newline
= (LineList
*)SafeMalloc(sizeof(LineList
));
60 newline
->Text
= (char*)SafeMalloc(strlen(line
)+1);
61 strncpy(newline
->Text
, line
, strlen(line
)+1);
62 newline
->Text
[strlen(line
)] = '\0';
64 // add it to the list as the head or the tail
69 edBuf
->Lines
= newline
;
72 // update the number of lines in the buffer
78 /*------------------------------------------------------------------------
79 Procedure: editbuffer_updateline ID:1
80 Author: Chris Watford watford@uiuc.edu
81 Purpose: Updates the edit buffer's internal contents for a line
82 Input: idx - Line index
84 Output: if the line was updated or not
86 ------------------------------------------------------------------------*/
87 BOOL
editbuffer_updateline(EditBuffer
* edBuf
, int idx
, char* line
)
89 LineList
*update
= edBuf
->Lines
; //head of the edit buffer line list
90 LineList
*newline
= NULL
;
97 } else if( (edBuf
->LineCount
== 0) ||
98 (edBuf
->Lines
== NULL
) ||
99 (idx
>= edBuf
->LineCount
) ||
104 // move to the index in the line list
105 // i left in update != NULL as a sanity check
106 for(i
= 0; ((update
!= NULL
) && (i
!= idx
)); update
= update
->Next
, i
++);
108 // did things mess up?
109 if( (update
== NULL
) || (i
!= idx
) )
114 // get rid of the old line
117 // get the new line updated
118 update
->Text
= (char*)SafeMalloc(strlen(line
)+1);
119 strncpy(update
->Text
, line
, strlen(line
)+1);
120 update
->Text
[strlen(line
)] = '\0';
125 /*------------------------------------------------------------------------
126 Procedure: editbuffer_updateoraddline ID:1
127 Author: Chris Watford watford@uiuc.edu
128 Purpose: Updates the edit buffer's internal contents for a line
129 Input: idx - Line index
131 Output: if the line was updated or not
133 ------------------------------------------------------------------------*/
134 BOOL
editbuffer_updateoraddline(EditBuffer
* edBuf
, int idx
, char* line
)
142 } else if((idx
> edBuf
->LineCount
) || (idx
< 0)) {
146 update
= edBuf
->Lines
; //head of the edit buffer line list
148 // do we update or add?
149 if((idx
< edBuf
->LineCount
) && (edBuf
->Lines
!= NULL
))
150 { //interior line, update
151 return editbuffer_updateline(edBuf
, idx
, line
);
154 return editbuffer_addline(edBuf
, line
);
158 /*------------------------------------------------------------------------
159 Procedure: editbuffer_removeline ID:1
160 Author: Chris Watford watford@uiuc.edu
161 Purpose: Removes a line from the edit buffer
162 Input: idx - Line index to remove
163 Output: if the line was removed or not
165 --------------------------------------------------------------------------
167 18 Sept 2003 - Chris Watford watford@uiuc.edu
168 - Added to allow backspace and delete support
169 - Corrected doubly linked list issue
170 ------------------------------------------------------------------------*/
171 BOOL
editbuffer_removeline(EditBuffer
* edBuf
, int idx
)
173 LineList
*update
= NULL
;
180 } else if( (edBuf
->LineCount
== 0) ||
181 (edBuf
->Lines
== NULL
) ||
182 (idx
>= edBuf
->LineCount
) ||
187 // move to the index in the line list
188 // i left in update != NULL as a sanity check
189 for(i
= 0, update
= edBuf
->Lines
; ((update
!= NULL
) && (i
!= idx
)); update
= update
->Next
, i
++);
194 // break links, removing our line
195 if(update
->Prev
!= NULL
)
197 // we're not the first so just break the link
198 update
->Prev
->Next
= update
->Next
;
200 // fix the prev check
201 if(update
->Next
!= NULL
)
202 update
->Next
->Prev
= update
->Prev
;
204 // we're the first, attach the next guy to lines
205 edBuf
->Lines
= update
->Next
;
208 // one less line to worry about
211 // get rid of the text
212 if(update
->Text
!= NULL
)
224 /*------------------------------------------------------------------------
225 Procedure: editbuffer_getasline ID:1
226 Author: Chris Watford watford@uiuc.edu
227 Purpose: Returns the edit buffer as one big line, \n's and \t's
232 ------------------------------------------------------------------------*/
233 char* editbuffer_getasline(EditBuffer
* edBuf
)
235 LineList
*line
= NULL
; //head of the edit buffer line list
236 char* retline
= (char*)realloc(NULL
, 1);
246 } else if (edBuf
->LineCount
== 0 || edBuf
->Lines
== NULL
) {
247 // fix any possible errors that may come from this
248 edBuf
->LineCount
= 0;
254 for(line
= edBuf
->Lines
; line
!= NULL
; line
= line
->Next
)
256 if(line
->Text
!= NULL
)
258 retline
= (char*)realloc(retline
, (strlen(retline
) + strlen(line
->Text
) + (strlen(retline
) > 0 ? 2 : 1)));
260 if(strlen(retline
) > 0)
261 retline
= strcat(retline
, " ");
263 retline
= strcat(retline
, line
->Text
);
265 //concat in the hoouuusssseee!
269 // now we have the big line, so lets ditch all \n's \t's and \r's
270 for(i
= 0; i
< strlen(retline
); i
++)
284 /*------------------------------------------------------------------------
285 Procedure: editbuffer_getasbuffer ID:1
286 Author: Chris Watford watford@uiuc.edu
287 Purpose: Returns the edit buffer as one big line, \n's and \t's
292 ------------------------------------------------------------------------*/
293 char* editbuffer_getasbuffer(EditBuffer
* edBuf
)
295 LineList
*line
= NULL
; //head of the edit buffer line list
296 char* retbuf
= (char*)realloc(NULL
, 1);
306 } else if (edBuf
->LineCount
== 0 || edBuf
->Lines
== NULL
) {
307 // fix any possible errors that may come from this
308 edBuf
->LineCount
= 0;
314 for(line
= edBuf
->Lines
; line
!= NULL
; line
= line
->Next
)
316 if(line
->Text
!= NULL
)
318 int len
= strlen(retbuf
);
319 len
+= strlen(line
->Text
) + (len
> 0 ? 3 : 1);
321 retbuf
= (char*)realloc(retbuf
, len
);
323 if(strlen(retbuf
) > 0)
324 retbuf
= strcat(retbuf
, "\r\n");
326 retbuf
= strcat(retbuf
, line
->Text
);
328 retbuf
[len
-1] = '\0';
330 //concat in the hoouuusssseee!
337 /*------------------------------------------------------------------------
338 Procedure: editbuffer_lastline ID:1
339 Author: Chris Watford watford@uiuc.edu
340 Purpose: Returns the last line in the edit buffer
344 ------------------------------------------------------------------------*/
345 char* editbuffer_lastline(EditBuffer
* edBuf
)
347 LineList
*line
= NULL
; //head of the edit buffer line list
353 } else if (edBuf
->LineCount
== 0 || edBuf
->Lines
== NULL
) {
354 // fix any possible errors that may come from this
355 edBuf
->LineCount
= 0;
360 // go to the last line
361 for(line
= edBuf
->Lines
; line
->Next
!= NULL
; line
= line
->Next
);
366 /*------------------------------------------------------------------------
367 Procedure: editbuffer_copy ID:1
368 Author: Chris Watford watford@uiuc.edu
369 Purpose: Makes an exact copy of an edit buffer
373 --------------------------------------------------------------------------
375 16 Sept 2003 - Chris Watford watford@uiuc.edu
376 - Added to make copies of history entries
377 18 Sept 2003 - Chris Watford watford@uiuc.edu
378 - Corrected doubly linked list issue
379 06 Oct 2003 - Chris Watford watford@uiuc.edu
380 - Added isCorrect flag
381 ------------------------------------------------------------------------*/
382 EditBuffer
* editbuffer_copy(EditBuffer
* edBuf
)
389 EditBuffer
* copy
= (EditBuffer
*)SafeMalloc(sizeof(EditBuffer
));
390 LineList
* lines
= edBuf
->Lines
;
391 LineList
* lastLine
= NULL
;
393 // clear its initial values
396 copy
->isCorrect
= FALSE
;
398 // well we don't have to copy much
399 if((lines
== NULL
) || (edBuf
->LineCount
<= 0))
404 // get if its correct
405 copy
->isCorrect
= edBuf
->isCorrect
;
407 // go through each line, malloc it and add it
408 for( ; lines
!= NULL
; lines
= lines
->Next
)
410 LineList
* curline
= (LineList
*)SafeMalloc(sizeof(LineList
));
411 curline
->Next
= NULL
;
412 curline
->Prev
= NULL
;
414 // if there was a last line, link them to us
417 lastLine
->Next
= curline
;
418 curline
->Prev
= lastLine
;
421 // are we the first line? add us to the edit buffer as the first
422 if(copy
->Lines
== NULL
)
424 copy
->Lines
= curline
;
427 // check if there is text on the line
428 if(lines
->Text
== NULL
)
429 { // no text, make it blankz0r
430 curline
->Text
= (char*)SafeMalloc(sizeof(char));
431 curline
->Text
[0] = '\0';
433 // there is text, copy it and null-terminate
434 curline
->Text
= (char*)SafeMalloc(strlen(lines
->Text
) + 1);
435 strncpy(curline
->Text
, lines
->Text
, strlen(lines
->Text
));
436 curline
->Text
[strlen(lines
->Text
)] = '\0';
439 // up the line count and make us the last line
444 // return our new copy
449 /*------------------------------------------------------------------------
450 Procedure: editbuffer_destroy ID:1
451 Author: Chris Watford watford@uiuc.edu
452 Purpose: Destroys an edit buffer
456 ------------------------------------------------------------------------*/
457 void editbuffer_destroy(EditBuffer
* edBuf
)
463 } else if(edBuf
->Lines
!= NULL
) {
464 LineList
* lastline
= NULL
;
466 // loop through each line free'ing its text
467 for( ; edBuf
->Lines
!= NULL
; edBuf
->Lines
= edBuf
->Lines
->Next
)
469 if(edBuf
->Lines
->Text
!= NULL
)
470 free(edBuf
->Lines
->Text
);
472 // if there was a line before us, free it
479 lastline
= edBuf
->Lines
;
482 // free the last line
490 /*------------------------------------------------------------------------
491 Procedure: editbuffer_new ID:1
492 Author: Chris Watford watford@uiuc.edu
493 Purpose: Creates an edit buffer
497 --------------------------------------------------------------------------
499 06 Oct 2003 - Chris Watford watford@uiuc.edu
500 - Added isCorrect flag
501 ------------------------------------------------------------------------*/
502 EditBuffer
* editbuffer_new(void)
505 EditBuffer
*edBuf
= (EditBuffer
*)SafeMalloc(sizeof(EditBuffer
));
508 edBuf
->LineCount
= 0;
510 edBuf
->isCorrect
= FALSE
;