⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 editbuf.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
//    This is part of the iostream library, providing input/output for C++.//    Copyright (C) 1991 Per Bothner.////    This library is free software; you can redistribute it and/or//    modify it under the terms of the GNU Library General Public//    License as published by the Free Software Foundation; either//    version 2 of the License, or (at your option) any later version.////    This library 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//    Library General Public License for more details.////    You should have received a copy of the GNU Library General Public//    License along with this library; if not, write to the Free//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.#include "ioprivate.h"#include "editbuf.h"#include <stddef.h>#ifdef __GNUG__#pragma implementation#endif/* NOTE: Some of the code here is taken from GNU emacs *//* Hence this file falls under the GNU License! */// Invariants for edit_streambuf:// An edit_streambuf is associated with a specific edit_string,// which again is a sub-string of a specific edit_buffer.// An edit_streambuf is always in either get mode or put mode, never both.// In get mode, gptr() is the current position,// and pbase(), pptr(), and epptr() are all NULL.// In put mode, pptr() is the current position,// and eback(), gptr(), and egptr() are all NULL.// Any edit_streambuf that is actively doing insertion (as opposed to// replacing) // must have its pptr() pointing to the start of the gap.// Only one edit_streambuf can be actively inserting into a specific// edit_buffer; the edit_buffer's _writer field points to that edit_streambuf.// That edit_streambuf "owns" the gap, and the actual start of the// gap is the pptr() of the edit_streambuf; the edit_buffer::_gap_start pointer// will only be updated on an edit_streambuf::overflow().int edit_streambuf::truncate(){    str->buffer->delete_range(str->buffer->tell((buf_char*)pptr()),			      str->buffer->tell(str->end));    return 0;}#ifdef OLD_STDIOinline void  disconnect_gap_from_file(edit_buffer* buffer, FILE* fp){    if (buffer->gap_start_ptr != &fp->__bufp)	return;    buffer->gap_start_normal = fp->__bufp;    buffer->gap_start_ptr = &buffer->gap_start_normal;}#endifvoid edit_streambuf::flush_to_buffer(edit_buffer* buffer){    if (pptr() > buffer->_gap_start && pptr() < buffer->gap_end())	buffer->_gap_start = pptr();}void edit_streambuf::disconnect_gap_from_file(edit_buffer* buffer){    if (buffer->_writer != this) return;    flush_to_buffer(buffer);    setp(pptr(),pptr());    buffer->_writer = NULL;    }buf_index edit_buffer::tell(buf_char *ptr){    if (ptr <= gap_start())	return ptr - data;    else	return ptr - gap_end() + size1();}#if 0buf_index buf_cookie::tell(){    return str->buffer->tell(file->__bufp);}#endifbuf_index edit_buffer::tell(edit_mark*mark){    return tell(data + mark->index_in_buffer(this));}// adjust the position of the gapvoid edit_buffer::move_gap(buf_offset pos){  if (pos < size1())    gap_left (pos);  else if (pos > size1())    gap_right (pos);}void edit_buffer::gap_left (int pos){  register buf_char *to, *from;  register int i;  int new_s1;  i = size1();  from = gap_start();  to = from + gap_size();  new_s1 = size1();  /* Now copy the characters.  To move the gap down,     copy characters up.  */  for (;;)    {      /* I gets number of characters left to copy.  */      i = new_s1 - pos;      if (i == 0)	break;#if 0      /* If a quit is requested, stop copying now.	 Change POS to be where we have actually moved the gap to.  */      if (QUITP)	{	  pos = new_s1;	  break;	}#endif      /* Move at most 32000 chars before checking again for a quit.  */      if (i > 32000)	i = 32000;      new_s1 -= i;      while (--i >= 0)	*--to = *--from;    }  /* Adjust markers, and buffer data structure, to put the gap at POS.     POS is where the loop above stopped, which may be what was specified     or may be where a quit was detected.  */  adjust_markers (pos << 1, size1() << 1, gap_size(), data);#ifndef OLD_STDIO  _gap_start = data + pos;#else  if (gap_start_ptr == &gap_start_normal)	gap_start_normal = data + pos;#endif  __gap_end_pos = to - data;/*  QUIT;*/}void edit_buffer::gap_right (int pos){  register buf_char *to, *from;  register int i;  int new_s1;  i = size1();  to = gap_start();  from = i + gap_end();  new_s1 = i;  /* Now copy the characters.  To move the gap up,     copy characters down.  */  while (1)    {      /* I gets number of characters left to copy.  */      i = pos - new_s1;      if (i == 0)	break;#if 0      /* If a quit is requested, stop copying now.	 Change POS to be where we have actually moved the gap to.  */      if (QUITP)	{	  pos = new_s1;	  break;	}#endif      /* Move at most 32000 chars before checking again for a quit.  */      if (i > 32000)	i = 32000;      new_s1 += i;      while (--i >= 0)	*to++ = *from++;    }  adjust_markers ((size1() + gap_size()) << 1, (pos + gap_size()) << 1,	- gap_size(), data);#ifndef OLD_STDIO  _gap_start = data+pos;#else  if (gap_start_ptr == &gap_start_normal)	gap_start_normal = data + pos;#endif  __gap_end_pos = from - data;/*  QUIT;*/}/* make sure that the gap in the current buffer is at least k   characters wide */void edit_buffer::make_gap(buf_offset k){  register buf_char *p1, *p2, *lim;  buf_char *old_data = data;  int s1 = size1();  if (gap_size() >= k)    return;  /* Get more than just enough */  if (buf_size > 1000) k += 2000;  else k += /*200;*/ 20; // for testing!  p1 = (buf_char *) realloc (data, s1 + size2() + k);  if (p1 == 0)    abort(); /*memory_full ();*/  k -= gap_size();			/* Amount of increase.  */  /* Record new location of text */  data = p1;  /* Transfer the new free space from the end to the gap     by shifting the second segment upward */  p2 = data + buf_size;  p1 = p2 + k;  lim = p2 - size2();  while (lim < p2)    *--p1 = *--p2;  /* Finish updating text location data */  __gap_end_pos += k;#ifndef OLD_STDIO  _gap_start = data + s1;#else  if (gap_start_ptr == &gap_start_normal)	gap_start_normal = data + s1;#endif  /* adjust markers */  adjust_markers (s1 << 1, (buf_size << 1) + 1, k, old_data);  buf_size += k;}/* Add `amount' to the position of every marker in the current buffer   whose current position is between `from' (exclusive) and `to' (inclusive).   Also, any markers past the outside of that interval, in the direction   of adjustment, are first moved back to the near end of the interval   and then adjusted by `amount'.  */void edit_buffer::adjust_markers(register mark_pointer low,				 register mark_pointer high,				 int amount, buf_char *old_data){  register struct edit_mark *m;  register mark_pointer mpos;  /* convert to mark_pointer */  amount <<= 1;  if (_writer)      _writer->disconnect_gap_from_file(this);  for (m = mark_list(); m != NULL; m = m->chain)    {      mpos = m->_pos;      if (amount > 0)	{	  if (mpos > high && mpos < high + amount)	    mpos = high + amount;	}      else	{	  if (mpos > low + amount && mpos <= low)	    mpos = low + amount;	}      if (mpos > low && mpos <= high)	mpos += amount;      m->_pos = mpos;    }    // Now adjust files    edit_streambuf *file;    for (file = files; file != NULL; file = file->next) {	mpos = file->current() - old_data;	if (amount > 0)	{	  if (mpos > high && mpos < high + amount)	    mpos = high + amount;	}	else	{	  if (mpos > low + amount && mpos <= low)	    mpos = low + amount;	}	if (mpos > low && mpos <= high)	    mpos += amount;	char* new_pos = data + mpos;	file->set_current(new_pos, file->is_reading());    }}#if 0stdio_   __off == index at start of buffer (need only be valid after seek ? )   __buf ==if read/read_delete/overwrite mode:     __endp <= min(*gap_start_ptr, edit_string->end->ptr(buffer))if inserting:     must have *gap_start_ptr == __bufp && *gap_start_ptr+gap == __endp     file->edit_string->end->ptr(buffer) == *gap_start_ptr+endif write_mode:     if before gap#endifint edit_streambuf::underflow(){    if (!(_mode & ios::in))	return EOF;    struct edit_buffer *buffer = str->buffer;    if (!is_reading()) { // Must switch from put to get mode.	disconnect_gap_from_file(buffer);	set_current(pptr(), 1);    }    buf_char *str_end = str->end->ptr(buffer);  retry:    if (gptr() < egptr()) {	return *gptr();    }    if ((buf_char*)gptr() == str_end)	return EOF;    if (str_end <= buffer->gap_start()) {	setg(eback(), gptr(), str_end);	goto retry;    }    if (gptr() < buffer->gap_start()) {	setg(eback(), gptr(), buffer->gap_start());	goto retry;    }    if (gptr() == buffer->gap_start()) {	disconnect_gap_from_file(buffer);//	fp->__offset += fp->__bufp - fp->__buffer;	setg(buffer->gap_end(), buffer->gap_end(), str_end);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -