From dcd9341fe41fd9873017280471a29f2a223d1da9 Mon Sep 17 00:00:00 2001 From: Eddy De Greef Date: Thu, 20 Mar 2003 13:02:38 +0000 Subject: [PATCH] Fix for SF #700823: Nedit crash after highlight Perl-Syntax on OS/390. Made the syntax highlighting style information independent of the character coding (ASCII or EBCDIC). --- source/help.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++------- source/highlight.c | 22 +++++++++--------- source/highlight.h | 6 ++++- source/textDisp.c | 12 +++++----- 4 files changed, 80 insertions(+), 25 deletions(-) diff --git a/source/help.c b/source/help.c index 289cd6c..205228d 100644 --- a/source/help.c +++ b/source/help.c @@ -1,4 +1,4 @@ -static const char CVSID[] = "$Id: help.c,v 1.87 2002/11/13 21:58:24 tringali Exp $"; +static const char CVSID[] = "$Id: help.c,v 1.88 2003/03/20 13:02:34 edg Exp $"; /******************************************************************************* * * * help.c -- Nirvana Editor help display * @@ -154,6 +154,20 @@ static int StyleUnderlines[] = static styleTableEntry HelpStyleInfo[ N_STYLES ]; +/* Translation table for style codes (A, B, C, ...) to their ASCII codes. + For systems using ASCII, this is just a one-to-one mapping, but the + table makes it possible to use the style codes also on an EBCDIC system. + */ +static unsigned char AlphabetToAsciiTable[256]; + +/* Macro that calculates the zero-based index for a given style, taking + into account that the character set may not use ASCII coding, but EBCDIC. + The "style" argument must be one of the characters A - Z. + In ASCII, this comes down to "style - STYLE_PLAIN". */ +#define STYLE_INDEX(style) \ + (AlphabetToAsciiTable[(unsigned char)style] - \ + AlphabetToAsciiTable[(unsigned char)STYLE_PLAIN]) + /*============================================================================*/ /* PROGRAM PROTOTYPES */ /*============================================================================*/ @@ -292,6 +306,38 @@ static void initHelpStyles (Widget parent) break; } } + + /*--------------------------------------------------------- + * Also initialize the alphabet-to-ASCII-code table (to + * make the style mapping also work on EBCDIC). + * DON'T use 'A' to initialize the table! 'A' != 65 in EBCDIC. + *--------------------------------------------------------*/ + AlphabetToAsciiTable[(unsigned char)'A'] = ASCII_A + 0; + AlphabetToAsciiTable[(unsigned char)'B'] = ASCII_A + 1; + AlphabetToAsciiTable[(unsigned char)'C'] = ASCII_A + 2; + AlphabetToAsciiTable[(unsigned char)'D'] = ASCII_A + 3; + AlphabetToAsciiTable[(unsigned char)'E'] = ASCII_A + 4; + AlphabetToAsciiTable[(unsigned char)'F'] = ASCII_A + 5; + AlphabetToAsciiTable[(unsigned char)'G'] = ASCII_A + 6; + AlphabetToAsciiTable[(unsigned char)'H'] = ASCII_A + 7; + AlphabetToAsciiTable[(unsigned char)'I'] = ASCII_A + 8; + AlphabetToAsciiTable[(unsigned char)'J'] = ASCII_A + 9; + AlphabetToAsciiTable[(unsigned char)'K'] = ASCII_A + 10; + AlphabetToAsciiTable[(unsigned char)'L'] = ASCII_A + 11; + AlphabetToAsciiTable[(unsigned char)'M'] = ASCII_A + 12; + AlphabetToAsciiTable[(unsigned char)'N'] = ASCII_A + 13; + AlphabetToAsciiTable[(unsigned char)'O'] = ASCII_A + 14; + AlphabetToAsciiTable[(unsigned char)'P'] = ASCII_A + 15; + AlphabetToAsciiTable[(unsigned char)'Q'] = ASCII_A + 16; + AlphabetToAsciiTable[(unsigned char)'R'] = ASCII_A + 17; + AlphabetToAsciiTable[(unsigned char)'S'] = ASCII_A + 18; + AlphabetToAsciiTable[(unsigned char)'T'] = ASCII_A + 19; + AlphabetToAsciiTable[(unsigned char)'U'] = ASCII_A + 20; + AlphabetToAsciiTable[(unsigned char)'V'] = ASCII_A + 21; + AlphabetToAsciiTable[(unsigned char)'W'] = ASCII_A + 22; + AlphabetToAsciiTable[(unsigned char)'X'] = ASCII_A + 23; + AlphabetToAsciiTable[(unsigned char)'Y'] = ASCII_A + 24; + AlphabetToAsciiTable[(unsigned char)'Z'] = ASCII_A + 25; } } @@ -303,12 +349,12 @@ static void loadFontsAndColors(Widget parent, int style) { XFontStruct *font; int r,g,b; - if (HelpStyleInfo[style - STYLE_PLAIN].font == NULL) { + if (HelpStyleInfo[STYLE_INDEX(style)].font == NULL) { font = XLoadQueryFont(XtDisplay(parent), - GetPrefHelpFontName(StyleFonts[style - STYLE_PLAIN])); + GetPrefHelpFontName(StyleFonts[STYLE_INDEX(style)])); if (font == NULL) { fprintf(stderr, "NEdit: help font, %s, not available\n", - GetPrefHelpFontName(StyleFonts[style - STYLE_PLAIN])); + GetPrefHelpFontName(StyleFonts[STYLE_INDEX(style)])); font = XLoadQueryFont(XtDisplay(parent), "fixed"); if (font == NULL) { fprintf(stderr, "NEdit: fallback help font, \"fixed\", not " @@ -316,9 +362,9 @@ static void loadFontsAndColors(Widget parent, int style) exit(EXIT_FAILURE); } } - HelpStyleInfo[style - STYLE_PLAIN].font = font; + HelpStyleInfo[STYLE_INDEX(style)].font = font; if (style == STL_NM_LINK) - HelpStyleInfo[style - STYLE_PLAIN].color = + HelpStyleInfo[STYLE_INDEX(style)].color = AllocColor(parent, GetPrefHelpLinkColor(), &r, &g, &b); } } @@ -427,8 +473,9 @@ static char * stitch ( else { *(sp++) = *cp; + /* Beware of possible EBCDIC coding! Use the mapping table. */ if (styleMap) - *(sdp++) = style; + *(sdp++) = AlphabetToAsciiTable[(unsigned char)style]; } } } @@ -984,7 +1031,9 @@ static void helpHyperlinkAP(Widget w, XEvent *event, String *args, } clickedPos = TextDXYToCharPos(textD, e->x, e->y); - if (BufGetCharacter(textD->styleBuffer, clickedPos) != STL_NM_LINK){ + /* Beware of possible EBCDIC coding! Use the mapping table. */ + if (BufGetCharacter(textD->styleBuffer, clickedPos) != + (char)AlphabetToAsciiTable[(unsigned char)STL_NM_LINK]) { if(*nArgs == 3) XtCallActionProc(w, args[2], event, NULL, 0); return; diff --git a/source/highlight.c b/source/highlight.c index 7183830..bdfcd88 100644 --- a/source/highlight.c +++ b/source/highlight.c @@ -1,4 +1,4 @@ -static const char CVSID[] = "$Id: highlight.c,v 1.38 2002/12/08 09:29:40 yooden Exp $"; +static const char CVSID[] = "$Id: highlight.c,v 1.39 2003/03/20 13:02:36 edg Exp $"; /******************************************************************************* * * * highlight.c -- Nirvana Editor syntax highlighting (text coloring and font * @@ -75,9 +75,11 @@ static const char CVSID[] = "$Id: highlight.c,v 1.38 2002/12/08 09:29:40 yooden This distance is increased by a factor of two for each subsequent step. */ #define REPARSE_CHUNK_SIZE 80 -/* Meanings of style buffer characters (styles) */ -#define UNFINISHED_STYLE 'A' -#define PLAIN_STYLE 'B' +/* Meanings of style buffer characters (styles). Don't use plain 'A' or 'B'; + it causes problems with EBCDIC coding (possibly negative offsets when + subtracting 'A'). */ +#define UNFINISHED_STYLE ASCII_A +#define PLAIN_STYLE (ASCII_A+1) #define IS_PLAIN(style) (style == PLAIN_STYLE || style == UNFINISHED_STYLE) #define IS_STYLED(style) (style != PLAIN_STYLE && style != UNFINISHED_STYLE) @@ -713,9 +715,9 @@ any existing style", "Dismiss", patternSrc[i].style, patternSrc[i].name); pass2Pats[0].style = PLAIN_STYLE; } for (i=1; ihighlightData; - hCode -= 'A'; /* get the correct index value */ + hCode -= UNFINISHED_STYLE; /* get the correct index value */ if (!highlightData || hCode < 0 || hCode >= highlightData->nStyles) return NULL; return &highlightData->styleTable[hCode]; @@ -1266,9 +1268,9 @@ static void handleUnparsedRegion(WindowInfo *window, textBuffer *styleBuf, endParse = min(endParse, p); endSafety = p; break; - } else if ((unsigned char)c != UNFINISHED_STYLE && p < endParse) { + } else if (c != UNFINISHED_STYLE && p < endParse) { endParse = p; - if (c < firstPass2Style) + if ((unsigned char)c < firstPass2Style) endSafety = p; else endSafety = forwardOneContext(buf, context, endParse); @@ -2019,7 +2021,7 @@ static regexp *compileREAndWarn(Widget parent, const char *re) static int parentStyleOf(const char *parentStyles, int style) { - return parentStyles[(unsigned char)style-'A']; + return parentStyles[(unsigned char)style-UNFINISHED_STYLE]; } static int isParentStyle(const char *parentStyles, int style1, int style2) diff --git a/source/highlight.h b/source/highlight.h index 3ef16c3..a665ea0 100644 --- a/source/highlight.h +++ b/source/highlight.h @@ -1,4 +1,4 @@ -/* $Id: highlight.h,v 1.9 2002/11/08 20:22:45 edg Exp $ */ +/* $Id: highlight.h,v 1.10 2003/03/20 13:02:38 edg Exp $ */ #ifndef NEDIT_HIGHLIGHT_H_INCLUDED #define NEDIT_HIGHLIGHT_H_INCLUDED @@ -12,6 +12,10 @@ #define DEFER_PARSING 2 #define COLOR_ONLY 4 +/* Don't use plain 'A' or 'B' for style indices, it causes problems + with EBCDIC coding (possibly negative offsets when subtracting 'A'). */ +#define ASCII_A ((char)65) + /* Pattern specification structure */ typedef struct { char *name; diff --git a/source/textDisp.c b/source/textDisp.c index 68dd580..49b1658 100644 --- a/source/textDisp.c +++ b/source/textDisp.c @@ -1,4 +1,4 @@ -static const char CVSID[] = "$Id: textDisp.c,v 1.42 2003/03/05 23:51:00 n8gray Exp $"; +static const char CVSID[] = "$Id: textDisp.c,v 1.43 2003/03/20 13:02:38 edg Exp $"; /******************************************************************************* * * * textDisp.c - Display text from a text buffer * @@ -352,8 +352,8 @@ textBuffer *TextDGetBuffer(textDisp *textD) ** Highlighting information consists of a style buffer which parallels the ** normal text buffer, but codes font and color information for the display; ** a style table which translates style buffer codes (indexed by buffer -** character - 'A') into fonts and colors; and a callback mechanism for -** as-needed highlighting, triggered by a style buffer entry of +** character - 65 (ASCII code for 'A')) into fonts and colors; and a callback +** mechanism for as-needed highlighting, triggered by a style buffer entry of ** "unfinishedStyle". Style buffer can trigger additional redisplay during ** a normal buffer modification if the buffer contains a primary selection ** (see extendRangeForStyleMods for more information on this protocol). @@ -1940,7 +1940,7 @@ static void drawString(textDisp *textD, int style, int x, int y, int toX, pre-allocated and pre-configured. For syntax highlighting, GCs are configured here, on the fly. */ if (style & STYLE_LOOKUP_MASK) { - styleRec = &textD->styleTable[(style & STYLE_LOOKUP_MASK) - 'A']; + styleRec = &textD->styleTable[(style & STYLE_LOOKUP_MASK) - ASCII_A]; underlineStyle = styleRec->underline; fs = styleRec->font; gcValues.font = fs->fid; @@ -2166,7 +2166,7 @@ static int stringWidth(textDisp *textD, char *string, int length, int style) XFontStruct *fs; if (style & STYLE_LOOKUP_MASK) - fs = textD->styleTable[(style & STYLE_LOOKUP_MASK) - 'A'].font; + fs = textD->styleTable[(style & STYLE_LOOKUP_MASK) - ASCII_A].font; else fs = textD->fontStruct; return XTextWidth(fs, string, length); @@ -2899,7 +2899,7 @@ static int measureVisLine(textDisp *textD, int visLineNum) len = BufGetExpandedChar(textD->buffer, lineStartPos+i, charCount, expandedChar); style = (unsigned char)BufGetCharacter(textD->styleBuffer, - lineStartPos+i) - 'A'; + lineStartPos+i) - ASCII_A; width += XTextWidth(textD->styleTable[style].font, expandedChar, len); charCount += len; -- 2.11.4.GIT