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

📄 highlight.c

📁 nedit 是一款linux下的开发源码的功能强大的编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
/*** Callback wrapper around the above function.*/static void handleUnparsedRegionCB(textDisp *textD, int pos, void *cbArg){    handleUnparsedRegion((WindowInfo*)cbArg, textD->styleBuffer, pos);}/*** Re-parse the smallest region possible around a modification to buffer "buf"** to gurantee that the promised context lines and characters have** been presented to the patterns.  Changes the style buffer in "highlightData"** with the parsing result.*/static void incrementalReparse(windowHighlightData *highlightData,    	textBuffer *buf, int pos, int nInserted, const char *delimiters){    int beginParse, endParse, endAt, lastMod, parseInStyle, nPasses;    textBuffer *styleBuf = highlightData->styleBuffer;    highlightDataRec *pass1Patterns = highlightData->pass1Patterns;    highlightDataRec *pass2Patterns = highlightData->pass2Patterns;    highlightDataRec *startPattern;    reparseContext *context = &highlightData->contextRequirements;    char *parentStyles = highlightData->parentStyles;    /* Find the position "beginParse" at which to begin reparsing.  This is       far enough back in the buffer such that the guranteed number of       lines and characters of context are examined. */    beginParse = pos;    parseInStyle = findSafeParseRestartPos(buf, highlightData, &beginParse);    /* Find the position "endParse" at which point it is safe to stop       parsing, unless styles are getting changed beyond the last       modification */    lastMod = pos + nInserted;    endParse = forwardOneContext(buf, context, lastMod);        /*    ** Parse the buffer from beginParse, until styles compare    ** with originals for one full context distance.  Distance increases    ** by powers of two until nothing changes from previous step.  If    ** parsing ends before endParse, start again one level up in the    ** pattern hierarchy    */    for (nPasses=0; ; nPasses++) {		/* Parse forward from beginParse to one context beyond the end	   of the last modification */        startPattern = patternOfStyle(pass1Patterns, parseInStyle);        /* If there is no pattern matching the style, it must be a pass-2           style. It that case, it is (probably) safe to start parsing with           the root pass-1 pattern again. Anyway, passing a NULL-pointer to           the parse routine would result in a crash; restarting with pass-1            patterns is certainly preferable, even if there is a slight chance            of a faulty coloring. */	if (!startPattern) {	    startPattern = pass1Patterns;	}    	endAt = parseBufferRange(startPattern,    	    	pass2Patterns, buf, styleBuf, context, beginParse, endParse,		delimiters);		/* If parse completed at this level, move one style up in the	   hierarchy and start again from where the previous parse left off. */	if (endAt < endParse) {	    beginParse = endAt;	    endParse = forwardOneContext(buf, context,	    	    max(endAt, max(lastModified(styleBuf), lastMod)));	    if (IS_PLAIN(parseInStyle)) {		fprintf(stderr,			"NEdit internal error: incr. reparse fell short\n");		return;	    }	    parseInStyle = parentStyleOf(parentStyles, parseInStyle);	    	/* One context distance beyond last style changed means we're done */	} else if (lastModified(styleBuf) <= lastMod) {	    return;	    	/* Styles are changing beyond the modification, continue extending	   the end of the parse range by powers of 2 * REPARSE_CHUNK_SIZE and	   reparse until nothing changes */	} else {	    lastMod = lastModified(styleBuf);    	    endParse = min(buf->length, forwardOneContext(buf, context, lastMod)    	    	    + (REPARSE_CHUNK_SIZE << nPasses));	}    }	}/*** Parse text in buffer "buf" between positions "beginParse" and "endParse"** using pass 1 patterns over the entire range and pass 2 patterns where needed** to determine whether re-parsed areas have changed and need to be redrawn.** Deposits style information in "styleBuf" and expands the selection in** styleBuf to show the additional areas which have changed and need** redrawing.  beginParse must be a position from which pass 1 parsing may** safely be started using the pass1Patterns given.  Internally, adds a** "takeoff" safety region before beginParse, so that pass 2 patterns will be** allowed to match properly if they begin before beginParse, and a "landing"** safety region beyond endparse so that endParse is guranteed to be parsed** correctly in both passes.  Returns the buffer position at which parsing** finished (this will normally be endParse, unless the pass1Patterns is a** pattern which does end and the end is reached).*/static int parseBufferRange(highlightDataRec *pass1Patterns,    	highlightDataRec *pass2Patterns, textBuffer *buf, textBuffer *styleBuf,        reparseContext *contextRequirements, int beginParse, int endParse,        const char *delimiters){    char *string, *styleString, *stringPtr, *stylePtr, *temp, prevChar;    int endSafety, endPass2Safety, startPass2Safety, tempLen;    int modStart, modEnd, beginSafety, beginStyle, p, style;    int firstPass2Style = pass2Patterns == NULL ? INT_MAX :	    (unsigned char)pass2Patterns[1].style;        /* Begin parsing one context distance back (or to the last style change) */    beginStyle = pass1Patterns->style;    if (CAN_CROSS_LINE_BOUNDARIES(contextRequirements)) {    	beginSafety = backwardOneContext(buf, contextRequirements, beginParse);     	for (p=beginParse; p>=beginSafety; p--) {    	    style = BufGetCharacter(styleBuf, p-1);    	    if (!EQUIVALENT_STYLE(style, beginStyle, firstPass2Style)) {    	    	beginSafety = p;    	    	break;    	    }    	}    } else {    	for (beginSafety=max(0,beginParse-1); beginSafety>0; beginSafety--) {    	    style = BufGetCharacter(styleBuf, beginSafety);    	    if (!EQUIVALENT_STYLE(style, beginStyle, firstPass2Style) ||    	    	    BufGetCharacter(buf, beginSafety) == '\n') {    	    	beginSafety++;    	    	break;    	    }    	}    }        /* Parse one parse context beyond requested end to gurantee that parsing       at endParse is complete, unless patterns can't cross line boundaries,       in which case the end of the line is fine */    if (endParse == 0)    	return 0;    if (CAN_CROSS_LINE_BOUNDARIES(contextRequirements))    	endSafety = forwardOneContext(buf, contextRequirements, endParse);    else if (endParse>=buf->length || (BufGetCharacter(buf,endParse-1)=='\n'))    	endSafety = endParse;    else    	endSafety = min(buf->length, BufEndOfLine(buf, endParse) + 1);        /* copy the buffer range into a string */    string = BufGetRange(buf, beginSafety, endSafety);    styleString = BufGetRange(styleBuf, beginSafety, endSafety);        /* Parse it with pass 1 patterns */    /* printf("parsing from %d thru %d\n", beginSafety, endSafety); */    prevChar = getPrevChar(buf, beginParse);    stringPtr = &string[beginParse-beginSafety];    stylePtr = &styleString[beginParse-beginSafety];    parseString(pass1Patterns, &stringPtr, &stylePtr, endParse-beginParse,    	    &prevChar, False, delimiters, string);    /* On non top-level patterns, parsing can end early */    endParse = min(endParse, stringPtr-string + beginSafety);        /* If there are no pass 2 patterns, we're done */    if (pass2Patterns == NULL)    	goto parseDone;        /* Parsing of pass 2 patterns is done only as necessary for determining       where styles have changed.  Find the area to avoid, which is already       marked as changed (all inserted text and previously modified areas) */    if (styleBuf->primary.selected) {	modStart = styleBuf->primary.start;	modEnd = styleBuf->primary.end;    } else    	modStart = modEnd = 0;        /* Re-parse the areas before the modification with pass 2 patterns, from       beginSafety to far enough beyond modStart to gurantee that parsing at       modStart is correct (pass 2 patterns must match entirely within one       context distance, and only on the top level).  If the parse region       ends entirely before the modification or at or beyond modEnd, parse       the whole thing and take advantage of the safety region which will be       thrown away below.  Otherwise save the contents of the safety region       temporarily, and restore it after the parse. */    if (beginSafety < modStart) {	if (endSafety > modStart) {	    endPass2Safety = forwardOneContext(buf, contextRequirements,	    	    modStart);	    if (endPass2Safety + PASS_2_REPARSE_CHUNK_SIZE >= modEnd)	    	endPass2Safety = endSafety;    	} else    	    endPass2Safety = endSafety;	prevChar = getPrevChar(buf, beginSafety);	if (endPass2Safety == endSafety) {	    passTwoParseString(pass2Patterns, string, styleString,	    	endParse - beginSafety, &prevChar, False, delimiters, string);	    goto parseDone;	} else {	    tempLen = endPass2Safety - modStart;	    temp = XtMalloc(tempLen);	    strncpy(temp, &styleString[modStart-beginSafety], tempLen);	    passTwoParseString(pass2Patterns, string, styleString,		    modStart - beginSafety, &prevChar, False, delimiters, string);	    strncpy(&styleString[modStart-beginSafety], temp, tempLen);	    XtFree(temp);	}    }        /* Re-parse the areas after the modification with pass 2 patterns, from       modEnd to endSafety, with an additional safety region before modEnd       to ensure that parsing at modEnd is correct. */    if (endParse > modEnd) {	if (beginSafety > modEnd) {	    prevChar = getPrevChar(buf, beginSafety);	    passTwoParseString(pass2Patterns, string, styleString,	    	    endParse - beginSafety, &prevChar, False, delimiters, string);	} else {	    startPass2Safety = max(beginSafety,	    	    backwardOneContext(buf, contextRequirements, modEnd));	    tempLen = modEnd - startPass2Safety;	    temp = XtMalloc(tempLen);	    strncpy(temp, &styleString[startPass2Safety-beginSafety], tempLen);	    prevChar = getPrevChar(buf, startPass2Safety);	    passTwoParseString(pass2Patterns,	    	    &string[startPass2Safety-beginSafety],	    	    &styleString[startPass2Safety-beginSafety],	    	    endParse-startPass2Safety, &prevChar, False, delimiters, string);	    strncpy(&styleString[startPass2Safety-beginSafety], temp, tempLen);	    XtFree(temp);	}    }    	parseDone:    /* Update the style buffer with the new style information, but only       through endParse.  Skip the safety region at the end */    styleString[endParse-beginSafety] = '\0';    modifyStyleBuf(styleBuf, &styleString[beginParse-beginSafety],    	    beginParse, endParse, firstPass2Style);    XtFree(styleString);    XtFree(string);        return endParse;}/*** Parses "string" according to compiled regular expressions in "pattern"** until endRE is or errorRE are matched, or end of string is reached.** Advances "string", "styleString" pointers to the next character past** the end of the parsed section, and updates "prevChar" to reflect** the new character before "string".** If "anchored" is true, just scan the sub-pattern starting at the beginning** of the string.  "length" is how much of the string must be parsed, but** "string" must still be null terminated, the termination indicating how** far the string should be searched, and "length" the part which is actually** required (the string may or may not be parsed beyond "length").**** Returns True if parsing was done and the parse succeeded.  Returns False if** the error pattern matched, if the end of the string was reached without** matching the end expression, or in the unlikely event of an internal error.*/static int parseString(highlightDataRec *pattern, char **string,    	char **styleString, int length, char *prevChar, int anchored,    	const char *delimiters, const char* lookBehindTo){    int i, subExecuted, subIndex;    char *stringPtr, *stylePtr, *startingStringPtr, *savedStartPtr;    signed char *subExpr;    char savedPrevChar;    highlightDataRec *subPat = NULL, *subSubPat;        if (length <= 0)    	return False;    stringPtr = *string;    stylePtr = *styleString;        while(ExecRE(pattern->subPatternRE, NULL, stringPtr, anchored ? *string+1 :	    *string+length+1, False, *prevChar, '\0', delimiters, lookBehindTo)) {	/* Beware of the case where only one real branch exists, but that 	   branch has sub-branches itself. In that case the top_branch refers 	   to the matching sub-branch and must be ignored. */	subIndex = (pattern->nSubBranches > 1) ? 	   pattern->subPatternRE->top_branch : 0;    	/* Combination of all sub-patterns and end pattern matched */    	/* printf("combined patterns RE matched at %d\n",    	    	pattern->subPatternRE->startp[0] - *string); */	startingStringPtr = stringPtr;		/* Fill in the pattern style for the text that was skipped over before	   the match, and advance the pointers to the start of the pattern */	fillStyleString(&stringPtr, &stylePtr, pattern->subPatternRE->startp[0],	    	pattern->style, prevChar);    	    	/* If the combined pattern matched this pattern's end pattern, we're    	   done.  Fill in the style string, update the pointers, color the	   end expression if there were coloring sub-patterns, and return */	savedStartPtr = stringPtr;	savedPrevChar = *prevChar;	if (pattern->endRE != NULL) {	    if (subIndex == 0) {		fillStyleString(&stringPtr, &stylePtr, 		    pattern->subPatternRE->endp[0], pattern->style, prevChar);		subExecuted = False;		for (i=0;i<pattern->nSubPatterns; i++) {		    subPat = pattern->subPatterns[i];		    if (subPat->colorOnly) {			if (!subExecuted) { 			    if (!ExecRE(pattern->endRE, NULL, savedStartPtr,				savedStartPtr+1, False, savedPrevChar, 				'\0', delimiters, lookBehindTo)) {				fprintf(stderr, "Internal error, failed to "					"recover end match in parseString\n");				return False;			    }			    subExecuted = True;			}			for (subExpr=subPat->endSubexprs; *subExpr!=-1; subExpr++)		    	    recolorSubexpr(pattern->endRE, *subExpr, 				subPat->style, *string, *styleString);     	    	    }		}    		*string = stringPtr;		*styleString = stylePtr;		return True;	    }	    --subIndex;    	}    	    	/* If the combined pattern matched this pattern's error pattern, we're    	   done.  Fill in the style string, update the pointers, and return */    	if (pattern->errorRE != NULL) {	    if (subIndex == 0) {		fillStyleString(&stringPtr, &stylePtr, 		    pattern->subPatternRE->startp[0], pattern->style, prevChar);    	

⌨️ 快捷键说明

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