This repository has been archived on 2023-07-11. You can view files and clone it, but cannot push or open issues or pull requests.
fte/h_rexx.cpp

392 lines
12 KiB
C++

/* h_rexx.cpp
*
* Copyright (c) 1994-1996, Marko Macek
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
*
*/
#include "fte.h"
#ifdef CONFIG_HILIT_REXX
#define hsREXX_Normal 0
#define hsREXX_Comment 1
#define hsREXX_String1 3
#define hsREXX_String2 4
#define hsREXX_Keyword 5
int Hilit_REXX(EBuffer *BF, int /*LN*/, PCell B, int Pos, int Width, ELine *Line, hlState &State, hsState *StateMap, int *ECol) {
ChColor *Colors = BF->Mode->fColorize->Colors;
int j = 0;
int firstnw = 0;
HILIT_VARS(Colors[CLR_Normal], Line);
int wascall = 0;
C = 0;
NC = 0;
for(i = 0; i < Line->Count;) {
if (*p != ' ' && *p != 9) firstnw++;
IF_TAB() else {
switch(State) {
case hsREXX_Comment:
Color = Colors[CLR_Comment];
if ((len >= 2) && (*p == '*') && (*(p+1) == '/')) {
ColorNext();
set_normal:
ColorNext();
State = hsREXX_Normal;
continue;
}
goto hilit;
case hsREXX_String1:
Color = Colors[CLR_String];
if (*p == '\'') {
goto set_normal;
}
goto hilit;
case hsREXX_String2:
Color = Colors[CLR_String];
if (*p == '"') {
goto set_normal;
}
goto hilit;
default:
case hsREXX_Normal:
if (isalpha(*p) || (*p == '_')) {
j = 0;
while (((i + j) < Line->Count) &&
(isalnum(Line->Chars[i+j]) ||
(Line->Chars[i + j] == '_'))
) j++;
if (wascall) {
State = hsREXX_Normal;
Color = Colors[CLR_Function];
wascall = 0;
} else {
if (BF->GetHilitWord(j, Line->Chars + i, Color, 1))
State = hsREXX_Keyword;
else {
int x;
x = i + j;
if ((x < Line->Count) && (Line->Chars[x] == '(')) {
Color = Colors[CLR_Function];
} else {
Color = Colors[CLR_Normal];
}
State = hsREXX_Normal;
}
}
if (StateMap)
memset(StateMap + i, State, j);
if (B)
MoveMem(B, C - Pos, Width, Line->Chars + i, Color, j);
if (State == hsREXX_Keyword)
if (strnicmp(Line->Chars + i, "CALL", 4) == 0)
wascall = 1;
i += j;
len -= j;
p += j;
C += j;
State = hsREXX_Normal;
continue;
} else if ((len >= 2) && (*p == '/') && (*(p+1) == '*')) {
State = hsREXX_Comment;
Color = Colors[CLR_Comment];
//hilit2:
ColorNext();
hilit:
ColorNext();
continue;
} else if (isdigit(*p)) {
Color = Colors[CLR_Number];
ColorNext();
while(len && isdigit(*p)) ColorNext();
continue;
} else if (*p == '\'') {
State = hsREXX_String1;
Color = Colors[CLR_String];
goto hilit;
} else if (*p == '"') {
State = hsREXX_String2;
Color = Colors[CLR_String];
goto hilit;
} else if (ispunct(*p) && *p != '_') {
Color = Colors[CLR_Punctuation];
goto hilit;
}
Color = Colors[CLR_Normal];
goto hilit;
}
}
}
switch (State) {
case hsREXX_String1:
case hsREXX_String2:
State = hsREXX_Normal;
break;
}
*ECol = C;
return 0;
}
#ifdef CONFIG_INDENT_REXX
static int Match(int Len, int Pos, hsState *StateMap, const char *Text, const char *String, hsState State) {
int L = strlen(String);
if (Pos + L <= Len)
if (StateMap == NULL || IsState(StateMap + Pos, State, L))
if (strnicmp(String, Text + Pos, L) == 0)
return 1;
return 0;
}
static int SearchMatch(int Count, EBuffer *B, int Row, int Ctx) {
char *P;
int L;
int Pos;
int StateLen;
hsState *StateMap;
int ICount = (Ctx == 2) ? Count : 0;
Count = (Ctx == 2) ? 0 : Count;
while (Row >= 0) {
P = B->RLine(Row)->Chars;
L = B->RLine(Row)->Count;
StateMap = NULL;
if (B->GetMap(Row, &StateLen, &StateMap) == 0) return -1;
Pos = L - 1;
if (L > 0) while (Pos >= 0) {
if (isalpha(P[Pos])) {
if (Match(L, Pos, StateMap, P, "do", hsREXX_Keyword) ||
Match(L, Pos, StateMap, P, "select", hsREXX_Keyword ))
{
Count++;
if (Count == 0 && Ctx != 2) {
if (StateMap)
free(StateMap);
return B->LineIndented(Row);
}
} else if (Match(L, Pos, StateMap, P, "end", hsREXX_Keyword)) {
Count--;
}
if (Ctx == 2 && Count == 0) {
if (Match(L, Pos, StateMap, P, "if", hsREXX_Keyword)) {
ICount++;
if (ICount == 0) {
if (StateMap)
free(StateMap);
return B->LineIndented(Row);
}
} else if (Match(L, Pos, StateMap, P, "else", hsREXX_Keyword)) {
ICount--;
}
}
}
Pos--;
}
if (StateMap) free(StateMap);
Row--;
}
return -1;
}
static int CheckLabel(EBuffer *B, int Line) {
PELine L = B->RLine(Line);
int P = B->CharOffset(L, B->LineIndented(Line));
int Cnt = 0;
if (Line > 0 && B->RLine(Line - 1)->StateE != hsREXX_Normal)
return 0;
while ((P < L->Count) &&
(L->Chars[P] == ' ' || L->Chars[P] == 9)) P++;
while (P < L->Count) {
if (Cnt > 0)
if (L->Chars[P] == ':') return 1;
if (!(isalnum(L->Chars[P]) || (L->Chars[P] == '_'))) return 0;
Cnt++;
P++;
}
return 0;
}
static int SearchBackContext(EBuffer *B, int Row, char &ChFind) {
char *P;
int L;
int Pos;
int Count = -1;
int StateLen;
hsState *StateMap;
int isblank = 0;
ChFind = '0';
while (Row >= 0) {
P = B->RLine(Row)->Chars;
L = B->RLine(Row)->Count;
StateMap = NULL;
if (B->GetMap(Row, &StateLen, &StateMap) == 0) return 0;
Pos = L - 1;
if (L > 0) while (Pos >= 0) {
if (CheckLabel(B, Row) == 1) {
Count++;
ChFind = 'p';
if (Count == 0) {
if (StateMap)
free(StateMap);
return B->LineIndented(Row);
}
}
if (isalpha(P[Pos]) && (Pos == 0 || !isalpha(P[Pos - 1]))) {
if (Match(L, Pos, StateMap, P, "do", hsREXX_Keyword)) {
Count++;
ChFind = 'd';
//} else if (Match(L, Pos, StateMap, P, "procedure", hsREXX_Keyword)) {
//Count++;
//ChFind = 'p';
} else if (Match(L, Pos, StateMap, P, "select", hsREXX_Keyword)) {
Count++;
ChFind = 's';
} else if (Match(L, Pos, StateMap, P, "otherwise", hsREXX_Keyword) && Count == 0) {
//Count++;
ChFind = 'o';
if (StateMap)
free(StateMap);
return B->LineIndented(Row);
} else if (Match(L, Pos, StateMap, P, "end", hsREXX_Keyword)) {
Count--;
ChFind = 'e';
} else if (isblank < 5 && Match(L, Pos, StateMap, P, "then", hsREXX_Keyword)) {
ChFind = 't';
if (StateMap)
free(StateMap);
return B->LineIndented(Row);
} else if (isblank < 5 && Match(L, Pos, StateMap, P, "else", hsREXX_Keyword)) {
ChFind = 'e';
if (StateMap)
free(StateMap);
return B->LineIndented(Row);
} else {
isblank++;
Pos--;
continue;
}
if (Count == 0) {
if (StateMap)
free(StateMap);
return B->LineIndented(Row);
}
}
if (P[Pos] != ' ' && P[Pos] != 9) isblank++;
Pos--;
}
if (StateMap) free(StateMap);
Row--;
}
return -1;
}
int REXX_Base_Indent = 4;
int REXX_Do_Offset = 0;
#define REXX_BASE_INDENT REXX_Base_Indent
#define REXX_DO_OFFSET REXX_Do_Offset
static int IndentComment(EBuffer *B, int Row, int /*StateLen*/, hsState * /*StateMap*/) {
int I = 0;
if (Row > 0) {
I = B->LineIndented(Row - 1);
if (B->RLine(Row - 1)->StateE == hsREXX_Comment)
if (LookAt(B, Row - 1, I, "/*", hsREXX_Comment, 0)) I+= 1;
}
return I;
}
static int IndentNormal(EBuffer *B, int Line, int /*StateLen*/, hsState * /*StateMap*/) {
int I = 0;
if (CheckLabel(B, Line)) {
return 0;
} else if (LookAtNoCase(B, Line, 0, "end", hsREXX_Keyword)) {
return SearchMatch(-1, B, Line - 1, 1);
} else if (LookAtNoCase(B, Line, 0, "else", hsREXX_Keyword)) {
return SearchMatch(-1, B, Line - 1, 2);
} else {
char ChFind;
I = SearchBackContext(B, Line - 1, ChFind);
if (I == -1)
return 0;
switch (ChFind) {
case 'p':
if (LookAtNoCase(B, Line, 0, "return", hsREXX_Keyword))
return I;
else
return I + REXX_BASE_INDENT;
case 's':
case 'd':
return I + REXX_BASE_INDENT;
case 't':
case 'e':
case 'o':
if (LookAtNoCase(B, Line, 0, "do", hsREXX_Keyword))
return I + REXX_DO_OFFSET;
else
return I + REXX_BASE_INDENT;
default:
return I;
}
}
}
int Indent_REXX(EBuffer *B, int Line, int PosCursor) {
int I;
hsState *StateMap = NULL;
int StateLen = 0;
int OI;
OI = I = B->LineIndented(Line);
if (I != 0) B->IndentLine(Line, 0);
if (B->GetMap(Line, &StateLen, &StateMap) == 0) return 0;
if (StateLen > 0) { // line is not empty
if (StateMap[0] == hsREXX_Comment) {
I = IndentComment(B, Line, StateLen, StateMap);
} else {
I = IndentNormal(B, Line, StateLen, StateMap);
}
} else {
I = IndentNormal(B, Line, 0, NULL);
}
if (StateMap)
free(StateMap);
if (I >= 0)
B->IndentLine(Line, I);
else
I = 0;
if (PosCursor == 1) {
int X = B->CP.Col;
X = X - OI + I;
if (X < I) X = I;
if (X < 0) X = 0;
if (X > B->LineLen(Line)) {
X = B->LineLen(Line);
if (X < I) X = I;
}
if (B->SetPosR(X, Line) == 0) return 0;
} else if (PosCursor == 2) {
if (B->SetPosR(I, Line) == 0) return 0;
}
return 1;
}
#endif
#endif