📄 highlight.c
字号:
p1Ptr->style = p2Ptr->style = "Plain"; p1Ptr->subPatternOf = p2Ptr->subPatternOf = NULL; p1Ptr->flags = p2Ptr->flags = 0; p1Ptr++; p2Ptr++; for (i=0; i<nPatterns; i++) { if (patternSrc[i].flags & DEFER_PARSING) *p2Ptr++ = patternSrc[i]; else *p1Ptr++ = patternSrc[i]; } /* If a particular pass is empty except for the default pattern, don't bother compiling it or setting up styles */ if (nPass1Patterns == 1) nPass1Patterns = 0; if (nPass2Patterns == 1) nPass2Patterns = 0; /* Compile patterns */ if (nPass1Patterns == 0) pass1Pats = NULL; else { pass1Pats = compilePatterns(window->shell, pass1PatternSrc, nPass1Patterns); if (pass1Pats == NULL) return NULL; } if (nPass2Patterns == 0) pass2Pats = NULL; else { pass2Pats = compilePatterns(window->shell, pass2PatternSrc, nPass2Patterns); if (pass2Pats == NULL) return NULL; } /* Set pattern styles. If there are pass 2 patterns, pass 1 pattern 0 should have a default style of UNFINISHED_STYLE. With no pass 2 patterns, unstyled areas of pass 1 patterns should be PLAIN_STYLE to avoid triggering re-parsing every time they are encountered */ noPass1 = nPass1Patterns == 0; noPass2 = nPass2Patterns == 0; if (noPass2) pass1Pats[0].style = PLAIN_STYLE; else if (noPass1) pass2Pats[0].style = PLAIN_STYLE; else { pass1Pats[0].style = UNFINISHED_STYLE; pass2Pats[0].style = PLAIN_STYLE; } for (i=1; i<nPass1Patterns; i++) pass1Pats[i].style = PLAIN_STYLE + i; for (i=1; i<nPass2Patterns; i++) pass2Pats[i].style = PLAIN_STYLE + (noPass1 ? 0 : nPass1Patterns-1) + i; /* Create table for finding parent styles */ parentStylesPtr = parentStyles = XtMalloc(nPass1Patterns+nPass2Patterns+2); *parentStylesPtr++ = '\0'; *parentStylesPtr++ = '\0'; for (i=1; i<nPass1Patterns; i++) { parentName = pass1PatternSrc[i].subPatternOf; *parentStylesPtr++ = parentName == NULL ? PLAIN_STYLE : pass1Pats[indexOfNamedPattern(pass1PatternSrc, nPass1Patterns, parentName)].style; } for (i=1; i<nPass2Patterns; i++) { parentName = pass2PatternSrc[i].subPatternOf; *parentStylesPtr++ = parentName == NULL ? PLAIN_STYLE : pass2Pats[indexOfNamedPattern(pass2PatternSrc, nPass2Patterns, parentName)].style; } /* Set up table for mapping colors and fonts to syntax */ styleTablePtr = styleTable = (styleTableEntry *)XtMalloc( sizeof(styleTableEntry) * (nPass1Patterns + nPass2Patterns + 1));#define setStyleTablePtr(styleTablePtr, patternSrc) \ do { \ styleTableEntry *p = styleTablePtr; \ highlightPattern *pat = patternSrc; \ int r, g, b; \ \ p->highlightName = pat->name; \ p->styleName = pat->style; \ p->colorName = ColorOfNamedStyle(pat->style); \ p->bgColorName = BgColorOfNamedStyle(pat->style); \ p->isBold = FontOfNamedStyleIsBold(pat->style); \ p->isItalic = FontOfNamedStyleIsItalic(pat->style); \ /* And now for the more physical stuff */ \ p->color = AllocColor(window->textArea, p->colorName, &r, &g, &b); \ p->red = r; \ p->green = g; \ p->blue = b; \ if (p->bgColorName) { \ p->bgColor = AllocColor(window->textArea, p->bgColorName, &r, &g, &b); \ p->bgRed = r; \ p->bgGreen = g; \ p->bgBlue = b; \ } \ else { \ p->bgColor = p->color; \ p->bgRed = r; \ p->bgGreen = g; \ p->bgBlue = b; \ } \ p->font = FontOfNamedStyle(window, pat->style); \ } while (0) /* PLAIN_STYLE (pass 1) */ styleTablePtr->underline = FALSE; setStyleTablePtr(styleTablePtr++, noPass1 ? &pass2PatternSrc[0] : &pass1PatternSrc[0]); /* PLAIN_STYLE (pass 2) */ styleTablePtr->underline = FALSE; setStyleTablePtr(styleTablePtr++, noPass2 ? &pass1PatternSrc[0] : &pass2PatternSrc[0]); /* explicit styles (pass 1) */ for (i=1; i<nPass1Patterns; i++) { styleTablePtr->underline = FALSE; setStyleTablePtr(styleTablePtr++, &pass1PatternSrc[i]); } /* explicit styles (pass 2) */ for (i=1; i<nPass2Patterns; i++) { styleTablePtr->underline = FALSE; setStyleTablePtr(styleTablePtr++, &pass2PatternSrc[i]); } /* Free the temporary sorted pattern source list */ XtFree((char *)pass1PatternSrc); XtFree((char *)pass2PatternSrc); /* Create the style buffer */ styleBuf = BufCreate(); /* Collect all of the highlighting information in a single structure */ highlightData =(windowHighlightData *)XtMalloc(sizeof(windowHighlightData)); highlightData->pass1Patterns = pass1Pats; highlightData->pass2Patterns = pass2Pats; highlightData->parentStyles = parentStyles; highlightData->styleTable = styleTable; highlightData->nStyles = styleTablePtr - styleTable; highlightData->styleBuffer = styleBuf; highlightData->contextRequirements.nLines = contextLines; highlightData->contextRequirements.nChars = contextChars; highlightData->patternSetForWindow = patSet; return highlightData;}/*** Transform pattern sources into the compiled highlight information** actually used by the code. Output is a tree of highlightDataRec structures** containing compiled regular expressions and style information.*/static highlightDataRec *compilePatterns(Widget dialogParent, highlightPattern *patternSrc, int nPatterns){ int i, nSubExprs, patternNum, length, subPatIndex, subExprNum, charsRead; int parentIndex; char *ptr, *bigPattern, *compileMsg; highlightDataRec *compiledPats; /* Allocate memory for the compiled patterns. The list is terminated by a record with style == 0. */ compiledPats = (highlightDataRec *)XtMalloc(sizeof(highlightDataRec) * (nPatterns + 1)); compiledPats[nPatterns].style = 0; /* Build the tree of parse expressions */ for (i=0; i<nPatterns; i++) { compiledPats[i].nSubPatterns = 0; compiledPats[i].nSubBranches = 0; } for (i=1; i<nPatterns; i++) if (patternSrc[i].subPatternOf == NULL) compiledPats[0].nSubPatterns++; else compiledPats[indexOfNamedPattern(patternSrc, nPatterns, patternSrc[i].subPatternOf)].nSubPatterns++; for (i=0; i<nPatterns; i++) compiledPats[i].subPatterns = compiledPats[i].nSubPatterns == 0 ? NULL : (highlightDataRec **)XtMalloc( sizeof(highlightDataRec *) * compiledPats[i].nSubPatterns); for (i=0; i<nPatterns; i++) compiledPats[i].nSubPatterns = 0; for (i=1; i<nPatterns; i++) { if (patternSrc[i].subPatternOf == NULL) { compiledPats[0].subPatterns[compiledPats[0].nSubPatterns++] = &compiledPats[i]; } else { parentIndex = indexOfNamedPattern(patternSrc, nPatterns, patternSrc[i].subPatternOf); compiledPats[parentIndex].subPatterns[compiledPats[parentIndex]. nSubPatterns++] = &compiledPats[i]; } } /* Process color-only sub patterns (no regular expressions to match, just colors and fonts for sub-expressions of the parent pattern */ for (i=0; i<nPatterns; i++) { compiledPats[i].colorOnly = patternSrc[i].flags & COLOR_ONLY; compiledPats[i].userStyleIndex = IndexOfNamedStyle(patternSrc[i].style); if (compiledPats[i].colorOnly && compiledPats[i].nSubPatterns != 0) { DialogF(DF_WARN, dialogParent, 1, "Color-only Pattern", "Color-only pattern \"%s\" may not have subpatterns", "Dismiss", patternSrc[i].name); return NULL; } nSubExprs = 0; if (patternSrc[i].startRE != NULL) { ptr = patternSrc[i].startRE; while(TRUE) { if (*ptr == '&') { compiledPats[i].startSubexprs[nSubExprs++] = 0; ptr++; } else if (sscanf(ptr, "\\%d%n", &subExprNum, &charsRead)==1) { compiledPats[i].startSubexprs[nSubExprs++] = subExprNum; ptr += charsRead; } else break; } } compiledPats[i].startSubexprs[nSubExprs] = -1; nSubExprs = 0; if (patternSrc[i].endRE != NULL) { ptr = patternSrc[i].endRE; while(TRUE) { if (*ptr == '&') { compiledPats[i].endSubexprs[nSubExprs++] = 0; ptr++; } else if (sscanf(ptr, "\\%d%n", &subExprNum, &charsRead)==1) { compiledPats[i].endSubexprs[nSubExprs++] = subExprNum; ptr += charsRead; } else break; } } compiledPats[i].endSubexprs[nSubExprs] = -1; } /* Compile regular expressions for all highlight patterns */ for (i=0; i<nPatterns; i++) { if (patternSrc[i].startRE == NULL || compiledPats[i].colorOnly) compiledPats[i].startRE = NULL; else { if ((compiledPats[i].startRE = compileREAndWarn(dialogParent, patternSrc[i].startRE)) == NULL) return NULL; } if (patternSrc[i].endRE == NULL || compiledPats[i].colorOnly) compiledPats[i].endRE = NULL; else { if ((compiledPats[i].endRE = compileREAndWarn(dialogParent, patternSrc[i].endRE)) == NULL) return NULL; } if (patternSrc[i].errorRE == NULL) compiledPats[i].errorRE = NULL; else { if ((compiledPats[i].errorRE = compileREAndWarn(dialogParent, patternSrc[i].errorRE)) == NULL) return NULL; } } /* Construct and compile the great hairy pattern to match the OR of the end pattern, the error pattern, and all of the start patterns of the sub-patterns */ for (patternNum=0; patternNum<nPatterns; patternNum++) { if (patternSrc[patternNum].endRE == NULL && patternSrc[patternNum].errorRE == NULL && compiledPats[patternNum].nSubPatterns == 0) { compiledPats[patternNum].subPatternRE = NULL; continue; } length = (compiledPats[patternNum].colorOnly || patternSrc[patternNum].endRE == NULL) ? 0 : strlen(patternSrc[patternNum].endRE) + 5; length += patternSrc[patternNum].errorRE == NULL ? 0 : strlen(patternSrc[patternNum].errorRE) + 5; for (i=0; i<compiledPats[patternNum].nSubPatterns; i++) { subPatIndex = compiledPats[patternNum].subPatterns[i]-compiledPats; length += compiledPats[subPatIndex].colorOnly ? 0 : strlen(patternSrc[subPatIndex].startRE) + 5; } if (length == 0) { compiledPats[patternNum].subPatternRE = NULL; continue; } bigPattern = XtMalloc(sizeof(char) * (length+1)); ptr=bigPattern; if (patternSrc[patternNum].endRE != NULL) { *ptr++ = '('; *ptr++ = '?'; *ptr++ = ':'; strcpy(ptr, patternSrc[patternNum].endRE); ptr += strlen(patternSrc[patternNum].endRE); *ptr++ = ')'; *ptr++ = '|'; compiledPats[patternNum].nSubBranches++; } if (patternSrc[patternNum].errorRE != NULL) { *ptr++ = '('; *ptr++ = '?'; *ptr++ = ':'; strcpy(ptr, patternSrc[patternNum].errorRE); ptr += strlen(patternSrc[patternNum].errorRE); *ptr++ = ')'; *ptr++ = '|'; compiledPats[patternNum].nSubBranches++; } for (i=0; i<compiledPats[patternNum].nSubPatterns; i++) { subPatIndex = compiledPats[patternNum].subPatterns[i]-compiledPats; if (compiledPats[subPatIndex].colorOnly) continue; *ptr++ = '('; *ptr++ = '?'; *ptr++ = ':'; strcpy(ptr, patternSrc[subPatIndex].startRE); ptr += strlen(patternSrc[subPatIndex].startRE); *ptr++ = ')'; *ptr++ = '|'; compiledPats[patternNum].nSubBranches++; } *(ptr-1) = '\0'; compiledPats[patternNum].subPatternRE = CompileRE(bigPattern, &compileMsg, REDFLT_STANDARD); if (compiledPats[patternNum].subPatternRE == NULL) { fprintf(stderr, "Error compiling syntax highlight patterns:\n%s", compileMsg); return NULL; } XtFree(bigPattern); } /* Copy remaining parameters from pattern template to compiled tree */ for (i=0; i<nPatterns; i++) compiledPats[i].flags = patternSrc[i].flags; return compiledPats;}/*** Free a pattern list and all of its allocated components*/static void freePatterns(highlightDataRec *patterns){ int i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -