Esempio n. 1
0
/*
 * 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 );
}
Esempio n. 2
0
/*
 * 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;
      }
   }
}
Esempio n. 3
0
/*
 * 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 );
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
/*
 * 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 );
}
Esempio n. 6
0
/*
 * 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 );
}
Esempio n. 7
0
/*
 * 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 );
}
Esempio n. 8
0
/*
 * 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 );
}
Esempio n. 9
0
/*
 * 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 );
      }
   }
}