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

📄 document.cxx

📁 robocup rcssserver 运行防真机器人足球比赛所用的服务器端
💻 CXX
📖 第 1 页 / 共 3 页
字号:
// Scintilla source code edit control/** @file Document.cxx ** Text document that handles notifications, DBCS, styling, words and end of line. **/// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>// The License.txt file describes the conditions under which this software may be distributed.#include <stdlib.h>#include <string.h>#include <stdio.h>#include <ctype.h>#include "Platform.h"#include "Scintilla.h"#include "SVector.h"#include "CellBuffer.h"#include "CharClassify.h"#include "Document.h"#include "RESearch.h"// This is ASCII specific but is safe with chars >= 0x80static inline bool isspacechar(unsigned char ch) {	return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));}static inline bool IsPunctuation(char ch) {	return isascii(ch) && ispunct(ch);}static inline bool IsADigit(char ch) {	return isascii(ch) && isdigit(ch);}static inline bool IsLowerCase(char ch) {	return isascii(ch) && islower(ch);}static inline bool IsUpperCase(char ch) {	return isascii(ch) && isupper(ch);}Document::Document() {	refCount = 0;#ifdef unix	eolMode = SC_EOL_LF;#else	eolMode = SC_EOL_CRLF;#endif	dbcsCodePage = 0;	stylingBits = 5;	stylingBitsMask = 0x1F;	stylingMask = 0;	endStyled = 0;	styleClock = 0;	enteredCount = 0;	enteredReadOnlyCount = 0;	tabInChars = 8;	indentInChars = 0;	actualIndentInChars = 8;	useTabs = true;	tabIndents = true;	backspaceUnindents = false;	watchers = 0;	lenWatchers = 0;	matchesValid = false;	pre = 0;	substituted = 0;}Document::~Document() {	for (int i = 0; i < lenWatchers; i++) {		watchers[i].watcher->NotifyDeleted(this, watchers[i].userData);	}	delete []watchers;	watchers = 0;	lenWatchers = 0;	delete pre;	pre = 0;	delete []substituted;	substituted = 0;}// Increase reference count and return its previous value.int Document::AddRef() {	return refCount++;}// Decrease reference count and return its previous value.// Delete the document if reference count reaches zero.int Document::Release() {	int curRefCount = --refCount;	if (curRefCount == 0)		delete this;	return curRefCount;}void Document::SetSavePoint() {	cb.SetSavePoint();	NotifySavePoint(true);}int Document::AddMark(int line, int markerNum) {	int prev = cb.AddMark(line, markerNum);	DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);	mh.line = line;	NotifyModified(mh);	return prev;}void Document::AddMarkSet(int line, int valueSet) {	unsigned int m = valueSet;	for (int i = 0; m; i++, m >>= 1)		if (m & 1)			cb.AddMark(line, i);	DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);	mh.line = line;	NotifyModified(mh);}void Document::DeleteMark(int line, int markerNum) {	cb.DeleteMark(line, markerNum);	DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);	mh.line = line;	NotifyModified(mh);}void Document::DeleteMarkFromHandle(int markerHandle) {	cb.DeleteMarkFromHandle(markerHandle);	DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);	mh.line = -1;	NotifyModified(mh);}void Document::DeleteAllMarks(int markerNum) {	cb.DeleteAllMarks(markerNum);	DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);	mh.line = -1;	NotifyModified(mh);}int Document::LineStart(int line) {	return cb.LineStart(line);}int Document::LineEnd(int line) {	if (line == LinesTotal() - 1) {		return LineStart(line + 1);	} else {		int position = LineStart(line + 1) - 1;		// When line terminator is CR+LF, may need to go back one more		if ((position > LineStart(line)) && (cb.CharAt(position - 1) == '\r')) {			position--;		}		return position;	}}int Document::LineFromPosition(int pos) {	return cb.LineFromPosition(pos);}int Document::LineEndPosition(int position) {	return LineEnd(LineFromPosition(position));}int Document::VCHomePosition(int position) {	int line = LineFromPosition(position);	int startPosition = LineStart(line);	int endLine = LineStart(line + 1) - 1;	int startText = startPosition;	while (startText < endLine && (cb.CharAt(startText) == ' ' || cb.CharAt(startText) == '\t' ) )		startText++;	if (position == startText)		return startPosition;	else		return startText;}int Document::SetLevel(int line, int level) {	int prev = cb.SetLevel(line, level);	if (prev != level) {		DocModification mh(SC_MOD_CHANGEFOLD | SC_MOD_CHANGEMARKER,		                   LineStart(line), 0, 0, 0);		mh.line = line;		mh.foldLevelNow = level;		mh.foldLevelPrev = prev;		NotifyModified(mh);	}	return prev;}static bool IsSubordinate(int levelStart, int levelTry) {	if (levelTry & SC_FOLDLEVELWHITEFLAG)		return true;	else		return (levelStart & SC_FOLDLEVELNUMBERMASK) < (levelTry & SC_FOLDLEVELNUMBERMASK);}int Document::GetLastChild(int lineParent, int level) {	if (level == -1)		level = GetLevel(lineParent) & SC_FOLDLEVELNUMBERMASK;	int maxLine = LinesTotal();	int lineMaxSubord = lineParent;	while (lineMaxSubord < maxLine - 1) {		EnsureStyledTo(LineStart(lineMaxSubord + 2));		if (!IsSubordinate(level, GetLevel(lineMaxSubord + 1)))			break;		lineMaxSubord++;	}	if (lineMaxSubord > lineParent) {		if (level > (GetLevel(lineMaxSubord + 1) & SC_FOLDLEVELNUMBERMASK)) {			// Have chewed up some whitespace that belongs to a parent so seek back			if (GetLevel(lineMaxSubord) & SC_FOLDLEVELWHITEFLAG) {				lineMaxSubord--;			}		}	}	return lineMaxSubord;}int Document::GetFoldParent(int line) {	int level = GetLevel(line) & SC_FOLDLEVELNUMBERMASK;	int lineLook = line - 1;	while ((lineLook > 0) && (	            (!(GetLevel(lineLook) & SC_FOLDLEVELHEADERFLAG)) ||	            ((GetLevel(lineLook) & SC_FOLDLEVELNUMBERMASK) >= level))	      ) {		lineLook--;	}	if ((GetLevel(lineLook) & SC_FOLDLEVELHEADERFLAG) &&	        ((GetLevel(lineLook) & SC_FOLDLEVELNUMBERMASK) < level)) {		return lineLook;	} else {		return -1;	}}int Document::ClampPositionIntoDocument(int pos) {	return Platform::Clamp(pos, 0, Length());}bool Document::IsCrLf(int pos) {	if (pos < 0)		return false;	if (pos >= (Length() - 1))		return false;	return (cb.CharAt(pos) == '\r') && (cb.CharAt(pos + 1) == '\n');}static const int maxBytesInDBCSCharacter=5;int Document::LenChar(int pos) {	if (pos < 0) {		return 1;	} else if (IsCrLf(pos)) {		return 2;	} else if (SC_CP_UTF8 == dbcsCodePage) {		unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));		if (ch < 0x80)			return 1;		int len = 2;		if (ch >= (0x80 + 0x40 + 0x20))			len = 3;		int lengthDoc = Length();		if ((pos + len) > lengthDoc)			return lengthDoc -pos;		else			return len;	} else if (dbcsCodePage) {		char mbstr[maxBytesInDBCSCharacter+1];		int i;		for (i=0; i<Platform::DBCSCharMaxLength(); i++) {			mbstr[i] = cb.CharAt(pos+i);		}		mbstr[i] = '\0';		return Platform::DBCSCharLength(dbcsCodePage, mbstr);	} else {		return 1;	}}// Normalise a position so that it is not halfway through a two byte character.// This can occur in two situations -// When lines are terminated with \r\n pairs which should be treated as one character.// When displaying DBCS text such as Japanese.// If moving, move the position in the indicated direction.int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {	//Platform::DebugPrintf("NoCRLF %d %d\n", pos, moveDir);	// If out of range, just return minimum/maximum value.	if (pos <= 0)		return 0;	if (pos >= Length())		return Length();	// PLATFORM_ASSERT(pos > 0 && pos < Length());	if (checkLineEnd && IsCrLf(pos - 1)) {		if (moveDir > 0)			return pos + 1;		else			return pos - 1;	}	// Not between CR and LF	if (dbcsCodePage) {		if (SC_CP_UTF8 == dbcsCodePage) {			unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));			while ((pos > 0) && (pos < Length()) && (ch >= 0x80) && (ch < (0x80 + 0x40))) {				// ch is a trail byte				if (moveDir > 0)					pos++;				else					pos--;				ch = static_cast<unsigned char>(cb.CharAt(pos));			}		} else {			// Anchor DBCS calculations at start of line because start of line can			// not be a DBCS trail byte.			int posCheck = LineStart(LineFromPosition(pos));			while (posCheck < pos) {				char mbstr[maxBytesInDBCSCharacter+1];				int i;				for(i=0;i<Platform::DBCSCharMaxLength();i++) {					mbstr[i] = cb.CharAt(posCheck+i);				}				mbstr[i] = '\0';				int mbsize = Platform::DBCSCharLength(dbcsCodePage, mbstr);				if (posCheck + mbsize == pos) {					return pos;				} else if (posCheck + mbsize > pos) {					if (moveDir > 0) {						return posCheck + mbsize;					} else {						return posCheck;					}				}				posCheck += mbsize;			}		}	}	return pos;}void Document::ModifiedAt(int pos) {	if (endStyled > pos)		endStyled = pos;}void Document::CheckReadOnly() {	if (cb.IsReadOnly() && enteredReadOnlyCount == 0) {		enteredReadOnlyCount++;		NotifyModifyAttempt();		enteredReadOnlyCount--;	}}// Document only modified by gateways DeleteChars, InsertStyledString, Undo, Redo, and SetStyleAt.// SetStyleAt does not change the persistent state of a document// Unlike Undo, Redo, and InsertStyledString, the pos argument is a cell number not a char numberbool Document::DeleteChars(int pos, int len) {	if (len == 0)		return false;	if ((pos + len) > Length())		return false;	CheckReadOnly();	if (enteredCount != 0) {		return false;	} else {		enteredCount++;		if (!cb.IsReadOnly()) {			NotifyModified(			    DocModification(			        SC_MOD_BEFOREDELETE | SC_PERFORMED_USER,			        pos, len,			        0, 0));			int prevLinesTotal = LinesTotal();			bool startSavePoint = cb.IsSavePoint();			const char *text = cb.DeleteChars(pos * 2, len * 2);			if (startSavePoint && cb.IsCollectingUndo())				NotifySavePoint(!startSavePoint);			if ((pos < Length()) || (pos == 0))				ModifiedAt(pos);			else				ModifiedAt(pos-1);			NotifyModified(			    DocModification(			        SC_MOD_DELETETEXT | SC_PERFORMED_USER,			        pos, len,			        LinesTotal() - prevLinesTotal, text));		}		enteredCount--;	}	return !cb.IsReadOnly();}/** * Insert a styled string (char/style pairs) with a length. */bool Document::InsertStyledString(int position, char *s, int insertLength) {	CheckReadOnly();	if (enteredCount != 0) {		return false;	} else {		enteredCount++;		if (!cb.IsReadOnly()) {			NotifyModified(			    DocModification(			        SC_MOD_BEFOREINSERT | SC_PERFORMED_USER,			        position / 2, insertLength / 2,			        0, s));			int prevLinesTotal = LinesTotal();			bool startSavePoint = cb.IsSavePoint();			const char *text = cb.InsertString(position, s, insertLength);			if (startSavePoint && cb.IsCollectingUndo())				NotifySavePoint(!startSavePoint);			ModifiedAt(position / 2);			NotifyModified(			    DocModification(			        SC_MOD_INSERTTEXT | SC_PERFORMED_USER,			        position / 2, insertLength / 2,			        LinesTotal() - prevLinesTotal, text));		}		enteredCount--;	}	return !cb.IsReadOnly();}int Document::Undo() {	int newPos = -1;	CheckReadOnly();	if (enteredCount == 0) {		enteredCount++;		if (!cb.IsReadOnly()) {			bool startSavePoint = cb.IsSavePoint();			bool multiLine = false;			int steps = cb.StartUndo();			//Platform::DebugPrintf("Steps=%d\n", steps);			for (int step = 0; step < steps; step++) {				const int prevLinesTotal = LinesTotal();				const Action &action = cb.GetUndoStep();				if (action.at == removeAction) {					NotifyModified(DocModification(									SC_MOD_BEFOREINSERT | SC_PERFORMED_UNDO, action));				} else {					NotifyModified(DocModification(									SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action));				}				cb.PerformUndoStep();				int cellPosition = action.position;				ModifiedAt(cellPosition);				newPos = cellPosition;				int modFlags = SC_PERFORMED_UNDO;				// With undo, an insertion action becomes a deletion notification				if (action.at == removeAction) {					newPos += action.lenData;					modFlags |= SC_MOD_INSERTTEXT;				} else {					modFlags |= SC_MOD_DELETETEXT;				}				if (steps > 1)					modFlags |= SC_MULTISTEPUNDOREDO;				const int linesAdded = LinesTotal() - prevLinesTotal;				if (linesAdded != 0)					multiLine = true;				if (step == steps - 1) {					modFlags |= SC_LASTSTEPINUNDOREDO;					if (multiLine)						modFlags |= SC_MULTILINEUNDOREDO;				}				NotifyModified(DocModification(modFlags, cellPosition, action.lenData,											   linesAdded, action.data));			}			bool endSavePoint = cb.IsSavePoint();			if (startSavePoint != endSavePoint)				NotifySavePoint(endSavePoint);		}		enteredCount--;	}	return newPos;}int Document::Redo() {	int newPos = -1;	CheckReadOnly();	if (enteredCount == 0) {		enteredCount++;		if (!cb.IsReadOnly()) {			bool startSavePoint = cb.IsSavePoint();			bool multiLine = false;			int steps = cb.StartRedo();			for (int step = 0; step < steps; step++) {				const int prevLinesTotal = LinesTotal();				const Action &action = cb.GetRedoStep();				if (action.at == insertAction) {					NotifyModified(DocModification(									SC_MOD_BEFOREINSERT | SC_PERFORMED_REDO, action));				} else {					NotifyModified(DocModification(									SC_MOD_BEFOREDELETE | SC_PERFORMED_REDO, action));				}				cb.PerformRedoStep();				ModifiedAt(action.position);				newPos = action.position;				int modFlags = SC_PERFORMED_REDO;				if (action.at == insertAction) {					newPos += action.lenData;					modFlags |= SC_MOD_INSERTTEXT;				} else {					modFlags |= SC_MOD_DELETETEXT;				}				if (steps > 1)					modFlags |= SC_MULTISTEPUNDOREDO;				const int linesAdded = LinesTotal() - prevLinesTotal;				if (linesAdded != 0)					multiLine = true;				if (step == steps - 1) {					modFlags |= SC_LASTSTEPINUNDOREDO;					if (multiLine)

⌨️ 快捷键说明

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