/***********************************************************************/ /* BOX.C - */ /* This file contains all functions relating to box operations. */ /***********************************************************************/ /* * THE - The Hessling Editor. A text editor similar to VM/CMS xedit. * Copyright (C) 1991-2001 Mark Hessling * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to: * * The Free Software Foundation, Inc. * 675 Mass Ave, * Cambridge, MA 02139 USA. * * * If you make modifications to this software that you feel increases * it usefulness for the rest of the community, please email the * changes, enhancements, bug fixes as well as any and all ideas to me. * This software is going to be maintained and enhanced as deemed * necessary by the community. * * Mark Hessling, M.Hessling@qut.edu.au http://www.lightlink.com/hessling/ */ static char RCSid[] = "$Id: box.c,v 1.11 2006/01/29 11:44:53 mark Exp $"; #include #include /* structure for passing box parameters */ struct _boxp { short action; short mark_type; LENGTHTYPE src_start_col; LENGTHTYPE dst_start_col; LENGTHTYPE src_end_col; LENGTHTYPE num_cols; LINETYPE src_start_line; LINETYPE dst_start_line; LINETYPE src_end_line; LINETYPE num_lines; LINETYPE cursor_y; LENGTHTYPE cursor_x; LINE *curr_src; LINE *curr_dst; VIEW_DETAILS *src_view; VIEW_DETAILS *dst_view; }; typedef struct _boxp BOXP; #ifdef HAVE_PROTO static short box_copy_to_temp(BOXP *); static short box_copy_from_temp(BOXP *,bool); static short box_copy_stream_from_temp(BOXP *,bool); static short box_delete(BOXP *); static short box_move(BOXP *,bool,bool); static short box_fill(BOXP *,CHARTYPE); #else static short box_copy_to_temp(); static short box_copy_from_temp(); static short box_copy_stream_from_temp(); static short box_delete(); static short box_move(); static short box_fill(); #endif /*#define DEBUG 1*/ /***********************************************************************/ #ifdef HAVE_PROTO void box_operations(short action,CHARTYPE reset,bool boverlay,CHARTYPE fillchar) #else void box_operations(action,reset,boverlay,fillchar) short action; CHARTYPE reset; bool boverlay; CHARTYPE fillchar; #endif /***********************************************************************/ { BOXP boxp; short rc=RC_OK; unsigned short y=0,x=0; LENGTHTYPE offset=0; short save_mark_type=MARK_VIEW->mark_type; bool same_view=FALSE; TRACE_FUNCTION("box.c: box_operations"); /* * This procedure is for copying, deleting, filling, moving and * overlaying box blocks. Box blocks consist of BOX, WORD, COLUMN, * STREAM and CUA blocks. In fact every type of block that isn't * a LINE block. * blocks. */ post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE); /* * If the command was issued on the command line then the destination * line is the current line and the destination column is 0; */ if (CURRENT_VIEW->current_window == WINDOW_COMMAND) { if (CURRENT_VIEW->current_line == 0L) boxp.dst_start_line = 1L; else boxp.dst_start_line = CURRENT_VIEW->current_line; boxp.dst_start_col = 0; } else { if (CURRENT_VIEW->focus_line == 0L) boxp.dst_start_line = 1L; else boxp.dst_start_line = CURRENT_VIEW->focus_line; getyx(CURRENT_WINDOW,y,x); boxp.dst_start_col = x + CURRENT_VIEW->verify_col-1; } /* * Set up the source and destination views... */ boxp.src_view = MARK_VIEW; boxp.dst_view = CURRENT_VIEW; if ( MARK_VIEW == CURRENT_VIEW ) same_view = TRUE; boxp.mark_type = MARK_VIEW->mark_type; /* * CUA block can have start position after end position */ if ( boxp.mark_type == M_CUA && ( MARK_VIEW->mark_start_line * max_line_length ) + MARK_VIEW->mark_start_col > (MARK_VIEW->mark_end_line * max_line_length ) + MARK_VIEW->mark_end_col ) { boxp.src_start_line = MARK_VIEW->mark_end_line; boxp.src_start_col = MARK_VIEW->mark_end_col-1; boxp.src_end_line = MARK_VIEW->mark_start_line; boxp.src_end_col = MARK_VIEW->mark_start_col-1; } else { boxp.src_start_line = MARK_VIEW->mark_start_line; boxp.src_start_col = MARK_VIEW->mark_start_col-1; boxp.src_end_line = MARK_VIEW->mark_end_line; boxp.src_end_col = MARK_VIEW->mark_end_col-1; } boxp.num_cols = MARK_VIEW->mark_end_col - MARK_VIEW->mark_start_col + 1; /* * If the block type is COLUMN, the number of lines to operate on is * the number of lines in the source file and the destination start * line is line 1. Reset these values set above. */ if (MARK_VIEW->mark_type == M_COLUMN) { boxp.num_lines = MARK_VIEW->file_for_view->number_lines - boxp.src_start_line +1L; boxp.dst_start_line = 1L; } else boxp.num_lines = boxp.src_end_line - boxp.src_start_line +1L; /* * Find the current LINE pointer for both the source and destination * lines. */ boxp.curr_src = lll_find(MARK_FILE->first_line,MARK_FILE->last_line,boxp.src_start_line,MARK_FILE->number_lines); if (action != BOX_D) boxp.curr_dst = lll_find(CURRENT_FILE->first_line,CURRENT_FILE->last_line,boxp.dst_start_line,CURRENT_FILE->number_lines); /* * Call the appropriate box function... */ boxp.action = action; switch(action) { case BOX_D: rc = box_delete(&boxp); break; case BOX_M: rc = box_move(&boxp,boverlay,TRUE); break; case BOX_C: rc = box_move(&boxp,boverlay,TRUE); break; case BOX_F: rc = box_fill(&boxp,fillchar); break; } /* * Increment the alteration counts... */ increment_alt(CURRENT_FILE); /* * Set the parameters in the MARK_VIEW to OFF, and * redraw the view if different from the current view */ MARK_VIEW->marked_line = MARK_VIEW->marked_col = FALSE; MARK_VIEW->mark_type = M_NONE; MARK_VIEW = (VIEW_DETAILS *)NULL; if ( !same_view && display_screens > 1) { build_screen( (CHARTYPE)(other_screen) ); display_screen( (CHARTYPE)(other_screen) ); } /* * If we are not resetting the block, set up block markers... */ if (reset != SOURCE_BLOCK_RESET) { if (boxp.src_start_col < boxp.dst_start_col && action == BOX_M) offset = boxp.num_cols; MARK_VIEW = CURRENT_VIEW; MARK_VIEW->mark_start_line = boxp.dst_start_line; MARK_VIEW->mark_end_line = boxp.dst_start_line+boxp.num_lines-1L; MARK_VIEW->mark_start_col = boxp.dst_start_col+1-offset; if ( (save_mark_type == M_STREAM || save_mark_type == M_CUA ) && boxp.num_lines != 1) MARK_VIEW->mark_end_col = boxp.src_end_col+1; else MARK_VIEW->mark_end_col = boxp.dst_start_col+boxp.num_cols-offset; MARK_VIEW->mark_type = save_mark_type; MARK_VIEW->marked_line = MARK_VIEW->marked_col = TRUE; wmove(CURRENT_WINDOW,y,x-offset); } pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL); build_screen(current_screen); display_screen(current_screen); /* should only call this is the marked block is in view */ TRACE_RETURN(); return; } /***********************************************************************/ #ifdef HAVE_PROTO void box_paste_from_clipboard( LINE *curr_src, LINETYPE numlines, LINETYPE numcols ) #else void box_paste_from_clipboard( curr_src, numlines, numcols ) LINE *curr_src; LINETYPE numlines,numcols; #endif /***********************************************************************/ { BOXP boxp; short rc=RC_OK; unsigned short y=0,x=0; TRACE_FUNCTION("box.c: box_paste_from_clipboard"); /* * This procedure is for copying from clipboard. */ post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE); /* * If the command was issued on the command line then the destination * line is the current line and the destination column is 0; */ if (CURRENT_VIEW->current_window == WINDOW_COMMAND) { if (CURRENT_VIEW->current_line == 0L) boxp.dst_start_line = 1L; else boxp.dst_start_line = CURRENT_VIEW->current_line; boxp.dst_start_col = 0; /* maybe this should current column TODO */ } else { if (CURRENT_VIEW->focus_line == 0L) boxp.dst_start_line = 1L; else boxp.dst_start_line = CURRENT_VIEW->focus_line; getyx(CURRENT_WINDOW,y,x); boxp.dst_start_col = x + CURRENT_VIEW->verify_col-1; } /* * Set up the source and destination views... */ boxp.src_view = NULL; boxp.dst_view = CURRENT_VIEW; boxp.mark_type = M_STREAM; boxp.src_start_line = 0; boxp.src_end_line = numlines-1; boxp.src_start_col = 0; boxp.src_end_col = numcols-1; boxp.num_cols = numcols; boxp.num_lines = numlines; /* * Find the current LINE pointer for both the source and destination * lines. */ boxp.curr_src = curr_src; boxp.curr_dst = lll_find( CURRENT_FILE->first_line, CURRENT_FILE->last_line, boxp.dst_start_line, CURRENT_FILE->number_lines ); /* * Call the appropriate box function... */ boxp.action = BOX_C; rc = box_move( &boxp, FALSE, FALSE ); /* * Increment the alteration counts... */ increment_alt( CURRENT_FILE ); /* * Redisplay the screen */ pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL); build_screen(current_screen); display_screen(current_screen); /* * Position cursor at end of inserted stream */ if ( CURRENT_VIEW->current_window == WINDOW_FILEAREA ) { THEcursor_goto( boxp.cursor_y, boxp.cursor_x ); } TRACE_RETURN(); return; } /***********************************************************************/ #ifdef HAVE_PROTO static short box_delete(BOXP *prm) #else static short box_delete(prm) BOXP *prm; #endif /***********************************************************************/ { LINETYPE i=0L; LENGTHTYPE j=0; LENGTHTYPE num_to_move=0,length_diff=0; short rc=0; bool shadow_found = FALSE; bool advance_line_ptr = TRUE; LINE *curr=NULL; TRACE_FUNCTION("box.c: box_delete"); curr = prm->curr_src; for (i=0L;inum_lines;i++) { advance_line_ptr = TRUE; rc = processable_line(prm->src_view,prm->src_start_line+i,curr); switch(rc) { case LINE_SHADOW: shadow_found = TRUE; break; case LINE_TOF: case LINE_EOF: break; default: if ( (prm->mark_type == M_STREAM || prm->mark_type == M_CUA ) && prm->src_start_line != prm->src_end_line) { if (i == 0) { /* * first line of stream block * delete from start column to end of line */ if (prm->src_start_col < curr->length) { add_to_recovery_list(curr->line,curr->length); curr->length = prm->src_start_col; } } else if (i+1 == prm->num_lines) /* last line of stream block */ { if (curr->length > 0) { add_to_recovery_list(curr->line,curr->length); curr->length = (LENGTHTYPE)(prm->src_end_col < curr->length-1) ? curr->length - prm->src_end_col - 1: 0; for (j=0;jlength;j++) *(curr->line+(LENGTHTYPE)(LINETYPE)j) = *(curr->line+prm->src_end_col+j+1); } } else { curr = delete_LINE( MARK_FILE->first_line, MARK_FILE->last_line, curr, DIRECTION_FORWARD, TRUE ); MARK_FILE->number_lines--; advance_line_ptr = FALSE; } } else { if ((LINETYPE)curr->length >= (LINETYPE)MARK_VIEW->mark_start_col) { num_to_move = (LENGTHTYPE)max((LINETYPE)curr->length - (LINETYPE)MARK_VIEW->mark_end_col,0L); length_diff = (LENGTHTYPE)min((LINETYPE)MARK_VIEW->mark_end_col-(LINETYPE)MARK_VIEW->mark_start_col+1L, (LINETYPE)curr->length-(LINETYPE)MARK_VIEW->mark_start_col+1L); } else num_to_move = length_diff = 0; if (length_diff != 0) { add_to_recovery_list(curr->line,curr->length); curr->length = (LENGTHTYPE)((LINETYPE)curr->length-(LINETYPE)length_diff); for (j=0;jline+(LENGTHTYPE)((LINETYPE)j+(LINETYPE)MARK_VIEW->mark_start_col-1L)) = *(curr->line+prm->src_start_col+j+prm->num_cols); *(curr->line+curr->length) = '\0';/* null terminate */ } } } if (advance_line_ptr) curr = curr->next; /* this should NEVER go past the end */ } /* * if the delete involved lines and there were no shadow lines involved * join the first line with the last line of the block */ if ( (prm->mark_type == M_STREAM || prm->mark_type == M_CUA ) && prm->src_start_line != prm->src_end_line && !shadow_found) { curr = prm->curr_src; if (curr->next->length > 0) { curr->line = (CHARTYPE *)(*the_realloc)( (void *)curr->line, (curr->length+curr->next->length)*sizeof(CHARTYPE) ); if (curr->line == NULL) { display_error(30,(CHARTYPE *)"",FALSE); TRACE_RETURN(); return(RC_OUT_OF_MEMORY); } memcpy((DEFCHAR*)curr->line+curr->length,(DEFCHAR*)curr->next->line,curr->next->length); curr->length += curr->next->length; if (curr->length > max_line_length) { display_error(0,(CHARTYPE*)"Truncated",FALSE); curr->length = max_line_length; } *(curr->line+curr->length) = '\0'; /* do we need to do this anymore ? */ } curr = delete_LINE( MARK_FILE->first_line, MARK_FILE->last_line, curr->next, DIRECTION_FORWARD, TRUE ); MARK_FILE->number_lines--; } TRACE_RETURN(); return(RC_OK); } /***********************************************************************/ #ifdef HAVE_PROTO static short box_move(BOXP *prm,bool boverlay, bool copy_to_temp) #else static short box_move(prm,boverlay,copy_to_temp) BOXP *prm; bool boverlay,copy_to_temp; #endif /***********************************************************************/ { LINE *save_src=NULL,*temp_src=NULL; LINETYPE save_src_start_line=0L; LENGTHTYPE save_src_start_col=0; TRACE_FUNCTION("box.c: box_move"); save_src_start_col = prm->src_start_col; save_src_start_line = prm->src_start_line; save_src = prm->curr_src; if ( copy_to_temp ) { box_copy_to_temp(prm); /* copy box from file to temp */ prm->src_start_line = 0L; prm->src_start_col = 0; } if (prm->dst_start_col <= prm->src_start_col+prm->num_cols && prm->action == BOX_M) { temp_src = prm->curr_src; /* save the LINE pointer to temp src lines */ prm->curr_src = save_src; /* point to file src lines */ box_delete(prm); prm->curr_src = temp_src; /* point to temp src lines */ } if ( (prm->mark_type == M_STREAM || prm->mark_type == M_CUA ) && prm->num_lines != 1) box_copy_stream_from_temp(prm,boverlay);/* copy box from temp to file */ else box_copy_from_temp(prm,boverlay); /* copy box from temp to file */ /*first_save = lll_free(first_save);*/ prm->src_start_line = save_src_start_line; prm->src_start_col = save_src_start_col; prm->curr_src = save_src; if (prm->dst_start_col > prm->src_start_col+prm->num_cols && prm->action == BOX_M) box_delete(prm); TRACE_RETURN(); return(RC_OK); } /***********************************************************************/ #ifdef HAVE_PROTO static short box_copy_to_temp(BOXP *prm) #else static short box_copy_to_temp(prm) BOXP *prm; #endif /***********************************************************************/ { LINE *first_save=NULL,*save_src=NULL,*tmp=NULL; LINETYPE i=0L; short rc=RC_OK; TRACE_FUNCTION("box.c: box_copy_to_temp"); tmp = prm->curr_src; for ( i = 0L; i < prm->num_lines ; i++ ) { if ( processable_line( prm->src_view, prm->src_start_line+i, tmp ) == LINE_LINE ) { memset( rec, ' ', max_line_length ); #if 1 if ( prm->mark_type == M_STREAM || prm->mark_type == M_CUA ) { int mystart=0,mynum=tmp->length; memset( trec, ' ', max_line_length ); memcpy( trec, tmp->line, tmp->length ); if ( i == 0 ) { mystart = prm->src_start_col; if ( mystart > tmp->length ) mystart = mynum = 0; else mynum = tmp->length - mystart; } if ( i + 1 == prm->num_lines ) mynum = prm->src_end_col - mystart + 1; memcpy( rec, trec+mystart, mynum ); rec_len = mynum; if ( ( save_src = add_LINE( first_save, save_src, rec, rec_len, 0, TRUE ) ) == (LINE *)NULL ) { TRACE_RETURN(); return(RC_OUT_OF_MEMORY); } } else { memcpy( rec, tmp->line, tmp->length ); rec_len = tmp->length; if ( ( save_src = add_LINE (first_save, save_src, rec+prm->src_start_col, prm->num_cols, 0, TRUE ) ) == (LINE *)NULL ) { TRACE_RETURN(); return(RC_OUT_OF_MEMORY); } } #else memcpy(rec,tmp->line,tmp->length); rec_len = tmp->length; if ((save_src = add_LINE(first_save,save_src, rec+prm->src_start_col,prm->num_cols,0,TRUE)) == (LINE *)NULL) { TRACE_RETURN(); return(RC_OUT_OF_MEMORY); } #endif if (first_save == (LINE *)NULL) first_save = save_src; } tmp = tmp->next; } prm->curr_src = first_save; TRACE_RETURN(); return(rc); } /***********************************************************************/ #ifdef HAVE_PROTO static short box_copy_from_temp(BOXP *prm,bool boverlay) #else static short box_copy_from_temp(prm,boverlay) BOXP *prm; bool boverlay; #endif /***********************************************************************/ { LINETYPE dst_lineno=0L; LENGTHTYPE j=0; CHARTYPE chr=0; short rc=RC_OK,line_type=0; TRACE_FUNCTION("box.c: box_copy_from_temp"); dst_lineno = prm->dst_start_line; while( prm->curr_src ) { while(1) { line_type = processable_line (prm->dst_view, dst_lineno, prm->curr_dst ); if ( line_type == LINE_LINE ) break; if ( line_type == LINE_TOF || line_type == LINE_EOF ) { if ( ( prm->curr_dst = add_LINE( CURRENT_FILE->first_line, prm->curr_dst->prev, (CHARTYPE *)"", 0, 0, TRUE ) ) == (LINE *)NULL ) { TRACE_RETURN(); return(RC_OUT_OF_MEMORY); } CURRENT_FILE->number_lines++; break; } dst_lineno++; prm->curr_dst = prm->curr_dst->next; } pre_process_line( prm->dst_view, dst_lineno, prm->curr_dst );/* copy dest line into rec */ for ( j = 0; j < prm->num_cols; j++ ) { if ( prm->src_start_col+j+1 > prm->curr_src->length ) chr = (CHARTYPE)' '; else chr = (CHARTYPE)*(prm->curr_src->line+prm->src_start_col+j); if ( boverlay ) rec[prm->dst_start_col+j] = chr; else meminschr( rec, chr, prm->dst_start_col+j, max_line_length, rec_len++ ); } rc = memrevne( rec, ' ', max_line_length ); if ( rc == (-1) ) rec_len = 0; else rec_len = rc+1; post_process_line( prm->dst_view, dst_lineno, (LINE *)NULL, FALSE ); prm->curr_src = prm->curr_src->next; /* this should NEVER go past the end */ prm->curr_dst = prm->curr_dst->next; /* this should NEVER go past the end */ /* * Save the position where the cursor should go after the end of the inserted text */ prm->cursor_x = prm->dst_start_col + prm->num_cols + 1; prm->cursor_y = dst_lineno; /* before increment */ dst_lineno++; } prm->num_lines = dst_lineno - prm->dst_start_line; TRACE_RETURN(); return(RC_OK); } /***********************************************************************/ #ifdef HAVE_PROTO static short box_copy_stream_from_temp(BOXP *prm,bool boverlay) #else static short box_copy_stream_from_temp(prm,boverlay) BOXP *prm; bool boverlay; #endif /***********************************************************************/ { LINETYPE dst_lineno=0L,i=0L; short line_type=0; int mystart=0,mynumcols=0; bool full_line=TRUE; LINE *curr=NULL,*last_line=NULL; TRACE_FUNCTION("box.c: box_copy_stream_from_temp"); if (boverlay) { /* * In overlay mode treat the stream block similar to a box block */ dst_lineno = prm->dst_start_line; i = 0; while(prm->curr_src) { while(1) { line_type = processable_line( prm->dst_view, dst_lineno, prm->curr_dst ); if (line_type == LINE_LINE) { break; } if (line_type == LINE_TOF || line_type == LINE_EOF) { if ((prm->curr_dst = add_LINE(CURRENT_FILE->first_line,prm->curr_dst->prev, (CHARTYPE *)"",0,0,TRUE)) == (LINE *)NULL) { TRACE_RETURN(); return(RC_OUT_OF_MEMORY); } CURRENT_FILE->number_lines++; break; } dst_lineno++; prm->curr_dst = prm->curr_dst->next; } pre_process_line( prm->dst_view, dst_lineno, prm->curr_dst );/* copy dest line into rec */ mystart=0; mynumcols=prm->curr_src->length; full_line=TRUE; if (i == 0) { mystart = prm->src_start_col; full_line = FALSE; } if (i+1 == prm->num_lines) full_line = FALSE; memcpy(rec+mystart,prm->curr_src->line,prm->curr_src->length); if (full_line) { rec_len = prm->curr_src->length; } else { rec_len = max(rec_len,prm->curr_src->length+mystart); } post_process_line( prm->dst_view, dst_lineno, (LINE *)NULL, FALSE ); prm->curr_src = prm->curr_src->next; /* this should NEVER go past the end */ prm->curr_dst = prm->curr_dst->next; /* this should NEVER go past the end */ dst_lineno++; i++; } prm->num_lines = dst_lineno - prm->dst_start_line; } else { /* * In non-overlay mode treat the stream block similar to a line block */ /* * This function copies saved lines from a multi-line stream block. * The line to which the stream block is copied is split at the * cursor position. * The first source line is appended to the current line. * The remainder of the lines are added as new lines, except the last. * The last line is pre-pended to that portion of the line that was * split. */ dst_lineno = prm->dst_start_line; while(1) { line_type = processable_line( prm->dst_view, dst_lineno, prm->curr_dst ); if (line_type == LINE_LINE) { break; } if (line_type == LINE_TOF || line_type == LINE_EOF) { if ( ( prm->curr_dst = add_LINE( CURRENT_FILE->first_line, prm->curr_dst->prev, (CHARTYPE *)"", 0, 0, TRUE ) ) == (LINE *)NULL ) { TRACE_RETURN(); return(RC_OUT_OF_MEMORY); } CURRENT_FILE->number_lines++; break; } dst_lineno++; prm->curr_dst = prm->curr_dst->next; } /* * Now have a line that we can split. */ curr = prm->curr_dst; for (i=0;inum_lines;i++) { if (i == 0) { /* * This is the first line that we split into two and append the first line * of the clipboard after the split position * Create the new line */ memset(rec,' ',max_line_length); if (prm->dst_start_col < curr->length) { memcpy(rec,curr->line+prm->dst_start_col,curr->length-prm->dst_start_col); rec_len = curr->length-prm->dst_start_col; } else rec_len = 0; curr->flags.changed_flag = TRUE; /* * Add the new line */ add_LINE(CURRENT_FILE->first_line,curr,(rec),rec_len,curr->select,TRUE); CURRENT_FILE->number_lines++; last_line = curr->next; /* * Get the current line back into rec so we can trim it at * the cursor position. */ pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,curr); memset(rec+prm->dst_start_col,' ',max_line_length-prm->dst_start_col); memcpy(rec+prm->dst_start_col,prm->curr_src->line,min(max_line_length-prm->dst_start_col,prm->curr_src->length)); rec_len = prm->curr_src->length+prm->dst_start_col; post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,curr,FALSE); prm->curr_src = prm->curr_src->next; /* this should NEVER go past the end */ curr = prm->curr_dst; } else if (i+1 == prm->num_lines) /* last line - prepend to "last_line" */ { pre_process_line( CURRENT_VIEW, CURRENT_VIEW->focus_line, last_line ); meminsmem( rec, prm->curr_src->line, prm->curr_src->length, 0, max_line_length, last_line->length ); rec_len = min( max_line_length, rec_len+prm->curr_src->length ); post_process_line( CURRENT_VIEW, CURRENT_VIEW->focus_line, last_line, FALSE ); /* 2 * Save the position at the end of the inserted stream block. */ prm->cursor_x = prm->curr_src->length+1; prm->cursor_y = dst_lineno+prm->num_lines-1; } else { /* * All lines other than the first and last line. */ if ((curr = add_LINE(CURRENT_FILE->first_line,curr, prm->curr_src->line,prm->curr_src->length,0,TRUE)) == (LINE *)NULL) { TRACE_RETURN(); return(RC_OUT_OF_MEMORY); } prm->curr_src = prm->curr_src->next; /* this should NEVER go past the end */ CURRENT_FILE->number_lines++; } } pre_process_line( prm->dst_view, dst_lineno, prm->curr_dst ); } TRACE_RETURN(); return(RC_OK); } /***********************************************************************/ #ifdef HAVE_PROTO static short box_fill(BOXP *prm,CHARTYPE fillchar) #else static short box_fill(prm,fillchar) BOXP *prm; CHARTYPE fillchar; #endif /***********************************************************************/ { LINETYPE i=0L; short rc=RC_OK; TRACE_FUNCTION("box.c: box_fill"); for (i=0L;inum_lines;i++) { if (processable_line(CURRENT_VIEW,prm->src_start_line+i,prm->curr_src) == LINE_LINE) { pre_process_line(CURRENT_VIEW,prm->src_start_line+i,(LINE *)NULL);/* copy source line into rec */ if ( prm->mark_type == M_STREAM || prm->mark_type == M_CUA ) { int mystart=0,mynum=max_line_length; if (i == 0) mystart = prm->src_start_col; if (i+1 == prm->num_lines) mynum = prm->src_end_col - mystart + 1; memset(rec+mystart,fillchar,mynum); } else memset(rec+prm->src_start_col,fillchar,prm->num_cols); rc = memrevne(rec,' ',max_line_length); if (rc == (-1)) rec_len = 0; else rec_len = rc+1; post_process_line(CURRENT_VIEW,prm->src_start_line+i,(LINE *)NULL,FALSE); } prm->curr_src = prm->curr_src->next; /* this should NEVER go past the end */ } prm->dst_start_col = prm->src_start_col; prm->dst_start_line = prm->src_start_line; TRACE_RETURN(); return(RC_OK); }