/*
* tkTextIndex.c --
*
* This module provides procedures that manipulate indices for
* text widgets.
*
* Copyright (c) 1992-1994 The Regents of the University of California.
* Copyright (c) 1994-1995 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* SCCS: @(#) tkTextIndex.c 1.13 96/02/15 18:52:57
*/
#include "tkInt.h"
#include "tkText.h"
#include "tkDefault.h"
/*
* Index to use to select last character in line (very large integer):
*/
/*
* Forward declarations for procedures defined later in this file:
*/
TkTextIndex *indexPtr));
TkTextIndex *indexPtr));
/*
*--------------------------------------------------------------
*
* TkTextMakeIndex --
*
* Given a line index and a character index, look things up
* in the B-tree and fill in a TkTextIndex structure.
*
* Results:
* The structure at *indexPtr is filled in with information
* about the character at lineIndex and charIndex (or the
* closest existing character, if the specified one doesn't
* exist), and indexPtr is returned as result.
*
* Side effects:
* None.
*
*--------------------------------------------------------------
*/
* to. */
int lineIndex; /* Index of desired line (0 means first
* line of text). */
int charIndex; /* Index of desired character. */
{
int index;
if (lineIndex < 0) {
lineIndex = 0;
charIndex = 0;
}
if (charIndex < 0) {
charIndex = 0;
}
charIndex = 0;
}
/*
* Verify that the index is within the range of the line.
* If not, just use the index of the last character in the line.
*/
break;
}
break;
}
}
return indexPtr;
}
/*
*--------------------------------------------------------------
*
* TkTextIndexToSeg --
*
* Given an index, this procedure returns the segment and
* offset within segment for the index.
*
* Results:
* The return value is a pointer to the segment referred to
* by indexPtr; this will always be a segment with non-zero
* size. The variable at *offsetPtr is set to hold the
* integer offset within the segment of the character
* given by indexPtr.
*
* Side effects:
* None.
*
*--------------------------------------------------------------
*/
int *offsetPtr; /* Where to store offset within
* segment, or NULL if offset isn't
* wanted. */
{
int offset;
/* Empty loop body. */
}
}
return segPtr;
}
/*
*--------------------------------------------------------------
*
* TkTextSegToOffset --
*
* Given a segment pointer and the line containing it, this
* procedure returns the offset of the segment within its
* line.
*
* Results:
* The return value is the offset (within its line) of the
* first character in segPtr.
*
* Side effects:
* None.
*
*--------------------------------------------------------------
*/
int
{
int offset;
offset = 0;
}
return offset;
}
/*
*----------------------------------------------------------------------
*
* TkTextGetIndex --
*
* Given a string, return the line and character indices that
* it describes.
*
* Results:
* The return value is a standard Tcl return result. If
* TCL_OK is returned, then everything went well and the index
* at *indexPtr is filled in; otherwise TCL_ERROR is returned
* and an error message is left in interp->result.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
char *string; /* Textual description of position. */
{
register char *p;
char c;
/*
*---------------------------------------------------------------------
* Stage 1: check to see if the index consists of nothing but a mar
* name. We do this check now even though it's also done later, in
* order to allow mark names that include funny characters such as
* spaces or "+1c".
*---------------------------------------------------------------------
*/
return TCL_OK;
}
/*
*------------------------------------------------
* Stage 2: start again by parsing the base index.
*------------------------------------------------
*/
/*
* First look for the form "tag.first" or "tag.last" where "tag"
* is the name of a valid tag. Try to use up as much as possible
* of the string in this check (strrchr instead of strchr below).
* Doing the check now, and in this way, allows tag names to include
* funny characters like "@" or "+1c".
*/
if (p != NULL) {
wantLast = 0;
endOfBase = p+6;
wantLast = 1;
endOfBase = p+5;
} else {
goto tryxy;
}
*p = 0;
*p = '.';
goto tryxy;
}
&last);
"text doesn't contain any characters tagged with \"",
(char *) NULL);
return TCL_ERROR;
}
if (wantLast) {
while (TkBTreeNextTag(&search)) {
}
}
goto gotBase;
}
if (string[0] == '@') {
/*
* Find character at a given x,y location in the window.
*/
int x, y;
p = string+1;
goto error;
}
p = end+1;
if (end == p) {
goto error;
}
goto gotBase;
}
/*
* Base is identified with line and character indices.
*/
goto error;
}
p = end+1;
endOfBase = p+3;
} else {
if (end == p) {
goto error;
}
}
goto gotBase;
}
for (p = string; *p != 0; p++) {
break;
}
}
endOfBase = p;
if (string[0] == '.') {
/*
* See if the base position is the name of an embedded window.
*/
c = *endOfBase;
*endOfBase = 0;
*endOfBase = c;
if (result != 0) {
goto gotBase;
}
}
if ((string[0] == 'e')
/*
* Base position is end of text.
*/
0, indexPtr);
goto gotBase;
} else {
/*
* See if the base position is the name of a mark.
*/
c = *endOfBase;
*endOfBase = 0;
*endOfBase = c;
goto gotBase;
}
}
goto error;
/*
*-------------------------------------------------------------------
* Stage 3: process zero or more modifiers. Each modifier is either
* a keyword like "wordend" or "linestart", or it has the form
* "op count units" where op is + or -, count is a number, and units
* is "chars" or "lines".
*-------------------------------------------------------------------
*/
p = endOfBase;
while (1) {
p++;
}
if (*p == 0) {
break;
}
if ((*p == '+') || (*p == '-')) {
} else {
}
if (p == NULL) {
goto error;
}
}
return TCL_OK;
(char *) NULL);
return TCL_ERROR;
}
/*
*----------------------------------------------------------------------
*
* TkTextPrintIndex --
*
*
* This procedure generates a string description of an index,
* suitable for reading in again later.
*
* Results:
* The characters pointed to by string are modified.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
char *string; /* Place to store the position. Must have
* at least TK_POS_CHARS characters. */
{
}
/*
*--------------------------------------------------------------
*
* TkTextIndexCmp --
*
* Compare two indices to see which one is earlier in
* the text.
*
* Results:
* The return value is 0 if index1Ptr and index2Ptr refer
* to the same position in the file, -1 if index1Ptr refers
* to an earlier position than index2Ptr, and 1 otherwise.
*
* Side effects:
* None.
*
*--------------------------------------------------------------
*/
int
{
return -1;
return 1;
} else {
return 0;
}
}
return -1;
}
return 1;
}
return 0;
}
/*
*----------------------------------------------------------------------
*
* ForwBack --
*
* This procedure handles +/- modifiers for indices to adjust
* the index forwards or backwards.
*
* Results:
* If the modifier in string is successfully parsed then the
* return value is the address of the first character after the
* modifier, and *indexPtr is updated to reflect the modifier.
* If there is a syntax error in the modifier then NULL is returned.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static char *
char *string; /* String to parse for additional info
* about modifier (count and units).
* Points to "+" or "-" that starts
* modifier. */
{
register char *p;
/*
* Get the count (how many units forward or backward).
*/
p = string+1;
p++;
}
if (end == p) {
return NULL;
}
p = end;
p++;
}
/*
* Find the end of this modifier (next space or + or - character),
* then parse the unit specifier and update the position
* accordingly.
*/
units = p;
p++;
}
if (*string == '+') {
} else {
}
if (*string == '+') {
} else {
/*
* The check below retains the character position, even
* if the line runs off the start of the file. Without
* it, the character position will get reset to 0 by
* TkTextMakeIndex.
*/
if (lineIndex < 0) {
lineIndex = 0;
}
}
indexPtr);
} else {
return NULL;
}
return p;
}
/*
*----------------------------------------------------------------------
*
* TkTextIndexForwChars --
*
* Given an index for a text widget, this procedure creates a
* new index that points "count" characters ahead of the source
* index.
*
* Results:
* *dstPtr is modified to refer to the character "count" characters
* after srcPtr, or to the last character in the file if there aren't
* "count" characters left in the file.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
void
int count; /* How many characters forward to
* move. May be negative. */
{
int lineLength;
if (count < 0) {
return;
}
while (1) {
/*
* Compute the length of the current line.
*/
lineLength = 0;
}
/*
* If the new index is in the same line then we're done.
* Otherwise go on to the next line.
*/
return;
}
return;
}
}
}
/*
*----------------------------------------------------------------------
*
* TkTextIndexBackChars --
*
* Given an index for a text widget, this procedure creates a
* new index that points "count" characters earlier than the
* source index.
*
* Results:
* *dstPtr is modified to refer to the character "count" characters
* before srcPtr, or to the first character in the file if there aren't
* "count" characters earlier than srcPtr.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
int count; /* How many characters backward to
* move. May be negative. */
{
int lineIndex;
if (count < 0) {
return;
}
lineIndex = -1;
/*
* Move back one line in the text. If we run off the beginning
* of the file then just return the first character in the text.
*/
if (lineIndex < 0) {
}
if (lineIndex == 0) {
return;
}
lineIndex--;
/*
* Compute the length of the line and add that to dstPtr->charIndex.
*/
}
}
}
/*
*----------------------------------------------------------------------
*
* StartEnd --
*
* This procedure handles modifiers like "wordstart" and "lineend"
* to adjust indices forwards or backwards.
*
* Results:
* If the modifier is successfully parsed then the return value
* is the address of the first character after the modifier, and
* *indexPtr is updated to reflect the modifier. If there is a
* syntax error in the modifier then NULL is returned.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static char *
char *string; /* String to parse for additional info
* about modifier (count and units).
* Points to first character of modifer
* word. */
{
char *p;
int c, offset;
/*
* Find the end of the modifier word.
*/
/* Empty loop body. */
}
&& (length >= 5)) {
}
&& (length >= 5)) {
&& (length >= 5)) {
/*
* If the current character isn't part of a word then just move
* forward one character. Otherwise move forward until finding
* a character that isn't part of a word and stop there.
*/
while (1) {
break;
}
firstChar = 0;
}
offset += 1;
}
}
if (firstChar) {
}
&& (length >= 5)) {
/*
* Starting with the current character, look for one that's not
* part of a word and keep moving backward until you find one.
* Then if the character found wasn't the first one, move forward
* again one position.
*/
while (1) {
break;
}
firstChar = 0;
}
offset -= 1;
if (offset < 0) {
goto done;
}
}
}
if (!firstChar) {
}
} else {
return NULL;
}
done:
return p;
}