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;