/* * Name: find_left_margin * Purpose: find left margin depending on word wrap mode * Date: June 5, 1992 * Passed: ll: node pointer to current line * wrap_mode: current word wrap mode * Notes: the algorithm used to figure the indent column was yanked out * of the insert_newline( ) function and was made into a more * general algorithm for figuring the left margin irregardless * of word wrap or indent mode. when in the DYNAMIC_WRAP mode, * the user don't have to keep changing the left margin when * special indentation is needed. */ int find_left_margin( line_list_ptr ll, int wrap_mode ) { register int lm; int len; text_ptr source; if (wrap_mode == FIXED_WRAP) { /* * for FIXED_WRAP mode, the left and paragraph margins are determined * from the master mode structure. */ if (g_status.copied) { source = (text_ptr)g_status.line_buff; len = g_status.line_buff_len; } else { if (ll->prev != NULL) { source = ll->prev->line; len = ll->prev->len; } else { source = NULL; len = 0; } } if (source == NULL) lm = mode.parg_margin; else if (find_end( source, len ) == 0) lm = mode.parg_margin; else lm = mode.left_margin; } else { /* * for Indent and DYNAMIC_WRAP modes, the left margin is determined * from the first non blank line above the cursor. */ if (g_status.copied == TRUE) { source = (text_ptr)g_status.line_buff; len = g_status.line_buff_len; } else { source = ll->line; len = ll->len; } lm = first_non_blank( source, len ); if (is_line_blank( source, len ) && ll->prev != NULL) { for (ll=ll->prev; ll != NULL; ll=ll->prev) { lm = first_non_blank( ll->line, ll->len ); if (!is_line_blank( ll->line, ll->len )) break; } } } return( lm ); }
/* * Name: combine_wrap_spill * Purpose: combine word wrap lines so we don't push each word onto a * separate line. * Date: November 27, 1991 * Passed: window: pointer to current window * wrap_col: col to combine next line * lm: left margin * rm: right margin * side: left or right margin to insert spaces * new_line: boolean, should we insert a new line? */ void combine_wrap_spill( WINDOW *window, int wrap_col, int lm, int rm, int side, int new_line ) { line_list_ptr p; /* line we wrapped */ line_list_ptr pp; /* pointer to next line after wrapped line */ int p_len; /* length of line we just word wrapped */ int non_blank; /* first non-blank column on next line */ int control_t; /* number of times to call word_delete */ int next_line_len; /* length of next line counting from 1st word */ WINDOW w; /* scratch window */ dup_window_info( &w, window ); g_status.command = WordWrap; w.rcol = wrap_col; if (new_line) { insert_newline( &w ); if (mode.right_justify == TRUE) justify_right_margin( &w, w.ll->prev, mode.word_wrap == FIXED_WRAP ? find_left_margin( w.ll->prev, mode.word_wrap ) : lm, rm, side ); p = window->ll->next; } else p = window->ll; if (p != NULL) { p_len = find_end( p->line, p->len ); pp = p->next; if (pp != NULL) { non_blank = first_non_blank( pp->line, pp->len ); next_line_len = find_end( pp->line, pp->len ) - non_blank; if (!is_line_blank( pp->line, pp->len ) && p_len + next_line_len <= rm) { control_t = 1; if (mode.inflate_tabs) { if (*pp->line == ' ' || *pp->line == '\t') ++control_t; } else if (*pp->line == ' ') ++control_t; w.ll = p; w.rcol = p_len + 1; if (*(p->line+p_len-1) == '.') ++w.rcol; while (control_t--) word_delete( &w ); remove_spaces( lm ); un_copy_line( w.ll, &w, TRUE ); } window->file_info->dirty = GLOBAL; } } }
/* * Name: skip_eol * Purpose: move the diff to the next line * Date: October 31, 1992 * Passed: d: pointer to current node * r: tab adjusted real col * rcol: real real col * rline: current line number * bin_offset: offset from the beginning of the file * Returns: next non-blank node */ line_list_ptr skip_eol( line_list_ptr d, int *r, int *rcol, long *rline, long *bin_offset ) { int leading; long rl; long bo; *r = *rcol = 0; rl = *rline; bo = *bin_offset; if (d->len != EOF) { bo += d->len; d = d->next; ++rl; if (diff.blank_lines) { while (d->len != EOF && is_line_blank( d->line, d->len )) { bo += d->len; d = d->next; ++rl; } } if (d->len != EOF) { if (diff.leading) { leading = skip_leading_space( d->line, d->len ); if (mode.inflate_tabs) leading = detab_adjust_rcol( d->line, leading ); *rcol = leading; } else *rcol = 0; *r = *rcol; if (mode.inflate_tabs) *r = entab_adjust_rcol( d->line, d->len, *rcol ); } } *rline = rl; *bin_offset = bo; return( d ); }
codelist_entry *process_line(){ eat_whitespace(); codelist_entry *ret = NULL; printf("Processing line: %s -- len: %d\n", input_file_stack->line_buffer, (int)strlen(input_file_stack->line_buffer)); if(!is_line_blank() && !is_line_comment()){ if(is_line_label()){ printf("Line is label\n"); return process_label(); }else if(is_line_dat()){ printf("Line is data\n"); return process_dat(); }else if(is_line_include()){ printf("Line is include\n"); open_input_m4(get_include_filename()); return NULL; }else{ printf("Processing code line\n"); return process_op(); } }else{ printf("Line comment/empty/blank\n"); } return ret; }
/* * Name: differ * Purpose: diff text pointers * Date: October 31, 1992 * Passed: initial_rcol1: beginning column to begin diff in window1 * initial_rcol2: beginning column to begin diff in window2 * bottom: line to display diagnostics * Notes: a straight diff on text pointers is simple; however, diffing * with leading spaces and tabs is kinda messy. let's do the * messy diff. */ int differ( int initial_rcol1, int initial_rcol2, int bottom ) { int rcol1; /* virtual real column on diff window 1 */ int rcol2; /* virtual real column on diff window 2 */ int r1; /* real real column rcol1 - needed for tabs */ int r2; /* real real column rcol2 - needed for tabs */ char c1; /* character under r1 */ char c2; /* character under r2 */ int leading1; /* adjustment for leading space in window 1 */ int leading2; /* adjustment for leading space in window 2 */ int len1; /* length of diff1 line */ int len2; /* length of diff2 line */ line_list_ptr node1; /* scratch node in window 1 */ line_list_ptr node2; /* scratch node in window 2 */ text_ptr diff1; /* scratch text ptr in window 1 */ text_ptr diff2; /* scratch text ptr in window 2 */ long rline1; /* real line number of diff pointer 1 */ long rline2; /* real line number of diff pointer 2 */ long bin_offset1; /* binary offset of diff pointer 1 */ long bin_offset2; /* binary offset of diff pointer 2 */ int len; /* line length variable */ register int tabs; /* local variable for mode.inflate_tabs, T or F */ char line_buff[(MAX_COLS+1)*2]; /* buffer for char and attribute */ /* * initialize the text pointers and the initial column. skip any * initial blank lines. */ rline1 = diff.rline1; rline2 = diff.rline2; node1 = diff.d1; node2 = diff.d2; bin_offset1 = diff.bin_offset1; bin_offset2 = diff.bin_offset2; tabs = mode.inflate_tabs; if (diff.blank_lines) { while (node1->len != EOF && is_line_blank( node1->line, node1->len )) { bin_offset1 += node1->len; node1 = node1->next; ++rline1; initial_rcol1 = 0; } while (node2->len != EOF && is_line_blank( node2->line , node2->len)) { bin_offset2 += node2->len; node2 = node2->next; ++rline2; initial_rcol2 = 0; } } /* * if everything is everything, initialize the diff variables and diff. */ if (node1->len != EOF && node2->len != EOF) { diff1 = node1->line; diff2 = node2->line; rcol1 = initial_rcol1; rcol2 = initial_rcol2; len1 = node1->len; len2 = node2->len; assert( rcol1 >= 0 ); assert( rcol1 < MAX_LINE_LENGTH ); assert( rcol2 >= 0 ); assert( rcol2 < MAX_LINE_LENGTH ); assert( len1 >= 0 ); assert( len1 < MAX_LINE_LENGTH ); assert( len2 >= 0 ); assert( len2 < MAX_LINE_LENGTH ); /* * if cursors are past EOL, move them back to EOL. */ len = find_end( diff1, len1 ); if (rcol1 > len) rcol1 = len; len = find_end( diff2, len2 ); if (rcol2 > len) rcol2 = len; /* * if skip leading space, make sure our cursors start on first non-space. */ if (diff.leading) { leading1 = skip_leading_space( diff1, len1 ); leading2 = skip_leading_space( diff2, len2 ); if (tabs) { leading1 = detab_adjust_rcol( diff1, leading1 ); leading2 = detab_adjust_rcol( diff2, leading2 ); } if (rcol1 < leading1) rcol1 = leading1; if (rcol2 < leading2) rcol2 = leading2; } /* * we now have a valid rcol for the diff start, we may need to adjust * for tabs, though. */ assert( rcol1 >= 0 ); assert( rcol1 < MAX_LINE_LENGTH ); assert( rcol2 >= 0 ); assert( rcol2 < MAX_LINE_LENGTH ); r1 = tabs ? entab_adjust_rcol( diff1, len1, rcol1 ) : rcol1; r2 = tabs ? entab_adjust_rcol( diff2, len2, rcol2 ) : rcol2; assert( r1 >= 0 ); assert( r1 <= len1 ); assert( r2 >= 0 ); assert( r2 <= len2 ); assert( r1 <= rcol1 ); assert( r2 <= rcol2 ); s_output( diff_message, g_display.mode_line, 67, g_display.diag_color ); while (node1->len != EOF && node2->len != EOF && !g_status.control_break) { /* * look at each character in each diff window */ c1 = (char)(r1 < len1 ? *(diff1 + r1) : 0); c2 = (char)(r2 < len2 ? *(diff2 + r2) : 0); /* * tabs == space */ if (tabs) { if (c1 == '\t') c1 = ' '; if (c2 == '\t') c2 = ' '; } /* * skip spaces, if needed */ if (diff.all_space) { while (c1 == ' ' && r1 < len1) { ++rcol1; r1 = tabs ? entab_adjust_rcol( diff1, len1, rcol1 ) : rcol1; c1 = (char)(r1 < len1 ? *(diff1 + r1) : 0); if (c1 == '\t' && tabs) c1 = ' '; } while (c2 == ' ' && r2 < len2) { ++rcol2; r2 = tabs ? entab_adjust_rcol( diff2, len2, rcol2 ) : rcol2; c2 = (char)(r2 < len2 ? *(diff2 + r2) : 0); if (c2 == '\t' && tabs) c2 = ' '; } } /* * if one of the node pointers has come to EOL, move to next * diff line. */ if (diff.ignore_eol) { if (r1 >= len1) { node1 = skip_eol( node1, &r1, &rcol1, &rline1, &bin_offset1 ); len1 = node1->len; if (len1 != EOF) { diff1 = node1->line; c1 = (char)(r1 < len1 ? *(diff1 + r1) : 0); if (c1 == '\t' && tabs) c1 = ' '; } } if (r2 >= len2) { node2 = skip_eol( node2, &r2, &rcol2, &rline2, &bin_offset2 ); len2 = node2->len; if (len2 != EOF) { diff2 = node2->line; c2 = (char)(r2 < len2 ? *(diff2 + r2) : 0); if (c2 == '\t' && tabs) c2 = ' '; } } } /* * convert the characters to lower case, if needed. */ if (mode.search_case == IGNORE) { c1 = (char)tolower( c1 ); c2 = (char)tolower( c2 ); } /* * diff each character in the diff lines until we reach EOL */ while (r1 < len1 && r2 < len2) { if (c1 == c2) { if (diff.all_space) { do { ++rcol1; r1 = tabs ? entab_adjust_rcol( diff1,len1,rcol1 ) : rcol1; c1 = (char)(r1 < len1 ? *(diff1 + r1) : 0); if (c1 == '\t' && tabs) c1 = ' '; } while (c1 == ' ' && r1 < len1); do { ++rcol2; r2 = tabs ? entab_adjust_rcol( diff2,len2,rcol2 ) : rcol2; c2 = (char)(r2 < len2 ? *(diff2 + r2) : 0); if (c2 == '\t' && tabs) c2 = ' '; } while (c2 == ' ' && r2 < len2); } else { ++rcol1; ++rcol2; r1 = tabs ? entab_adjust_rcol( diff1, len1, rcol1 ) : rcol1; r2 = tabs ? entab_adjust_rcol( diff2, len2, rcol2 ) : rcol2; c1 = (char)(r1 < len1 ? *(diff1 + r1) : 0); c2 = (char)(r2 < len2 ? *(diff2 + r2) : 0); if (tabs) { if (c1 == '\t') c1 = ' '; if (c2 == '\t') c2 = ' '; } } if (diff.ignore_eol) { if (r1 >= len1) { node1 = skip_eol(node1, &r1, &rcol1, &rline1,&bin_offset1); len1 = node1->len; if (len1 != EOF) { diff1 = node1->line; c1 = (char)(r1 < len1 ? *(diff1 + r1) : 0); if (c1 == '\t' && tabs) c1 = ' '; } } if (r2 >= len2) { node2 = skip_eol(node2, &r2, &rcol2, &rline2,&bin_offset2); len2 = node2->len; if (len2 != EOF) { diff2 = node2->line; c2 = (char)(r2 < len2 ? *(diff2 + r2) : 0); if (c2 == '\t' && tabs) c2 = ' '; } } } if (mode.search_case == IGNORE) { c1 = (char)tolower( c1 ); c2 = (char)tolower( c2 ); } } else { /* * when we show the diff, use rcol1 and rcol2, as * find_adjust does not adjust rcol for tabs. */ update_line( diff.w1 ); diff.w1->bin_offset = bin_offset1; find_adjust( diff.w1, node1, rline1, rcol1 ); check_virtual_col( diff.w1, rcol1, rcol1 ); show_diff_window( diff.w1 ); update_line( diff.w2 ); diff.w2->bin_offset = bin_offset2; bin_offset_adjust( diff.w2, rline2 ); find_adjust( diff.w2, node2, rline2, rcol2 ); check_virtual_col( diff.w2, rcol2, rcol2 ); show_diff_window( diff.w2 ); s_output( diff_blank, g_display.mode_line, 67, g_display.mode_color ); return( OK ); } } /* * if we haven't come to the end of a file buffer, check the last * characters. see if pointers are at EOL. */ if (node1->len != EOF && node2->len != EOF) { if (rcol1 != len1 && rcol2 != len2) { update_line( diff.w1 ); diff.w1->bin_offset = bin_offset1; find_adjust( diff.w1, node1, rline1, rcol1 ); show_diff_window( diff.w1 ); update_line( diff.w2 ); diff.w2->bin_offset = bin_offset2; find_adjust( diff.w2, node2, rline2, rcol2 ); show_diff_window( diff.w2 ); s_output( diff_blank, g_display.mode_line, 67, g_display.mode_color ); return( OK ); } else { node1 = skip_eol( node1, &r1, &rcol1, &rline1, &bin_offset1 ); len1 = node1->len; diff1 = node1->line; node2 = skip_eol( node2, &r2, &rcol2, &rline2, &bin_offset2 ); len2 = node2->len; diff2 = node2->line; } } assert( rcol1 >= 0 ); assert( rcol1 < MAX_LINE_LENGTH ); assert( rcol2 >= 0 ); assert( rcol2 < MAX_LINE_LENGTH ); assert( r1 >= 0 ); assert( r1 < MAX_LINE_LENGTH ); assert( r2 >= 0 ); assert( r2 < MAX_LINE_LENGTH ); assert( r1 <= rcol1 ); assert( r2 <= rcol2 ); if (node1->len == EOF) assert( len1 == EOF ); else { assert( len1 >= 0 ); assert( len1 < MAX_LINE_LENGTH ); } if (node2->len == EOF) assert( len2 == EOF ); else { assert( len2 >= 0 ); assert( len2 < MAX_LINE_LENGTH ); } } save_screen_line( 0, bottom, line_buff ); set_prompt( diff_prompt4, bottom ); getkey( ); restore_screen_line( 0, bottom, line_buff ); s_output( diff_blank, g_display.mode_line, 67, g_display.mode_color ); } return( ERROR ); }
/* * Name: flush_center * Purpose: flush line in center of margins * Date: November 27, 1991 * Passed: window: pointer to current window */ int flush_center( WINDOW *window ) { int len; /* length of current line */ char *source; /* temp line buffer pointers */ char *dest; int rm; int lm; register int spaces; /* center of text on current line */ int center; /* center of current margins */ int first; /* column of first char on line */ int last; /* column of last char on line */ register WINDOW *win; /* put window pointer in a register */ win = window; copy_line( win->ll ); detab_linebuff( ); source = g_status.line_buff; len = g_status.line_buff_len; if (!is_line_blank( (text_ptr)source, len )) { rm = mode.right_margin; lm = mode.left_margin; center = (rm + lm) / 2; first = first_non_blank( (text_ptr)source, len ); for (last=len-1; last>=0 && *(source+last) == ' ';) last--; spaces = last + first - 1; spaces = (spaces / 2) + (spaces & 1); if (spaces != center) { /* * if spaces is less than center margin then we need to add spaces. */ if (spaces < center) { spaces = center - spaces; dest = source + spaces; if (len + spaces > MAX_LINE_LENGTH) { /* * line would be too long */ error( WARNING, win->bottom_line, ww1 ); return( ERROR ); } else { load_undo_buffer( win->file_info, win->ll->line, win->ll->len ); assert( len >= 0 ); assert( len < MAX_LINE_LENGTH ); memmove( dest, source, len ); g_status.line_buff_len += spaces; while (spaces--) *source++ = ' '; win->file_info->dirty = GLOBAL; } /* * if spaces is greater than center margin then we need to sub spaces. */ } else { load_undo_buffer( win->file_info, win->ll->line, win->ll->len ); spaces = spaces - center; if (spaces > first) spaces = first; dest = source + spaces; assert( len - spaces >= 0 ); assert( len - spaces < MAX_LINE_LENGTH ); memmove( source, dest, len - spaces ); g_status.line_buff_len -= spaces; win->file_info->dirty = GLOBAL; } win->ll->dirty = TRUE; show_changed_line( win ); } } return( OK ); }
/* * Name: flush_right * Purpose: flush line on right margin * Date: November 27, 1991 * Passed: window: pointer to current window */ int flush_right( WINDOW *window ) { int len; /* length of current line */ int i; int spaces; char *source; char *dest; register int rcol; int rm; register WINDOW *win; /* put window pointer in a register */ win = window; copy_line( win->ll ); detab_linebuff( ); source = g_status.line_buff; len = g_status.line_buff_len; if (!is_line_blank( (text_ptr)source, len )) { rm = mode.right_margin; for (rcol=len-1; rcol>=0 && *(source+rcol) == ' ';) rcol--; if (rcol != rm) { /* * if rcol is less than right margin then we need to add spaces. */ if (rcol < rm) { spaces = rm - rcol; dest = source + spaces; if (len + spaces > MAX_LINE_LENGTH) { /* * line would be too long */ error( WARNING, win->bottom_line, ww1 ); return( ERROR ); } else { load_undo_buffer( win->file_info, win->ll->line, win->ll->len ); assert( len >= 0 ); assert( len < MAX_LINE_LENGTH ); memmove( dest, source, len ); g_status.line_buff_len += spaces; while (spaces--) *source++ = ' '; win->file_info->dirty = GLOBAL; } /* * if rcol is greater than right margin then we need to sub spaces. */ } else { load_undo_buffer( win->file_info, win->ll->line, win->ll->len ); rcol = rcol - rm; i = first_non_blank( (text_ptr)source, len ); if (rcol > i) rcol = i; dest = source + rcol; assert( len - rcol >= 0 ); assert( len - rcol < MAX_LINE_LENGTH ); memmove( source, dest, len - rcol ); g_status.line_buff_len -= (rcol - rm); win->file_info->dirty = GLOBAL; } win->ll->dirty = TRUE; show_changed_line( win ); } } return( OK ); }
/* * Name: format_paragraph * Purpose: format paragraph using left, right, and paragraph margins. * Date: November 27, 1991 * Passed: window: pointer to current window */ int format_paragraph( WINDOW *window ) { register int len; /* length of current line */ int first_line; /* boolean, first line formatted? */ int spaces; /* no. of spaces to add */ line_list_ptr p; /* scratch pointers */ line_list_ptr pp; char *source; /* scratch line buffer pointers */ char *dest; int rcol; /* scratch cols and margins */ int lm; int rm; int pm; int margin; int eop; /* boolean, (e)nd (o)f (p)aragraph? */ int old_ww; /* save state of word wrap flag */ long rline; WINDOW w; /* scratch window */ if (window->ll->len == EOF) return( ERROR ); entab_linebuff( ); if (un_copy_line( window->ll, window, TRUE ) == ERROR) return( ERROR ); if (!is_line_blank( window->ll->line, window->ll->len )) { old_ww = mode.word_wrap; if (old_ww == NO_WRAP) mode.word_wrap = FIXED_WRAP; dup_window_info( &w, window ); g_status.screen_display = FALSE; /* * find the beginning of the paragraph. */ p = w.ll->prev; if (g_status.command == FormatParagraph) { while (p != NULL && !is_line_blank( p->line, p->len )) { --w.rline; w.ll = w.ll->prev; p = p->prev; } pm = mode.parg_margin; /* * if format text, don't find the beginning of the paragraph. * but we need to know if this is the first line in a paragraph. */ } else if (g_status.command == FormatText) { if (p == NULL || is_line_blank( p->line, p->len )) pm = mode.parg_margin; else pm = mode.left_margin; } else pm = mode.left_margin; g_status.command = WordWrap; p = w.ll; if (mode.word_wrap == FIXED_WRAP) lm = mode.left_margin; else lm = pm = find_left_margin( p, mode.word_wrap ); rm = mode.right_margin; eop = FALSE; /* * do the paragraph */ for (first_line=TRUE; p != NULL && !is_line_blank( p->line, p->len ) && eop == FALSE && !g_status.control_break;) { /* * find out what margin to use */ if (first_line) { margin = pm; first_line = FALSE; } else margin = lm; /* * line up the margin */ w.ll->dirty = TRUE; copy_line( w.ll ); detab_linebuff( ); remove_spaces( 0 ); rcol = find_word( (text_ptr)g_status.line_buff, g_status.line_buff_len, 0 ); if (rcol != ERROR && rcol != margin) { /* * must add spaces to get the indentation right */ if (rcol < margin) { source = g_status.line_buff; spaces = margin - rcol; dest = source + spaces; assert( g_status.line_buff_len >= 0 ); assert( g_status.line_buff_len < MAX_LINE_LENGTH ); memmove( dest, source, g_status.line_buff_len ); g_status.line_buff_len += spaces; while (spaces--) *source++ = ' '; } else { w.rcol = margin; word_delete( &w ); entab_linebuff( ); un_copy_line( p, &w, TRUE ); copy_line( w.ll ); detab_linebuff( ); remove_spaces( margin ); } } /* * now make sure rest of line is formatted */ source = g_status.line_buff; len = g_status.line_buff_len; for (; len < rm+1 && eop == FALSE;) { pp = p->next; if (is_line_blank( pp->line, pp->len )) eop = TRUE; else { w.ll = p; w.rcol = len + 1; if (*(p->line+len-1) == '.') ++w.rcol; word_delete( &w ); entab_linebuff( ); un_copy_line( p, &w, TRUE ); copy_line( p ); detab_linebuff( ); remove_spaces( margin ); len = g_status.line_buff_len; } } if (len <= rm+1) { entab_linebuff( ); un_copy_line( p, &w, TRUE ); p = p->next; if (is_line_blank( p->line, p->len )) eop = TRUE; else { w.ll = w.ll->next; w.rline++; } } else { w.rcol = rm; g_status.key_pressed = *(w.ll->line + rm); rline = w.rline; word_wrap( &w ); if (rline == w.rline) { w.ll = w.ll->next; ++w.rline; } } g_status.copied = FALSE; p = w.ll; } mode.word_wrap = old_ww; g_status.copied = FALSE; w.file_info->dirty = GLOBAL; g_status.screen_display = TRUE; } return( OK ); }
/* * Name: word_wrap * Purpose: make sure lines don't get longer than right margin * Date: November 27, 1991 * Passed: window: pointer to current window * Notes: rcol, lm, rm, pm all start counting at zero. * len (line length) starts counting at 1. * * when we compare margins and line lengths, we either have to * add one to the margins or subtract one from the len. I add * one to the margins. */ void word_wrap( WINDOW *window ) { int c; /* character the user just entered. */ register int len; /* length of current line */ int i; /* padding spaces required */ line_list_ptr p; /* line above wrapped line */ int rcol; int lm; int rm; int side; register WINDOW *win; /* put window pointer in a register */ win = window; /* * set up a few local variables. */ c = g_status.key_pressed; rcol = win->rcol; copy_line( win->ll ); detab_linebuff( ); /* * always start the right margin justification on the right side * at the beginning of paragraphs. then, alternate with left margin. */ side = 1; p = win->ll->prev; while (p != NULL && !is_line_blank( p->line, p->len )) { ++side; p = p->prev; } side = (side & 1) ? RIGHT : LEFT; /* * when we wrap, we need know where the left margin is. * let's look at the line above to see if this is the first line * in a paragraph. */ p = win->ll->prev; lm = find_left_margin( win->ll, mode.word_wrap ); rm = mode.right_margin; /* * there two ways that words are pushed onto next line. * 1. if the word being typed goes over the right margin * 2. typing a word in the middle of the line pushes words at end of * line to next line * * if the user enters spaces past the right margin then we don't * word wrap spaces. */ len = g_status.line_buff_len; if (rcol > rm+1 && c != ' ') { /* * if this is the first line in a paragraph then set left margin * to paragraph margin. */ if ((p == NULL || is_line_blank( p->line, p->len )) && first_non_blank( (text_ptr)g_status.line_buff, g_status.line_buff_len ) > rm && mode.word_wrap == FIXED_WRAP) lm = mode.parg_margin; /* * simple word wrap. the cursor goes past the right margin. * find the beginning of the word and put it on a new line. * * Special case - if the word begins at the left margin then * don't wrap it. */ for (i=rcol-1; i > lm && g_status.line_buff[i] != ' '; ) i--; if (i > lm) { i++; win->rcol = i; g_status.command = WordWrap; insert_newline( win ); if (mode.right_justify == TRUE) justify_right_margin( win, win->ll->prev, mode.word_wrap == FIXED_WRAP ? find_left_margin( win->ll->prev, mode.word_wrap ) : lm, rm, side ); /* * find out where to place the cursor on the new line. */ win->rcol = lm + rcol - i; check_virtual_col( win, win->rcol, win->rcol ); /* * we just wrapped the word at the eol. now, let's see if * we can combine it with the line below. since just added * a line, set new_line to false - don't add another line. */ len = find_end( win->ll->line, win->ll->len ); if (len < rm+1) combine_wrap_spill( win, len, lm, rm, side, FALSE ); } } else if (len > rm+1) { /* * this is the second word wrap case. we are pushing words onto * next line. we need to now what character is in the right margin. * * 1) if the character is not a space, then we need to search backwards * to find the start of the word that is on the right margin. * 2) if the character is a space, then we need to search forward to * find the word that is over the right margin. */ /* * don't wrap spaces past right margin */ if (c == ' ' && rcol > rm) { for (i=rcol; i<len && g_status.line_buff[i] == ' ';) i++; /* * if i == len then all that's left on line is blanks - don't wrap. */ if (i < len) combine_wrap_spill( win, i, lm, rm, side, TRUE ); } else if (g_status.line_buff[rm+1] != ' ') { /* * search backwards for the word to put on next line. */ for (i=rm+1; i > lm && g_status.line_buff[i] != ' '; ) i--; /* * if we search all the way back to left margin then test for * a special case - see the matching else for more info. */ if (i > lm) { i++; /* * if i > rcol then cursor stays on same line. */ if (i > rcol) { combine_wrap_spill( win, i, lm, rm, side, TRUE ); /* * split the line at or behind the cursor. almost the * same as when the cursor goes over the right margin. */ } else if (i <= rcol) { win->rcol = i; g_status.command = WordWrap; insert_newline( win ); if (mode.right_justify == TRUE) justify_right_margin( win, win->ll->prev, mode.word_wrap == FIXED_WRAP ? find_left_margin( win->ll->prev, mode.word_wrap ) : lm, rm, side ); win->rcol = lm + rcol - i; check_virtual_col( win, win->rcol, win->rcol ); len = find_end( win->ll->line, win->ll->len ); if (len < rm+1) combine_wrap_spill( win, len, lm, rm, side, FALSE ); } } /* * if the user changed margins or for some reason there's a long * text line, let's see if there are any words past the right * margin. if we get to this else, we know the current word * begins at least at the left margin. * * now search forwards for a break */ } else { /* * go to the right margin and see if there are any words past * right margin. */ for (i=rm+1; i<len && g_status.line_buff[i] == ' '; ) i++; /* * we either found a space or the eol. test for eol. * if i == len then this is one big word - don't wrap it. */ if (i != len) combine_wrap_spill( win, i, lm, rm, side, TRUE ); } } }