Annotation of micropolis/src/tk/tktxidx.c, revision 1.1

1.1     ! root        1: /* 
        !             2:  * tkTextIndex.c --
        !             3:  *
        !             4:  *     This module provides procedures that manipulate indices for
        !             5:  *     text widgets.
        !             6:  *
        !             7:  * Copyright 1992 Regents of the University of California.
        !             8:  * Permission to use, copy, modify, and distribute this
        !             9:  * software and its documentation for any purpose and without
        !            10:  * fee is hereby granted, provided that the above copyright
        !            11:  * notice appear in all copies.  The University of California
        !            12:  * makes no representations about the suitability of this
        !            13:  * software for any purpose.  It is provided "as is" without
        !            14:  * express or implied warranty.
        !            15:  */
        !            16: 
        !            17: #ifndef lint
        !            18: static char rcsid[] = "$Header: /user6/ouster/wish/RCS/tkTextIndex.c,v 1.2 92/07/16 16:32:26 ouster Exp $ SPRITE (Berkeley)";
        !            19: #endif
        !            20: 
        !            21: #include "default.h"
        !            22: #include "tkconfig.h"
        !            23: #include "tk.h"
        !            24: #include "tktext.h"
        !            25: 
        !            26: /*
        !            27:  * Forward declarations for procedures defined later in this file:
        !            28:  */
        !            29: 
        !            30: static void            BackwardChars _ANSI_ARGS_((TkText *textPtr,
        !            31:                            TkTextLine *linePtr, int *lineIndexPtr,
        !            32:                            int *chPtr, int count));
        !            33: static char *          ForwBack _ANSI_ARGS_((TkText *textPtr,
        !            34:                            char *string, int *lineIndexPtr, int *chPtr));
        !            35: static void            ForwardChars _ANSI_ARGS_((TkText *textPtr,
        !            36:                            TkTextLine *linePtr, int *lineIndexPtr,
        !            37:                            int *chPtr, int count));
        !            38: static char *          StartEnd _ANSI_ARGS_((TkText *textPtr,
        !            39:                            char *string, int *lineIndexPtr, int *chPtr));
        !            40: 
        !            41: /*
        !            42:  *----------------------------------------------------------------------
        !            43:  *
        !            44:  * TkTextGetIndex --
        !            45:  *
        !            46:  *     Given a string, return the line and character indices that
        !            47:  *     it describes.
        !            48:  *
        !            49:  * Results:
        !            50:  *     The return value is a standard Tcl return result.  If
        !            51:  *     TCL_OK is returned, then everything went well and information
        !            52:  *     is stored at *lineIndexPtr and *chPtr;  otherwise TCL_ERROR
        !            53:  *     is returned and an error message is left in interp->result.
        !            54:  *
        !            55:  * Side effects:
        !            56:  *     None.
        !            57:  *
        !            58:  *----------------------------------------------------------------------
        !            59:  */
        !            60: 
        !            61: int
        !            62: TkTextGetIndex(interp, textPtr, string, lineIndexPtr, chPtr)
        !            63:     Tcl_Interp *interp;                /* Use this for error reporting. */
        !            64:     TkText *textPtr;           /* Information about text widget. */
        !            65:     char *string;              /* Textual description of position. */
        !            66:     int *lineIndexPtr;         /* Store line number here. */
        !            67:     int *chPtr;                        /* Store character position here. */
        !            68: {
        !            69:     register char *p;
        !            70:     char *end, *endOfBase;
        !            71:     TkTextLine *linePtr;
        !            72:     Tcl_HashEntry *hPtr;
        !            73:     TkAnnotation *markPtr;
        !            74:     TkTextTag *tagPtr;
        !            75:     TkTextSearch search;
        !            76:     int first;
        !            77:     char c;
        !            78: 
        !            79:     /*
        !            80:      *------------------------------------------------
        !            81:      * Stage 1: parse the base index.
        !            82:      *------------------------------------------------
        !            83:      */
        !            84: 
        !            85:     if (string[0] == '@') {
        !            86:        /*
        !            87:         * Find character at a given x,y location in the window.
        !            88:         */
        !            89: 
        !            90:        int x, y;
        !            91: 
        !            92:        p = string+1;
        !            93:        x = strtol(p, &end, 0);
        !            94:        if ((end == p) || (*end != ',')) {
        !            95:            goto error;
        !            96:        }
        !            97:        p = end+1;
        !            98:        y = strtol(p, &end, 0);
        !            99:        if (end == p) {
        !           100:            goto error;
        !           101:        }
        !           102:        *lineIndexPtr = TkBTreeLineIndex(TkTextCharAtLoc(textPtr, x,
        !           103:                y, chPtr));
        !           104:        endOfBase = end;
        !           105:        goto gotBase; 
        !           106:     } else if (isdigit(string[0]) || (string[0] == '-')) {
        !           107:        /*
        !           108:         * Base is identified with line and character indices.
        !           109:         */
        !           110: 
        !           111:        *lineIndexPtr = strtol(string, &end, 0) - 1;
        !           112:        if ((end == string) || (*end != '.')) {
        !           113:            goto error;
        !           114:        }
        !           115:        p = end+1;
        !           116:        if ((*p == 'e') && (strncmp(p, "end", 3) == 0)) {
        !           117:            linePtr = TkBTreeFindLine(textPtr->tree, *lineIndexPtr);
        !           118:            if (linePtr == NULL) {
        !           119:                Tcl_AppendResult(interp, "bad text index \"", string,
        !           120:                        "\": no such line in text", (char *) NULL);
        !           121:                return TCL_ERROR;
        !           122:            }
        !           123:            *chPtr = linePtr->numBytes - 1;
        !           124:            endOfBase = p+3;
        !           125:            goto gotBase;
        !           126:        } else {
        !           127:            *chPtr = strtol(p, &end, 0);
        !           128:            if (end == p) {
        !           129:                goto error;
        !           130:            }
        !           131:            endOfBase = end;
        !           132:            goto gotBase;
        !           133:        }
        !           134:     }
        !           135: 
        !           136:     for (p = string; *p != 0; p++) {
        !           137:        if (isspace(*p) || (*p == '+') || (*p == '-')) {
        !           138:            break;
        !           139:        }
        !           140:     }
        !           141:     endOfBase = p;
        !           142:     if ((string[0] == 'e')
        !           143:            && (strncmp(string, "end", endOfBase-string) == 0)) {
        !           144:        /*
        !           145:         * Base position is end of text.
        !           146:         */
        !           147: 
        !           148:        *lineIndexPtr = TkBTreeNumLines(textPtr->tree) - 1;
        !           149:        linePtr = TkBTreeFindLine(textPtr->tree, *lineIndexPtr);
        !           150:        *chPtr = linePtr->numBytes - 1;
        !           151:        goto gotBase;
        !           152:     } else {
        !           153:        /*
        !           154:         * See if the base position is the name of a mark.
        !           155:         */
        !           156: 
        !           157:        c = *endOfBase;
        !           158:        *endOfBase = 0;
        !           159:        hPtr = Tcl_FindHashEntry(&textPtr->markTable, string);
        !           160:        *endOfBase = c;
        !           161:        if (hPtr != NULL) {
        !           162:            markPtr = (TkAnnotation *) Tcl_GetHashValue(hPtr);
        !           163:            *lineIndexPtr = TkBTreeLineIndex(markPtr->linePtr);
        !           164:            *chPtr = markPtr->ch;
        !           165:            goto gotBase;
        !           166:        }
        !           167:     }
        !           168: 
        !           169:     /*
        !           170:      * Nothing has worked so far.  See if the base has the form
        !           171:      * "tag.first" or "tag.last" where "tag" is the name of a valid
        !           172:      * tag.
        !           173:      */
        !           174: 
        !           175:     p = strchr(string, '.');
        !           176:     if (p == NULL) {
        !           177:        goto error;
        !           178:     }
        !           179:     if ((p[1] == 'f') && (endOfBase == (p+6))
        !           180:            && (strncmp(p+1, "first", endOfBase - (p+1)) == 0)) {
        !           181:        first = 1;
        !           182:     } else if ((p[1] == 'l') && (endOfBase == (p+5))
        !           183:            && (strncmp(p+1, "last", endOfBase - (p+1)) == 0)) {
        !           184:        first = 0;
        !           185:     } else {
        !           186:        goto error;
        !           187:     }
        !           188:     *p = 0;
        !           189:     hPtr = Tcl_FindHashEntry(&textPtr->tagTable, string);
        !           190:     *p = '.';
        !           191:     if (hPtr == NULL) {
        !           192:        goto error;
        !           193:     }
        !           194:     tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr);
        !           195:     TkBTreeStartSearch(textPtr->tree, 0, 0, TkBTreeNumLines(textPtr->tree),
        !           196:            0, tagPtr, &search);
        !           197:     if (!TkBTreeNextTag(&search)) {
        !           198:        Tcl_AppendResult(interp,
        !           199:                "text doesn't contain any characters tagged with \"",
        !           200:                Tcl_GetHashKey(&textPtr->tagTable, hPtr), "\"", (char *) NULL);
        !           201:        return TCL_ERROR;
        !           202:     }
        !           203:     if (first) {
        !           204:        *lineIndexPtr = search.line1;
        !           205:        *chPtr = search.ch1;
        !           206:     } else {
        !           207:        while (TkBTreeNextTag(&search)) {
        !           208:            *lineIndexPtr = search.line1;
        !           209:            *chPtr = search.ch1;
        !           210:        }
        !           211:     }
        !           212: 
        !           213:     /*
        !           214:      *-------------------------------------------------------------------
        !           215:      * Stage 2: process zero or more modifiers.  Each modifier is either
        !           216:      * a keyword like "wordend" or "linestart", or it has the form
        !           217:      * "op count units" where op is + or -, count is a number, and units
        !           218:      * is "chars" or "lines".
        !           219:      *-------------------------------------------------------------------
        !           220:      */
        !           221: 
        !           222:     gotBase:
        !           223:     p = endOfBase;
        !           224:     while (1) {
        !           225:        while (isspace(*p)) {
        !           226:            p++;
        !           227:        }
        !           228:        if (*p == 0) {
        !           229:            return TCL_OK;
        !           230:        }
        !           231:     
        !           232:        if ((*p == '+') || (*p == '-')) {
        !           233:            p = ForwBack(textPtr, p, lineIndexPtr, chPtr);
        !           234:        } else {
        !           235:            p = StartEnd(textPtr, p, lineIndexPtr, chPtr);
        !           236:        }
        !           237:        if (p == NULL) {
        !           238:            goto error;
        !           239:        }
        !           240:     }
        !           241: 
        !           242:     error:
        !           243:     Tcl_AppendResult(interp, "bad text index \"", string, "\"",
        !           244:            (char *) NULL);
        !           245:     return TCL_ERROR;
        !           246: }
        !           247: 
        !           248: /*
        !           249:  *----------------------------------------------------------------------
        !           250:  *
        !           251:  * TkTextPrintIndex --
        !           252:  *
        !           253:  *     Given a line number and a character index, this procedure
        !           254:  *     generates a string description of the position, which is
        !           255:  *     suitable for reading in again later.
        !           256:  *
        !           257:  * Results:
        !           258:  *     The characters pointed to by string are modified.
        !           259:  *
        !           260:  * Side effects:
        !           261:  *     None.
        !           262:  *
        !           263:  *----------------------------------------------------------------------
        !           264:  */
        !           265: 
        !           266: void
        !           267: TkTextPrintIndex(line, ch, string)
        !           268:     int line;                  /* Line number. */
        !           269:     int ch;                    /* Character position within line. */
        !           270:     char *string;              /* Place to store the position.  Must have
        !           271:                                 * at least POS_CHARS characters. */
        !           272: {
        !           273:     sprintf(string, "%d.%d", line+1, ch);
        !           274: }
        !           275: 
        !           276: /*
        !           277:  *----------------------------------------------------------------------
        !           278:  *
        !           279:  * TkTextRoundIndex --
        !           280:  *
        !           281:  *     Given a line index and a character index, this procedure
        !           282:  *     adjusts those positions if necessary to correspond to the
        !           283:  *     nearest actual character within the text.
        !           284:  *
        !           285:  * Results:
        !           286:  *     The return value is a pointer to the line structure for
        !           287:  *     the line of the text's B-tree that contains the indicated
        !           288:  *     character.  In addition, *lineIndexPtr and *chPtr are
        !           289:  *     modified if necessary to refer to an existing character
        !           290:  *     in the file.
        !           291:  *
        !           292:  * Side effects:
        !           293:  *     None.
        !           294:  *
        !           295:  *----------------------------------------------------------------------
        !           296:  */
        !           297: 
        !           298: 
        !           299: TkTextLine *
        !           300: TkTextRoundIndex(textPtr, lineIndexPtr, chPtr)
        !           301:     TkText *textPtr;                   /* Information about text widget. */
        !           302:     int *lineIndexPtr;                 /* Points to initial line index,
        !           303:                                         * which is overwritten with actual
        !           304:                                         * line index. */
        !           305:     int *chPtr;                                /* Points to initial character index,
        !           306:                                         * which is overwritten with actual
        !           307:                                         * character index. */
        !           308: {
        !           309:     int line, ch, lastLine;
        !           310:     TkTextLine *linePtr;
        !           311: 
        !           312:     line = *lineIndexPtr;
        !           313:     ch = *chPtr;
        !           314:     if (line < 0) {
        !           315:        line = 0;
        !           316:        ch = 0;
        !           317:     }
        !           318:     lastLine = TkBTreeNumLines(textPtr->tree) - 1;
        !           319:     if (line > lastLine) {
        !           320:        line = lastLine;
        !           321:        linePtr = TkBTreeFindLine(textPtr->tree, line);
        !           322:        ch = linePtr->numBytes - 1;
        !           323:     } else {
        !           324:        linePtr = TkBTreeFindLine(textPtr->tree, line);
        !           325:        if (ch < 0) {
        !           326:            ch = 0;
        !           327:        }
        !           328:        if (ch >= linePtr->numBytes) {
        !           329:            if (line == lastLine) {
        !           330:                ch = linePtr->numBytes - 1;
        !           331:            } else {
        !           332:                line++;
        !           333:                linePtr = TkBTreeNextLine(linePtr);
        !           334:                ch = 0;
        !           335:            }
        !           336:        }
        !           337:     }
        !           338:     *lineIndexPtr = line;
        !           339:     *chPtr = ch;
        !           340:     return linePtr;
        !           341: }
        !           342: 
        !           343: /*
        !           344:  *----------------------------------------------------------------------
        !           345:  *
        !           346:  * ForwBack --
        !           347:  *
        !           348:  *     This procedure handles +/- modifiers for indices to adjust
        !           349:  *     the index forwards or backwards.
        !           350:  *
        !           351:  * Results:
        !           352:  *     If the modifier is successfully parsed then the return value
        !           353:  *     is the address of the first character after the modifier, and
        !           354:  *     *lineIndexPtr and *chPtr are updated to reflect the modifier.
        !           355:  *     If there is a syntax error in the modifier then NULL is returned.
        !           356:  *
        !           357:  * Side effects:
        !           358:  *     None.
        !           359:  *
        !           360:  *----------------------------------------------------------------------
        !           361:  */
        !           362: 
        !           363: static char *
        !           364: ForwBack(textPtr, string, lineIndexPtr, chPtr)
        !           365:     TkText *textPtr;           /* Information about widget that index
        !           366:                                 * refers to. */
        !           367:     char *string;              /* String to parse for additional info
        !           368:                                 * about modifier (count and units). 
        !           369:                                 * Points to "+" or "-" that starts
        !           370:                                 * modifier. */
        !           371:     int *lineIndexPtr;         /* Points to current line index, which will
        !           372:                                 * be updated to reflect modifier. */
        !           373:     int *chPtr;                        /* Points to current character index, which
        !           374:                                 * will be updated to reflect modifier. */
        !           375: {
        !           376:     register char *p;
        !           377:     char *end, *units;
        !           378:     int count, length, lastLine;
        !           379:     TkTextLine *linePtr;
        !           380: 
        !           381:     /*
        !           382:      * Get the count (how many units forward or backward).
        !           383:      */
        !           384: 
        !           385:     p = string+1;
        !           386:     while (isspace(*p)) {
        !           387:        p++;
        !           388:     }
        !           389:     count = strtoul(p, &end, 0);
        !           390:     if (end == p) {
        !           391:        return NULL;
        !           392:     }
        !           393:     p = end;
        !           394:     while (isspace(*p)) {
        !           395:        p++;
        !           396:     }
        !           397: 
        !           398:     /*
        !           399:      * Find the end of this modifier (next space or + or - character),
        !           400:      * then parse the unit specifier and update the position
        !           401:      * accordingly.
        !           402:      */
        !           403: 
        !           404:     units = p; 
        !           405:     while ((*p != 0) && !isspace(*p) && (*p != '+') && (*p != '-')) {
        !           406:        p++;
        !           407:     }
        !           408:     length = p - units;
        !           409:     if ((*units == 'c') && (strncmp(units, "chars", length) == 0)) {
        !           410:        linePtr = TkTextRoundIndex(textPtr, lineIndexPtr, chPtr);
        !           411:        if (*string == '+') {
        !           412:            ForwardChars(textPtr, linePtr, lineIndexPtr, chPtr, count);
        !           413:        } else {
        !           414:            BackwardChars(textPtr, linePtr, lineIndexPtr, chPtr, count);
        !           415:        }
        !           416:     } else if ((*units == 'l') && (strncmp(units, "lines", length) == 0)) {
        !           417:        if (*string == '+') {
        !           418:            *lineIndexPtr += count;
        !           419:            lastLine = TkBTreeNumLines(textPtr->tree) - 1;
        !           420:            if (*lineIndexPtr > lastLine) {
        !           421:                *lineIndexPtr = lastLine;
        !           422:            }
        !           423:        } else {
        !           424:            *lineIndexPtr -= count;
        !           425:            if (*lineIndexPtr < 0) {
        !           426:                *lineIndexPtr = 0;
        !           427:            }
        !           428:        }
        !           429:        linePtr = TkBTreeFindLine(textPtr->tree, *lineIndexPtr);
        !           430:        if (*chPtr >= linePtr->numBytes) {
        !           431:            *chPtr = linePtr->numBytes - 1;
        !           432:        }
        !           433:        if (*chPtr < 0) {
        !           434:            *chPtr = 0;
        !           435:        }
        !           436:     } else {
        !           437:        return NULL;
        !           438:     }
        !           439:     return p;
        !           440: }
        !           441: 
        !           442: /*
        !           443:  *----------------------------------------------------------------------
        !           444:  *
        !           445:  * ForwardChars --
        !           446:  *
        !           447:  *     Given a position in a text widget, this procedure computes
        !           448:  *     a new position that is "count" characters ahead of the given
        !           449:  *     position.
        !           450:  *
        !           451:  * Results:
        !           452:  *     *LineIndexPtr and *chPtr are overwritten with new values
        !           453:  *     corresponding to the new position.
        !           454:  *
        !           455:  * Side effects:
        !           456:  *     None.
        !           457:  *
        !           458:  *----------------------------------------------------------------------
        !           459:  */
        !           460: 
        !           461:        /* ARGSUSED */
        !           462: static void
        !           463: ForwardChars(textPtr, linePtr, lineIndexPtr, chPtr, count)
        !           464:     TkText *textPtr;                   /* Information about text widget. */
        !           465:     register TkTextLine *linePtr;      /* Text line corresponding to
        !           466:                                         * *lineIndexPtr. */
        !           467:     int *lineIndexPtr;                 /* Points to initial line index,
        !           468:                                         * which is overwritten with final
        !           469:                                         * line index. */
        !           470:     int *chPtr;                                /* Points to initial character index,
        !           471:                                         * which is overwritten with final
        !           472:                                         * character index. */
        !           473:     int count;                         /* How many characters forward to
        !           474:                                         * move.  Must not be negative. */
        !           475: {
        !           476:     TkTextLine *nextPtr;
        !           477:     int bytesInLine;
        !           478: 
        !           479:     while (count > 0) {
        !           480:        bytesInLine = linePtr->numBytes - *chPtr;
        !           481:        if (bytesInLine > count) {
        !           482:            *chPtr += count;
        !           483:            return;
        !           484:        }
        !           485:        nextPtr = TkBTreeNextLine(linePtr);
        !           486:        if (nextPtr == NULL) {
        !           487:            *chPtr = linePtr->numBytes - 1;
        !           488:            return;
        !           489:        }
        !           490:        *chPtr = 0;
        !           491:        *lineIndexPtr += 1;
        !           492:        linePtr = nextPtr;
        !           493:        count -= bytesInLine;
        !           494:     }
        !           495: }
        !           496: 
        !           497: /*
        !           498:  *----------------------------------------------------------------------
        !           499:  *
        !           500:  * BackwardChars --
        !           501:  *
        !           502:  *     Given a position in a text widget, this procedure computes
        !           503:  *     a new position that is "count" characters earlier than the given
        !           504:  *     position.
        !           505:  *
        !           506:  * Results:
        !           507:  *     *LineIndexPtr and *chPtr are overwritten with new values
        !           508:  *     corresponding to the new position.
        !           509:  *
        !           510:  * Side effects:
        !           511:  *     None.
        !           512:  *
        !           513:  *----------------------------------------------------------------------
        !           514:  */
        !           515: 
        !           516: static void
        !           517: BackwardChars(textPtr, linePtr, lineIndexPtr, chPtr, count)
        !           518:     TkText *textPtr;                   /* Information about text widget. */
        !           519:     register TkTextLine *linePtr;      /* Text line corresponding to
        !           520:                                         * *lineIndexPtr. */
        !           521:     int *lineIndexPtr;                 /* Points to initial line index,
        !           522:                                         * which is overwritten with final
        !           523:                                         * line index. */
        !           524:     int *chPtr;                                /* Points to initial character index,
        !           525:                                         * which is overwritten with final
        !           526:                                         * character index. */
        !           527:     int count;                         /* How many characters backward to
        !           528:                                         * move.  Must not be negative. */
        !           529: {
        !           530:     int bytesInLine;
        !           531: 
        !           532:     while (count > 0) {
        !           533:        bytesInLine = *chPtr;
        !           534:        if (bytesInLine >= count) {
        !           535:            *chPtr -= count;
        !           536:            return;
        !           537:        }
        !           538:        if (*lineIndexPtr <= 0) {
        !           539:            *chPtr = 0;
        !           540:            return;
        !           541:        }
        !           542:        *lineIndexPtr -= 1;
        !           543:        linePtr = TkBTreeFindLine(textPtr->tree, *lineIndexPtr);
        !           544:        count -= bytesInLine;
        !           545:        *chPtr = linePtr->numBytes;
        !           546:     }
        !           547: }
        !           548: 
        !           549: /*
        !           550:  *----------------------------------------------------------------------
        !           551:  *
        !           552:  * StartEnd --
        !           553:  *
        !           554:  *     This procedure handles modifiers like "wordstart" and "lineend"
        !           555:  *     to adjust indices forwards or backwards.
        !           556:  *
        !           557:  * Results:
        !           558:  *     If the modifier is successfully parsed then the return value
        !           559:  *     is the address of the first character after the modifier, and
        !           560:  *     *lineIndexPtr and *chPtr are updated to reflect the modifier.
        !           561:  *     If there is a syntax error in the modifier then NULL is returned.
        !           562:  *
        !           563:  * Side effects:
        !           564:  *     None.
        !           565:  *
        !           566:  *----------------------------------------------------------------------
        !           567:  */
        !           568: 
        !           569: static char *
        !           570: StartEnd(textPtr, string, lineIndexPtr, chPtr)
        !           571:     TkText *textPtr;           /* Information about widget that index
        !           572:                                 * refers to. */
        !           573:     char *string;              /* String to parse for additional info
        !           574:                                 * about modifier (count and units). 
        !           575:                                 * Points to first character of modifer
        !           576:                                 * word. */
        !           577:     int *lineIndexPtr;         /* Points to current line index, which will
        !           578:                                 * be updated to reflect modifier. */
        !           579:     int *chPtr;                        /* Points to current character index, which
        !           580:                                 * will be updated to reflect modifier. */
        !           581: {
        !           582:     char *p, c;
        !           583:     int length;
        !           584:     register TkTextLine *linePtr;
        !           585: 
        !           586:     /*
        !           587:      * Find the end of the modifier word.
        !           588:      */
        !           589: 
        !           590:     for (p = string; isalnum(*p); p++) {
        !           591:        /* Empty loop body. */
        !           592:     }
        !           593:     length = p-string;
        !           594:     linePtr = TkTextRoundIndex(textPtr, lineIndexPtr, chPtr);
        !           595:     if ((*string == 'l') && (strncmp(string, "lineend", length) == 0)
        !           596:            && (length >= 5)) {
        !           597:        *chPtr = linePtr->numBytes - 1;
        !           598:     } else if ((*string == 'l') && (strncmp(string, "linestart", length) == 0)
        !           599:            && (length >= 5)) {
        !           600:        *chPtr = 0;
        !           601:     } else if ((*string == 'w') && (strncmp(string, "wordend", length) == 0)
        !           602:            && (length >= 5)) {
        !           603:        c = linePtr->bytes[*chPtr];
        !           604:        if (!isalnum(c) && (c != '_')) {
        !           605:            if (*chPtr >= (linePtr->numBytes - 1)) {
        !           606:                /*
        !           607:                 * End of line:  go to start of next line unless this is the
        !           608:                 * last line in the text.
        !           609:                 */
        !           610: 
        !           611:                if (TkBTreeNextLine(linePtr) != NULL) {
        !           612:                    *lineIndexPtr += 1;
        !           613:                    *chPtr = 0;
        !           614:                }
        !           615:            } else {
        !           616:                *chPtr += 1;
        !           617:            }
        !           618:        } else {
        !           619:            do {
        !           620:                *chPtr += 1;
        !           621:                c = linePtr->bytes[*chPtr];
        !           622:            } while (isalnum(c) || (c == '_'));
        !           623:        }
        !           624:     } else if ((*string == 'w') && (strncmp(string, "wordstart", length) == 0)
        !           625:            && (length >= 5)) {
        !           626:        c = linePtr->bytes[*chPtr];
        !           627:        if (isalnum(c) || (c == '_')) {
        !           628:            while (*chPtr > 0) {
        !           629:                c = linePtr->bytes[(*chPtr) - 1];
        !           630:                if (!isalnum(c) && (c != '_')) {
        !           631:                    break;
        !           632:                }
        !           633:                *chPtr -= 1;
        !           634:            }
        !           635:        }
        !           636:     } else {
        !           637:        return NULL;
        !           638:     }
        !           639:     return p;
        !           640: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.