teacl/src/cmatch.c

280 lines
7.3 KiB
C

/*****************************************************************************
CMatch()
This recursive function trys to match one match construct with the
character pointed to by EBPtr2. It sets SamChr, which indicates whether the
match was successful or not. SStPtr is left pointing to the last character
of the match construct.
If the match construct is ^Em or ^S, then EBPtr2 will be updated to
point to the last matched character. In this case, RhtSid is needed to
indicate the limit past which EBPtr2 should not be incremented.
Match constructs are:
^X match any character
^S match a separator character (not letter or digit)
^N match anything but following match construct
^EA match any alphabetic
^EB match a separator character (not letter or digit)
^EC match symbol constituent
^ED match any digit
^EGq match any character in q-register q
^EL match any line terminator (LF, VT, FF)
^EM match non-null string of following match construct
^ER match any alphanumeric
^ES match non-null string of spaces and/or tabs
^EV match lowercase alphabetic
^EW match uppercase alphabetic
^EX match any character
^E<nnn> match character with ASCII code nnn (octal)
^E[x1,x2,...xn] match any of the match constructs x1, x2, etc.
else match the character itself
*****************************************************************************/
#include "zport.h" /* define portability identifiers */
#include "tecoc.h" /* define general identifiers */
#include "defext.h" /* define external global variables */
#include "dchars.h" /* define identifiers for characters */
#include "chmacs.h" /* define character processing macros */
#include "deferr.h" /* define identifiers for error messages */
DEFAULT CMatch(SamChr) /* match a character */
BOOLEAN *SamChr; /* returned match indicator */
{
BOOLEAN ChrMat; /* character match indicator */
char OtCase; /* "other" case character */
charptr QRPtr; /* pointer into q-register text */
charptr SavEP2; /* temporary holder of EBPtr2 */
charptr SavSSP; /* temporary holder of SStPtr */
DEFAULT Status; /* FindQR() status for ^EGq */
charptr TCBfPt; /* temporary holder of CBfPtr */
charptr TCStEn; /* temporary holder of CStEnd */
unsigned int TmpChr; /* accumulator for ^E<nnn> */
#if DEBUGGING
static char *DbgFNm = "CMatch";
sprintf(DbgSBf,"*SStPtr = '%c', *EBPtr2 = '%c'", *SStPtr, *EBPtr2);
DbgFEn(3,DbgFNm,DbgSBf);
#endif
switch (*SStPtr) {
case CTRL_X:
*SamChr = TRUE;
break;
case CTRL_S:
*SamChr = !Is_Alnum(*EBPtr2);
break;
case CTRL_N:
if (++SStPtr == SBfPtr) {
ErrMsg(ERR_ISS); /* ill. search str. */
DBGFEX(3,DbgFNm,"FAILURE");
return FAILURE;
}
if (CMatch(&ChrMat) == FAILURE) {
DBGFEX(3,DbgFNm,"FAILURE");
return FAILURE;
}
*SamChr = !ChrMat;
#if DEBUGGING
sprintf(DbgSBf,"SUCCESS, *SamChr = %s",
(*SamChr == TRUE) ? "TRUE" : "FALSE");
DbgFEx(3,DbgFNm,DbgSBf);
#endif
return SUCCESS;
case CTRL_E:
if (++SStPtr == SBfPtr) {
ErrMsg(ERR_ICE); /* ICE = illegal ^E */
DBGFEX(3,DbgFNm,"FAILURE");
return FAILURE;
}
switch (To_Upper(*SStPtr)) {
case 'A':
*SamChr = Is_Alpha(*EBPtr2);
break;
case 'B':
*SamChr = !Is_Alnum(*EBPtr2);
break;
case 'C':
*SamChr = Is_SyCon(*EBPtr2);
break;
case 'D':
*SamChr = Is_Digit(*EBPtr2);
break;
case 'G':
if (++SStPtr == SBfPtr) {
ErrMsg(ERR_ICE); /* ill. ^E command */
DBGFEX(3,DbgFNm,"FAILURE");
return FAILURE;
}
TCBfPt = CBfPtr; /* save CBfPtr */
TCStEn = CStEnd; /* save CStEnd */
CBfPtr = SStPtr;
CStEnd = SBfPtr;
Status = FindQR();
SStPtr = CBfPtr;
SBfPtr = CStEnd;
CBfPtr = TCBfPt; /* restore CBfPtr */
CStEnd = TCStEn; /* restore CStEnd */
if (Status == FAILURE) {
DBGFEX(3,DbgFNm,"FAILURE");
return FAILURE;
}
QRPtr = QR->Start;
while (QRPtr < QR->End_P1) {
if (*QRPtr++ == *EBPtr2) {
*SamChr = TRUE;
#if DEBUGGING
sprintf(DbgSBf,"SUCCESS, *SamChr = %s", (*SamChr)?"TRUE":"FALSE");
DbgFEx(3,DbgFNm,DbgSBf);
#endif
return SUCCESS;
}
}
*SamChr = FALSE;
break;
case 'L':
*SamChr = IsEOL(*EBPtr2);
break;
case 'M':
if (++SStPtr == SBfPtr) {
ErrMsg(ERR_ICE);
DBGFEX(3,DbgFNm,"FAILURE");
return FAILURE;
}
SavSSP = SStPtr;
if (CMatch(&ChrMat) == FAILURE) {
DBGFEX(3,DbgFNm,"FAILURE");
return FAILURE;
}
*SamChr = ChrMat;
if (ChrMat) {
while (EBPtr2 <= RhtSid) {
SavEP2 = EBPtr2;
++EBPtr2;
SStPtr = SavSSP;
if (CMatch(&ChrMat) == FAILURE) {
DBGFEX(3,DbgFNm,"FAILURE");
return FAILURE;
}
if (!ChrMat) {
EBPtr2 = SavEP2;
break;
}
}
}
#if DEBUGGING
sprintf(DbgSBf,"SUCCESS, *SamChr = %s",(*SamChr)?"TRUE":"FALSE");
DbgFEx(3,DbgFNm,DbgSBf);
#endif
return SUCCESS;
case 'R':
*SamChr = Is_Alnum(*EBPtr2);
break;
case 'S':
if ((*EBPtr2 != SPACE) && (*EBPtr2 != TABCHR)) {
*SamChr = FALSE;
} else {
*SamChr = TRUE;
while (EBPtr2 <= RhtSid) {
++EBPtr2;
if ((*EBPtr2 != SPACE) && (*EBPtr2 != TABCHR)) {
EBPtr2--;
break;
}
}
}
break;
case 'V':
*SamChr = Is_Lower(*EBPtr2);
break;
case 'W':
*SamChr = Is_Upper(*EBPtr2);
break;
case 'X':
*SamChr = TRUE;
break;
case '<':
if (++SStPtr == SBfPtr) {
ErrMsg(ERR_ICE);
DBGFEX(3, DbgFNm,"FAILURE");
return FAILURE;
}
TmpChr = 0;
while (Is_Digit(*SStPtr)) {
TmpChr *= 8;
TmpChr += *SStPtr - '0';
if (TmpChr > 255) {
ErrMsg(ERR_ICE);
DBGFEX(3,DbgFNm,"FAILURE");
return FAILURE;
}
if (++SStPtr == SBfPtr) {
ErrMsg(ERR_ICE);
DBGFEX(3,DbgFNm,"FAILURE");
return FAILURE;
}
}
if (*SStPtr != '>') {
ErrMsg(ERR_ICE);
DBGFEX(3,DbgFNm,"FAILURE");
return FAILURE;
}
*SamChr = (*EBPtr2 == (unsigned char)TmpChr);
break;
case '[':
if (++SStPtr == SBfPtr) {
ErrMsg(ERR_ICE);
DBGFEX(3,DbgFNm,"FAILURE");
return FAILURE;
}
while (*SStPtr != ']') {
if (*SStPtr == ',') {
if (++SStPtr == SBfPtr) {
ErrMsg(ERR_ICE);
DBGFEX(3,DbgFNm,"FAILURE");
return FAILURE;
}
} else {
if (CMatch(&ChrMat) == FAILURE) {
DBGFEX(3,DbgFNm,"FAILURE");
return FAILURE;
}
if (ChrMat) {
while (*SStPtr != ']') {
if (++SStPtr == SBfPtr) {
ErrMsg(ERR_ICE);
DBGFEX(3,DbgFNm,"FAILURE");
return FAILURE;
}
}
*SamChr = TRUE;
#if DEBUGGING
sprintf(DbgSBf,"SUCCESS, *SamChr = %s",
(*SamChr) ? "TRUE" : "FALSE");
DbgFEx(3,DbgFNm,DbgSBf);
#endif
return SUCCESS;
}
if (++SStPtr == SBfPtr) {
ErrMsg(ERR_ICE);
DBGFEX(3,DbgFNm,"FAILURE");
return FAILURE;
}
}
}
break;
default:
ErrMsg(ERR_ICE);
DBGFEX(3,DbgFNm,"FAILURE");
return FAILURE;
} /* end of ^E switch */
break;
default:
if (SMFlag == 0) { /* if case independence */
OtCase = Is_Upper(*SStPtr) ? To_Lower(*SStPtr)
: To_Upper(*SStPtr);
*SamChr = ((*EBPtr2 == *SStPtr) || (*EBPtr2 == OtCase));
} else {
*SamChr = (*EBPtr2 == *SStPtr);
}
} /* end of switch */
#if DEBUGGING
sprintf(DbgSBf,"SUCCESS, *SamChr = %s", (*SamChr) ? "TRUE" : "FALSE");
DbgFEx(3,DbgFNm,DbgSBf);
#endif
return SUCCESS;
}