/* * 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 ); }
/* * language_breakdown_copy_comment * * copies the passed in string (via delimiters) to the comment buffer * * Returns 1 on success, 0 on buffer overflow. Buffer overflows typically occur * for language syntax errors (e.g. unclosed strings or block comments) or * parser errors. */ int language_breakdown_copy_comment(LanguageBreakdown *lb, char *from, char *to) { from = first_non_blank(from, to); if (lb->comment_cur + (to - from) >= lb->comment + lb->buffer_size) return 0; // overflow error strncpy(lb->comment_cur, from, to - from); lb->comment_cur += to - from; *lb->comment_cur = 0; return 1; }
/* * 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: 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: 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 ); } } }