home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) Stephen Chung, 1991-1993. All rights reserved. */
-
- #include "jwp.h"
-
-
- #define EXPBLOCKSIZE 10
- #define CURLYINDICATOR 0xff
-
-
- typedef enum {
- T_ERROR = 0, T_TEXT, T_ESCAPE,
- T_SOFTRETURN, T_HARDRETURN, T_TAB,
- T_MATCHALL, T_MATCHONE, T_MATCHKANJI, T_MATCHASCII, T_MATCHKANA,
- T_COMMA, T_NOT, T_BOL, T_EOL, T_DASH,
- T_OPENPAREN, T_CLOSEPAREN, T_OPENBRACKET, T_CLOSEBRACKET,
- T_OPENCURLY, T_CLOSECURLY
- } TOKEN;
-
- static struct { char ascii; TOKEN token; } tokens[] = {
- { ',', T_COMMA },
- { '!', T_NOT },
- { '^', T_BOL },
- { '$', T_EOL },
- { '-', T_DASH },
- { '*', T_MATCHALL },
- { '?', T_MATCHONE },
- { '(', T_OPENPAREN },
- { ')', T_CLOSEPAREN },
- { '[', T_OPENBRACKET },
- { '[', T_OPENBRACKET },
- { ']', T_CLOSEBRACKET },
- { ']', T_CLOSEBRACKET },
- { '{', T_OPENCURLY },
- { '}', T_CLOSECURLY },
- { '\\', T_ESCAPE },
- { 0, T_ERROR }
- };
-
- static struct { char esc; TOKEN token; } escapes[] = {
- { 'n', T_SOFTRETURN }, /* \n */
- { 'p', T_HARDRETURN }, /* \p */
- { 't', T_TAB }, /* \t */
- { 'x', T_MATCHKANA }, /* \x */
- { 'k', T_MATCHKANJI }, /* \k */
- { 'a', T_MATCHASCII }, /* \a */
- { '\0', T_ERROR }
- };
-
- static char *CompileErrors[] = {
- /* 0 */ "The character after the escape character is missing",
- /* 1 */ "Special characters (\p, \n etc.) cannot be placed within square brackets",
- /* 2 */ "You can only put a NOT symbol right AFTER the open bracket",
- /* 3 */ "The closing bracket is missing",
- /* 4 */ "You must enter something to search for",
- /* 5 */ "The range is not correct",
- /* 6 */ "There must be character(s) inside a pair of brackets",
- /* 7 */ "Curly brackets must enclose the digit 1 - 9",
- /* 8 */ "",
- /* 9 */ "Internal Error. Life is tough."
- };
-
-
- typedef struct RegexStruct {
- TOKEN action;
- LONG data;
- POSITION startpos, endpos;
- struct RegexStruct far *prev, far *next;
- } REGEX;
-
- static REGEX far *Expression = NULL;
- static KANJI far *ExpText = NULL;
-
- static KANJI far *ReplaceExp = NULL;
- static KANJI far *ReplaceText = NULL;
-
- static struct {
- int IgnoreCase:1;
- int Regex:1;
- int JASCII:1;
- int WrapAround:1;
- int WholeFile:1;
- int NoConfirm:1;
- } SearchOptions = { 1, 0, 1, 0, 0, 0 };
-
- BOOL FAR PASCAL SearchProc (HWND, WORD, WORD, LONG);
- BOOL FAR PASCAL ReplaceProc (HWND, WORD, WORD, LONG);
- BOOL FAR PASCAL ReplaceDlgProc (HWND, WORD, WORD, LONG);
- BOOL FAR PASCAL EditReplacementProc (HWND, WORD, WORD, LONG);
-
- static KANJI far *Replacement = NULL;
-
-
-
- static int FindToken (KANJI token)
- {
- int i;
- char ch;
-
- token &= 0x7f7f;
-
- if (ISKANJI(token)) {
- ch = LOBYTE(TranslateJAscii(token, TRUE));
- if (!ch) return (-1);
- } else {
- ch = LOBYTE(token);
- }
-
- for (i = 0; tokens[i].token != T_ERROR; i++) {
- if (tokens[i].ascii == ch) return (i);
- }
- return (-1);
- }
-
-
- static int FindEscape (KANJI escape)
- {
- int i;
-
- if ('A' <= escape && escape <= 'Z') escape += 32;
-
- for (i = 0; escapes[i].token != T_ERROR; i++) {
- if (escapes[i].esc == escape) return (i);
- }
- return (-1);
- }
-
-
- static void FreeRegex (REGEX far *rp)
- {
- REGEX far *rp2;
-
- if (rp == NULL) return;
-
- for (; rp != NULL; ) {
- switch (rp->action) {
- case T_TEXT:
- FreeBlock(rp->data);
- break;
-
- case T_NOT:
- case T_OPENBRACKET:
- case T_OPENPAREN:
- case T_OPENCURLY:
- FreeRegex((REGEX far *) rp->data);
- break;
-
- default:
- break;
- }
-
- rp2 = rp->next;
- FreeBlock(rp);
- rp = rp2;
- }
- }
-
-
-
- #define RETURN_WITH_ERROR(x,y) { FreeRegex(RegexChain); RegexChain = NULL; *OutStr = InStr + (x); *ErrorNum = (y); return (NULL); }
-
-
- static REGEX far *CompileBracketedString (UNIT far *InStr, UNIT far **OutStr, int *ErrorNum, BOOL not)
- {
- int i, j, k, errornum;
- KANJI kch;
- KANJI far *kp;
- REGEX far *RegexChain = NULL, far *rp;
-
- for (i = 0; InStr[i].kanji; i++) {
- kch = InStr[i].kanji;
- j = FindToken(kch);
- if (j >= 0) {
- switch (tokens[j].token) {
- case T_CLOSEBRACKET:
- if (RegexChain == NULL) RETURN_WITH_ERROR(i, 6);
-
- *OutStr = InStr + i;
- return (RegexChain);
-
- case T_ESCAPE:
- kch = InStr[++i].kanji;
- if (!kch) RETURN_WITH_ERROR(i, 0);
- k = FindEscape(kch);
- if (k >= 0) RETURN_WITH_ERROR(i, 1);
- break;
-
- case T_NOT: {
- REGEX far *rpx;
- UNIT far *up;
-
- if (!not) RETURN_WITH_ERROR(i, 2);
- rpx = CompileBracketedString(InStr + i + 1, &up, &errornum, FALSE);
- i = up - InStr;
- if (rpx == NULL) RETURN_WITH_ERROR(i, errornum);
-
- /* Adds to it */
-
- if (RegexChain == NULL) {
- RegexChain = rp = StructAlloc(REGEX);
- rp->action = T_NOT;
- rp->data = (LONG) rpx;
- rp->next = rp->prev = NULL;
- } else {
- rp->next = StructAlloc(REGEX);
- rp->next->prev = rp;
- rp = rp->next;
- rp->next = NULL;
- rp->action = T_NOT;
- rp->data = (LONG) rpx;
- }
-
- *OutStr = up;
- return (RegexChain); /* Success! */
- }
- }
- }
-
- not = FALSE;
-
- if (j < 0 || tokens[j].token != T_DASH) {
- j = FindToken(InStr[i+1].kanji);
- } else {
- kch = 0;
- i--; /* Because it is i += 2 later on */
- goto ItIsADash;
- }
-
- if (j >= 0) {
- switch (tokens[j].token) {
- ItIsADash:
- case T_DASH: {
- KANJI start, stop;
-
- start = kch;
- i += 2;
- stop = InStr[i].kanji;
- if (!stop) RETURN_WITH_ERROR(i, 3);
-
- j = FindToken(stop);
- if (j >= 0 && tokens[j].token == T_CLOSEBRACKET) {
- stop = 0xffff; /* Maximum value */
- i--;
- } else if (j >= 0 && tokens[j].token == T_ESCAPE) {
- stop = InStr[++i].kanji;
- if (!stop) RETURN_WITH_ERROR(i, 3);
- k = FindEscape(stop);
- if (k >= 0) RETURN_WITH_ERROR(i, 1);
- }
-
- //if (ISKANJI(start) && !ISKANJI(stop)) RETURN_WITH_ERROR(i, ?);
- //if (!ISKANJI(start) && ISKANJI(stop)) RETURN_WITH_ERROR(i, ?);
-
- if (start > stop) RETURN_WITH_ERROR(i, 5);
- if (start == stop) {
- kch = start;
- goto StraightText;
- }
-
-
- /* Adds to it */
-
- if (RegexChain == NULL) {
- RegexChain = rp = StructAlloc(REGEX);
- rp->action = T_DASH;
- rp->data = MAKELONG(start,stop);
- rp->next = rp->prev = NULL;
- } else {
- rp->next = StructAlloc(REGEX);
- rp->next->prev = rp;
- rp = rp->next;
- rp->next = NULL;
- rp->action = T_DASH;
- rp->data = MAKELONG(start,stop);
- }
- continue;
- }
-
- }
- }
-
- /* Now, just a normal character */
-
- StraightText:
-
- if (RegexChain == NULL) {
- RegexChain = rp = StructAlloc(REGEX);
- rp->action = T_TEXT;
- kp = BlockAlloc(EXPBLOCKSIZE * sizeof(KANJI));
- kp[0] = kch;
- kp[1] = 0;
- rp->data = (LONG) kp;
- rp->next = rp->prev = NULL;
- } else if (rp->action != T_TEXT) {
- rp->next = StructAlloc(REGEX);
- rp->next->prev = rp;
- rp = rp->next;
- rp->next = NULL;
- rp->action = T_TEXT;
- kp = BlockAlloc(EXPBLOCKSIZE * sizeof(KANJI));
- kp[0] = kch;
- kp[1] = 0;
- rp->data = (LONG) kp;
- } else {
- kp = (KANJI far *) rp->data;
- j = kanjilen(kp);
- k = SegHeapGetSize(kp) / sizeof(KANJI);
- if (j + 2 >= k) {
- kp = (KANJI far *) BlockRealloc(kp, (k + EXPBLOCKSIZE) * sizeof(KANJI));
- rp->data = (LONG) kp;
- }
- kp[j] = kch;
- kp[j+1] = 0;
- }
- }
-
- RETURN_WITH_ERROR(i, 3);
- }
-
-
-
- static BOOL CharInBracketed (KANJI ch, REGEX far *rp)
- {
- int i;
- KANJI far *kp;
- KANJI start, stop;
-
- for (; rp != NULL; rp = rp->next) {
- switch (rp->action) {
- case T_TEXT:
- kp = (KANJI far *) rp->data;
- for (i = 0; kp[i]; i++) if (ch == kp[i]) return (TRUE);
- break;
-
- case T_NOT:
- return (!CharInBracketed(ch, (REGEX far *) rp->data));
-
- case T_DASH:
- start = LOWORD(rp->data);
- stop = HIWORD(rp->data);
- if (start <= ch && ch <= stop) return (TRUE);
- break;
- }
- }
-
- return (FALSE);
- }
-
-
-
- static REGEX far *CompileText (UNIT far *InStr)
- {
- int i, len;
- REGEX far *rp;
- KANJI far *kp;
-
- len = unitlen(InStr);
-
- if (len <= 0) return (NULL);
-
- rp = StructAlloc(REGEX);
- rp->action = T_TEXT;
-
- kp = (KANJI far *) BlockAlloc((len + 5) * sizeof(KANJI));
-
- for (i = 0; i < len; i++) kp[i] = InStr[i].kanji;
- kp[len] = 0;
-
- rp->data = (LONG) kp;
- rp->prev = rp->next = NULL;
-
- return (rp);
- }
-
-
-
- static REGEX far *CompileRegex (TOKEN action, UNIT far *InStr, UNIT far **OutStr, int *ErrorNum)
- {
- int i, j, k, errornum;
- KANJI kch;
- REGEX far *RegexChain = NULL;
- REGEX far *rp;
- REGEX far *SubRegex;
- KANJI far *kp;
- UNIT far *up;
- TOKEN token;
-
-
- /* Now process the string */
-
- *OutStr = InStr;
-
- for (i = 0; ; i++) {
- kch = InStr[i].kanji;
- if (!kch) {
- if (action != T_ERROR) RETURN_WITH_ERROR(i, 3) else break;
- }
-
- j = FindToken(kch);
-
-
- if (j < 0) {
- /* Not a special character */
- TextMatch: if (RegexChain == NULL) {
- RegexChain = rp = StructAlloc(REGEX);
- rp->action = T_TEXT;
- kp = BlockAlloc(EXPBLOCKSIZE * sizeof(KANJI));
- kp[0] = kch;
- kp[1] = 0;
- rp->data = (LONG) kp;
- rp->next = rp->prev = NULL;
- } else if (rp->action != T_TEXT) {
- rp->next = StructAlloc(REGEX);
- rp->next->prev = rp;
- rp = rp->next;
- rp->next = NULL;
- rp->action = T_TEXT;
- kp = BlockAlloc(EXPBLOCKSIZE * sizeof(KANJI));
- kp[0] = kch;
- kp[1] = 0;
- rp->data = (LONG) kp;
- } else {
- kp = (KANJI far *) rp->data;
- j = kanjilen(kp);
- k = SegHeapGetSize(kp) / sizeof(KANJI);
- if (j + 2 >= k) {
- kp = (KANJI far *) BlockRealloc(kp, (k + EXPBLOCKSIZE) * sizeof(KANJI));
- rp->data = (LONG) kp;
- }
- kp[j] = kch;
- kp[j+1] = 0;
- }
- continue;
- }
-
- /* Now, it is a special character */
-
- if (action == T_OPENPAREN) {
- if (tokens[j].token == T_CLOSEPAREN || tokens[j].token == T_COMMA) break;
- } else if (action == T_OPENBRACKET) {
- if (tokens[j].token == T_CLOSEBRACKET) break;
- } else if (action == T_OPENCURLY) {
- if (tokens[j].token == T_CLOSECURLY) break;
- }
-
-
- /* Process the special character */
-
- switch (tokens[j].token) {
- case T_ESCAPE:
- kch = InStr[++i].kanji;
- if (!kch) RETURN_WITH_ERROR(i, 0);
- k = FindEscape(kch);
- if (k < 0) goto TextMatch;
- token = escapes[k].token;
- SubRegex = NULL;
- break;
-
- case T_OPENCURLY:
- SubRegex = CompileRegex(tokens[j].token, InStr + i + 1, &up, &errornum);
- i = up - InStr;
- if (SubRegex == NULL) RETURN_WITH_ERROR(i, errornum);
- token = T_OPENCURLY;
- break;
-
- case T_OPENPAREN: {
- int x;
- REGEX far *SubExp = NULL, far *rpx;
-
- for (;;) { /* Wait till a close paren */
- SubRegex = CompileRegex(tokens[j].token, InStr + i + 1, &up, &errornum);
- i = up - InStr;
- if (SubRegex == NULL) RETURN_WITH_ERROR(i, errornum);
-
- /* Insert a new block */
-
- if (SubExp == NULL) {
- SubExp = rpx = SubRegex;
- } else {
- rpx->next = SubRegex;
- SubRegex->prev = rpx;
- rpx = SubRegex;
- }
-
- x = FindToken(up->kanji);
- if (x >= 0 && tokens[x].token == T_CLOSEPAREN) break;
- }
- token = T_OPENPAREN;
- SubRegex = SubExp;
- break;
- }
-
- case T_OPENBRACKET:
- SubRegex = CompileBracketedString(InStr + i + 1, &up, &errornum, TRUE);
- i = up - InStr;
- if (SubRegex == NULL) RETURN_WITH_ERROR(i, errornum);
- token = T_OPENBRACKET;
- break;
-
- case T_BOL:
- case T_EOL:
- case T_MATCHALL:
- case T_MATCHONE:
- case T_MATCHKANJI:
- case T_MATCHASCII:
- case T_MATCHKANA:
- case T_SOFTRETURN:
- case T_HARDRETURN:
- case T_TAB:
- SubRegex = NULL;
- token = tokens[j].token;
- break;
-
- default:
- RETURN_WITH_ERROR(i, 9);
- }
-
- /* Insert a new block */
-
- if (RegexChain == NULL) {
- RegexChain = rp = StructAlloc(REGEX);
- rp->prev = NULL;
- } else {
- rp->next = StructAlloc(REGEX);
- rp->next->prev = rp;
- rp = rp->next;
- }
- rp->next = NULL;
- rp->action = token;
- rp->data = (LONG) SubRegex;
- }
-
- if (RegexChain == NULL) {
- if (action == T_ERROR) { RETURN_WITH_ERROR(i, 4); }
- else { RETURN_WITH_ERROR(i, 6); }
- }
-
- *OutStr = InStr + i;
- return (RegexChain);
- }
-
-
-
- #define REPLACE_ERROR(x,y) { if (kp != NULL) FreeBlock(kp); *OutStr = InStr + (x); *ErrorNum = (y); return (NULL); }
-
- static KANJI far *CompileReplaceString (BOOL Regex, UNIT far *InStr, UNIT far **OutStr, int *ErrorNum)
- {
- int i, j, len;
- KANJI kch;
- KANJI far *kp = NULL;
-
-
- *OutStr = InStr;
-
- if (!Regex) {
- len = unitlen(InStr);
- kp = BlockAlloc((len + 5) * sizeof(KANJI));
- for (i = 0; i < len; i++) kp[i] = InStr[i].kanji;
- kp[len] = 0;
- *OutStr = NULL;
- *ErrorNum = 0;
- return (kp);
- }
-
-
- for (i = 0; InStr[i].kanji; i++) {
- kch = InStr[i].kanji;
-
- j = FindToken(kch);
-
- switch (tokens[j].token) {
- case T_ESCAPE:
- kch = InStr[++i].kanji;
- if (!kch) REPLACE_ERROR(i,0);
- j = FindEscape(kch);
- if (j >= 0) {
- switch (escapes[j].token) {
- case T_SOFTRETURN: kch = '\n'; break;
- case T_HARDRETURN: kch = '\r'; break;
- case T_TAB: kch = '\t'; break;
- default: break;
- }
- }
- break;
-
- case T_OPENCURLY:
- kch = InStr[i+1].kanji;
- if (ISKANJI(kch)) kch = TranslateJAscii(kch, TRUE);
- if (!kch) REPLACE_ERROR(i + 1, 7);
-
- if ('1' > kch || kch > '9') REPLACE_ERROR(i + 1, 7);
- j = FindToken(InStr[i+2].kanji);
- if (tokens[j].token != T_CLOSECURLY) REPLACE_ERROR(i + 2, 7);
-
- kch = (CURLYINDICATOR << 8) | (kch - '1');
- i += 2;
- break;
- }
-
- if (kp == NULL) {
- kp = BlockAlloc(EXPBLOCKSIZE * sizeof(KANJI));
- len = 0;
- kp[0] = kch;
- kp[1] = 0;
- } else {
- len = kanjilen(kp);
- j = SegHeapGetSize(kp);
-
- if ((len + 5) * sizeof(KANJI) >= j) {
- kp = BlockRealloc(kp, j + EXPBLOCKSIZE);
- }
- kp[len] = kch;
- kp[len + 1] = 0;
- }
- }
-
- *ErrorNum = 0;
- return (kp);
- }
-
-
-
- static BOOL CharComp (KANJI c1, KANJI c2, BOOL JASCII, BOOL nocase)
- {
- c1 &= 0x7f7f;
- c2 &= 0x7f7f;
-
- if (JASCII) {
- if (/* A */ 0x2341 <= c1 && c1 <= 0x235a /* Z */) c1 = 'A' + (c1 - 0x2341);
- if (/* a */ 0x2361 <= c1 && c1 <= 0x237a /* z */) c1 = 'a' + (c1 - 0x2361);
- if (/* A */ 0x2341 <= c2 && c2 <= 0x235a /* Z */) c2 = 'A' + (c2 - 0x2341);
- if (/* a */ 0x2361 <= c2 && c2 <= 0x237a /* z */) c2 = 'a' + (c2 - 0x2361);
- }
- if (nocase) {
- if ('A' <= c1 && c1 <= 'Z') c1 += 32;
- if ('A' <= c2 && c2 <= 'Z') c2 += 32;
- }
- return (c1 - c2);
- }
-
-
-
- static BOOL MatchRegex (REGEX far *regex, POSITION *StartPos, BOOL JASCII, BOOL nocase)
- {
- int i, j;
- int LineLength;
- UNIT far *up;
- KANJI far *kp;
- REGEX far *rp;
- POSITION pos, TempPos;
-
-
- rp = regex;
- pos = *StartPos;
-
- for (;;) {
- if (rp == NULL) break;
-
- up = PARAOF(pos)->text;
- LineLength = unitlen(up);
-
- for (i = POSOF(pos); i <= LineLength; i++) {
- POSOF(pos) = i;
-
- if (i == LineLength) {
- if (rp->action != T_EOL && rp->action != T_HARDRETURN) return (FALSE);
- }
-
- switch (rp->action) {
- case T_TEXT:
- kp = (KANJI far *) rp->data;
- for (j = 0; up[i + j].kanji; j++) {
- if (!kp[j]) break;
- if (CharComp(kp[j], up[i + j].kanji, JASCII, nocase)) break;
- }
- if (kp[j]) return (FALSE); /* Not matched */
-
- /* Matched... */
- PARAOF(rp->startpos) = PARAOF(rp->endpos) = PARAOF(pos);
- POSOF(rp->startpos) = i;
- POSOF(rp->endpos) = i + j - 1;
-
- i += (j - 1);
- rp = rp->next;
- break;
-
- case T_BOL:
- if (i > 0) return (FALSE); /* Not matched */
-
- rp->startpos = rp->endpos = pos;
- i--;
- rp = rp->next;
- break;
-
- case T_EOL:
- case T_HARDRETURN:
- if (i != LineLength) return (FALSE);
-
- rp->startpos = rp->endpos = pos;
- rp = rp->next;
- break;
-
- case T_SOFTRETURN:
- if (up[i].kanji != '\n') return (FALSE);
- rp->startpos = rp->endpos = pos;
- rp = rp->next;
- break;
-
- case T_TAB:
- if (up[i].kanji != '\t') return (FALSE);
- rp->startpos = rp->endpos = pos;
- rp = rp->next;
- break;
-
- case T_MATCHONE:
- if (up[i].kanji == 0) return (FALSE);
- rp->startpos = rp->endpos = pos;
- rp = rp->next;
- break;
-
- case T_MATCHKANA:
- if (!ISKANJI(up[i].kanji)) return (FALSE);
- if (HIBYTE(up[i].kanji) != 0x24 && HIBYTE(up[i].kanji) != 0x25)
- return (FALSE);
-
- rp->startpos = rp->endpos = pos;
- rp = rp->next;
- break;
-
- case T_MATCHKANJI:
- if (!ISKANJI(up[i].kanji)) return (FALSE);
- if (up[i].kanji < 0x3021) return (FALSE);
-
- rp->startpos = rp->endpos = pos;
- rp = rp->next;
- break;
-
- case T_MATCHASCII:
- if (ISKANJI(up[i].kanji)) return (FALSE);
- rp->startpos = rp->endpos = pos;
- rp = rp->next;
- break;
-
- case T_OPENCURLY:
- rp->startpos = TempPos = pos;
-
- if (!MatchRegex((REGEX far *) rp->data, &TempPos, JASCII, nocase))
- return (FALSE);
-
- /* Matched... */
- pos = rp->endpos = TempPos;
- i = POSOF(pos);
- rp = rp->next;
- break;
-
- case T_MATCHALL: {
- BOOL Matched = FALSE;
- int len;
-
- rp->startpos = TempPos = pos;
- len = unitlen(PARAOF(TempPos)->text);
- POSOF(TempPos) = i;
-
- for (;;) {
- if (POSOF(TempPos) >= len) {
- if (PARAOF(TempPos)->next == NULL) return (FALSE);
- PARAOF(TempPos) = PARAOF(TempPos)->next;
- POSOF(TempPos) = i = 0;
- len = unitlen(PARAOF(TempPos)->text);
- }
- if (MatchRegex(rp->next, &TempPos, JASCII, nocase)) {
- Matched = TRUE;
- break;
- }
- POSOF(TempPos)++;
- }
-
- if (!Matched) return (FALSE);
-
- pos = rp->endpos = TempPos;
- *StartPos = pos;
- return (TRUE);
- }
-
- case T_OPENPAREN: {
- REGEX far *rpx;
- REGEX far *rpnext;
-
- for (rpx = (REGEX far *) rp->data; rpx != NULL; rpx = rpx->next) {
- rp->startpos = TempPos = pos;
- /* Must unlink */
- rpnext = rpx->next;
- rpx->next = NULL;
- if (MatchRegex(rpx, &TempPos, JASCII, nocase)) break;
- rpx->next = rpnext;
- }
- if (rpx == NULL) return (FALSE);
-
- /* Matched... */
- pos = rp->endpos = TempPos;
- i = POSOF(pos);
- rp = rp->next;
- break;
- }
-
- case T_OPENBRACKET:
- if (!CharInBracketed(up[i].kanji, (REGEX far *) rp->data))
- return (FALSE);
-
- rp->startpos = rp->endpos = pos;
- rp = rp->next;
- break;
- }
-
- POSOF(pos) = i;
-
- if (rp == NULL) {
- *StartPos = pos;
- return (TRUE);
- }
- }
-
- if (PARAOF(pos)->next == NULL) break;
-
- PARAOF(pos) = PARAOF(pos)->next;
- POSOF(pos) = 0;
- }
-
- if (rp == NULL) {
- *StartPos = pos;
- return (TRUE);
- } else {
- return (FALSE);
- }
- }
-
-
-
- static REGEX far *GetCurlyString (REGEX far *regex, int *num, KANJI far *buffer)
- {
- int i, j;
- KANJI kch;
- REGEX far *rp, far *rp1;
- POSITION p;
-
- for (rp = regex; rp != NULL; rp = rp->next) {
- if (rp->action != T_OPENCURLY) continue;
-
- if (*num == 0) {
- p = rp->startpos;
- i = POSOF(p);
- j = 0;
-
- for(;;) {
- if (PARAOF(p) == NULL) break;
- if (PARAOF(p) == PARAOF(rp->endpos) && i > POSOF(rp->endpos)) break;
- kch = PARAOF(p)->text[i].kanji;
-
- if (!kch) {
- buffer[j++] = '\r';
- PARAOF(p) = PARAOF(p)->next;
- POSOF(p) = i = 0;
- } else {
- buffer[j++] = kch;
- i++;
- }
- }
-
- buffer[j] = 0;
- return (rp);
- } else {
- (*num)--;
- rp1 = GetCurlyString((REGEX far *) rp->data, num, buffer);
- if (rp1 != NULL) return (rp1);
- }
- }
-
- buffer[0] = 0;
- return (NULL);
- }
-
-
-
- static void ConstructReplacement (REGEX far *exp, KANJI far *rp, KANJI far *buffer)
- {
- int i, j;
- int level;
-
- for (i = j = 0; rp[i]; i++) {
- if (HIBYTE(rp[i]) != CURLYINDICATOR) {
- buffer[j++] = rp[i];
- continue;
- }
-
- level = LOBYTE(rp[i]);
-
- if (GetCurlyString(exp, &level, buffer + j) == NULL) continue;
-
- j = kanjilen(buffer);
- }
- buffer[j] = 0;
- }
-
-
-
- void DoSearch (void)
- {
- FILEOPTIONS *f;
- int i, len;
- KANJI FirstChar;
- BOOL Matched = FALSE;
- BOOL Wrapped = FALSE;
- HCURSOR hcursor;
- POSITION p;
-
-
- if (Expression == NULL) {
- i = DialogBox (hInstance, "Search", global.hwnd, SearchProc);
- if (!i) return;
- }
-
- /* Set up the first character - for speed */
-
- if (Expression->action == T_TEXT) {
- FirstChar = ((KANJI far *) Expression->data)[0];
- } else {
- FirstChar = 0;
- }
-
-
- /* Now do the search */
-
- hcursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
- ShowCursor(TRUE);
-
- f = global.active;
-
- if (SearchOptions.WholeFile) {
- PARAOF(p) = f->paragraph;
- POSOF(p) = 0;
- } else {
- PARAOF(p) = CURPARA(f);
- POSOF(p) = POS2ABS(f->current);
- }
- len = unitlen(PARAOF(p)->text);
-
- for (;;) {
- if (POSOF(p) >= len) {
- if (PARAOF(p)->next == NULL) {
- if (!SearchOptions.WrapAround || Wrapped) break;
- PARAOF(p) = f->paragraph;
- POSOF(p) = 0;
- Wrapped = TRUE;
- } else {
- PARAOF(p) = PARAOF(p)->next;
- POSOF(p) = 0;
- }
- len = unitlen(PARAOF(p)->text);
- }
-
- if (FirstChar > 0 && FirstChar != PARAOF(p)->text[POSOF(p)].kanji) {
- POSOF(p)++;
- continue;
- }
-
- if (MatchRegex(Expression, &p, SearchOptions.JASCII, SearchOptions.IgnoreCase)) {
- Matched = TRUE;
- break;
- }
- POSOF(p)++;
- }
-
- ShowCursor(FALSE);
- SetCursor(hcursor);
-
- if (!Matched) {
- TurnOffSelection(f);
- ErrorMessage(global.hwnd, "Search String Not Found.");
- } else {
- POSITION endrel;
-
- if (SELPARA1(f) != NULL) FlipHighlight(f);
- SEL1(f) = Expression->startpos;
- SEL2(f) = p;
- SELTYPE(f) = SEL_SELECTION;
-
- /* Set the cursor */
- if (POSOF(p) >= unitlen(PARAOF(p)->text)) {
- if (PARAOF(p)->next != NULL) {
- PARAOF(p) = PARAOF(p)->next;
- POSOF(p) = 0;
- }
- } else {
- POSOF(p)++;
- }
-
- AbsoluteToPosition(p, &endrel);
- f->current = endrel;
-
- if (CURPARA(f) != global.cpospara) FillCPos(f, CURPARA(f), 0, -1);
-
- if (!FindCaret(f, FALSE)) {
- MoveIntoWindow(f);
- InvalidateRect(f->hwnd, NULL, TRUE);
- UpdateWindow(f->hwnd);
- } else {
- FlipHighlight(f);
- }
- f->pseudo = f->cursor;
- DoCaret(f, CURX(f), CURY(f) - CURLINE(f)->height, TRUE);
- Triangles(f);
- }
- }
-
-
-
- void DoReplace (void)
- {
- FILEOPTIONS *f;
- int i, len, nr_matched;
- KANJI FirstChar;
- BOOL Matched;
- BOOL Wrapped = FALSE;
- BOOL KeepGoing = TRUE;
- BOOL NeedConfirm;
- HCURSOR hcursor;
- POSITION p;
- KANJI buffer[MAXLINELEN];
-
-
- if (ReplaceExp == NULL || Expression == NULL) {
- i = DialogBox (hInstance, "Replace", global.hwnd, ReplaceProc);
- if (!i) return;
- }
-
-
- /* Set up the first character - for speed */
-
- if (Expression->action == T_TEXT) {
- FirstChar = ((KANJI far *) Expression->data)[0];
- } else {
- FirstChar = 0;
- }
-
-
- /* Now do the search */
-
- hcursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
- ShowCursor(TRUE);
-
- f = global.active;
-
- NeedConfirm = !SearchOptions.NoConfirm;
- nr_matched = 0;
-
- if (NeedConfirm) {
- PARAOF(p) = f->paragraph;
- POSOF(p) = 0;
- } else {
- PARAOF(p) = CURPARA(f);
- POSOF(p) = POS2ABS(f->current);
- }
- len = unitlen(PARAOF(p)->text);
-
- Loop:
-
- Matched = FALSE;
-
- for (;;) {
- if (POSOF(p) >= len) {
- if (PARAOF(p)->next == NULL) {
- if (Wrapped) break;
- PARAOF(p) = f->paragraph;
- POSOF(p) = 0;
- Wrapped = TRUE;
- } else {
- PARAOF(p) = PARAOF(p)->next;
- POSOF(p) = 0;
- }
- len = unitlen(PARAOF(p)->text);
- }
-
- if (FirstChar > 0 && FirstChar != PARAOF(p)->text[POSOF(p)].kanji) {
- POSOF(p)++;
- continue;
- }
-
- if (MatchRegex(Expression, &p, SearchOptions.JASCII, SearchOptions.IgnoreCase)) {
- Matched = TRUE;
- nr_matched++;
- break;
- }
- POSOF(p)++;
- }
-
- if (!Matched) {
- ShowCursor(FALSE);
- SetCursor(hcursor);
- TurnOffSelection(f);
- if (nr_matched > 0) {
- char buf[50];
-
- sprintf(buf, "%d changes made", nr_matched);
- StatusMessage(buf);
- } else {
- ErrorMessage(global.hwnd, "Search String Not Found.");
- }
- KeepGoing = FALSE;
- } else {
- POSITION startrel, endrel;
-
- TurnOffSelection(f);
- SEL1(f) = Expression->startpos;
- SEL2(f) = p;
- SELTYPE(f) = SEL_SELECTION;
-
- /* Set the cursor */
- if (POSOF(p) >= unitlen(PARAOF(p)->text)) {
- if (PARAOF(p)->next != NULL) {
- PARAOF(p) = PARAOF(p)->next;
- POSOF(p) = 0;
- }
- } else {
- POSOF(p)++;
- }
-
- AbsoluteToPosition(p, &endrel);
- f->current = endrel;
-
- if (CURPARA(f) != global.cpospara) FillCPos(f, CURPARA(f), 0, -1);
-
- if (!FindCaret(f, FALSE)) {
- MoveIntoWindow(f);
- InvalidateRect(f->hwnd, NULL, TRUE);
- UpdateWindow(f->hwnd);
- } else {
- FlipHighlight(f);
- }
- f->pseudo = f->cursor;
- DoCaret(f, CURX(f), CURY(f) - CURLINE(f)->height, TRUE);
- Triangles(f);
-
- ConstructReplacement(Expression, ReplaceExp, buffer);
-
- if (NeedConfirm) {
- /* Put up the dialog box */
-
- ShowCursor(FALSE);
- SetCursor(hcursor);
-
- Replacement = buffer;
-
- i = DialogBox (hInstance, "ReplaceDlg", global.hwnd, ReplaceProc);
-
- hcursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
- ShowCursor(TRUE);
-
- switch (i) {
- case 4203: /* All */
- NeedConfirm = FALSE;
- /* ... falls into the next case */
-
- case 1: /* Yes */
- TurnOffSelection(f);
- AbsoluteToPosition(Expression->startpos, &startrel);
- if (POSOF(p) > 0) POSOF(p)--;
- AbsoluteToPosition(p, &endrel);
- BlockReplace(f, startrel, endrel, (KANJI far *) buffer);
- break;
-
- case 2: /* Stop */
- KeepGoing = FALSE;
- ShowCursor(FALSE);
- SetCursor(hcursor);
- break;
-
- case 4201: /* No*/
- break;
- }
- } else {
- TurnOffSelection(f);
- AbsoluteToPosition(Expression->startpos, &startrel);
- if (POSOF(p) > 0) POSOF(p)--;
- AbsoluteToPosition(p, &endrel);
- BlockReplace(f, startrel, endrel, (KANJI far *) buffer);
- }
- }
-
- if (KeepGoing) goto Loop;
- }
-
-
-
- BOOL FAR PASCAL SearchProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
- {
- switch (message) {
- case WM_INITDIALOG: {
- FILEOPTIONS *f;
-
- /* Set the type and mode-change icon */
- SendDlgItemMessage(hwnd, 4201, EM_SETMODIFY, FN_CONTROL, 0L);
- SendDlgItemMessage(hwnd, 4201, EM_SETRECT, GetDlgItem(hwnd, 4241), 0L);
-
- //SendDlgItemMessage(hwnd, 4202, EM_SETMODIFY, FN_CONTROL, 0L);
- //SendDlgItemMessage(hwnd, 4202, EM_SETRECT, GetDlgItem(hwnd, 4241), 0L);
-
- f = (FILEOPTIONS *) SendDlgItemMessage(hwnd, 4201, EM_GETHANDLE, 0, 0L);
- SendDlgItemMessage(hwnd, 4241, EM_SETHANDLE, f->hwnd, 0L); /* mode-change icon */
-
- if (ExpText != NULL) {
- int len;
-
- SendDlgItemMessage(hwnd, 4201, EM_REPLACESEL, 0, (LONG) ExpText);
- len = kanjilen(ExpText);
- if (len > 0) {
- SendDlgItemMessage(hwnd, 4201, EM_SETSEL, len, MAKELONG(0, len - 1));
- }
- }
-
- CheckDlgButton (hwnd, 4221, SearchOptions.IgnoreCase);
- CheckDlgButton (hwnd, 4222, SearchOptions.Regex);
- CheckDlgButton (hwnd, 4223, SearchOptions.JASCII);
- CheckDlgButton (hwnd, 4224, SearchOptions.WrapAround);
- CheckDlgButton (hwnd, 4225, SearchOptions.WholeFile);
- //CheckDlgButton (hwnd, 4226, SearchOptions.NoConfirm);
-
- CenterDialogBox(hwnd);
- return (TRUE);
- }
-
- case WM_PAINT: {
- HDC hdc;
- PAINTSTRUCT ps;
-
- hdc = BeginPaint(hwnd, &ps);
-
- DrawBoundingBox(hwnd, hdc, 4201);
- //DrawBoundingBox(hwnd, hdc, 4202);
-
- EndPaint(hwnd, &ps);
- return (TRUE);
- }
-
- case WM_COMMAND:
- switch (wParam) {
- case IDOK: {
- int i, len, errornum;
- UNIT far *up, far *up1;
- REGEX far *rp;
-
- SearchOptions.IgnoreCase = IsDlgButtonChecked(hwnd, 4221);
- SearchOptions.Regex = IsDlgButtonChecked(hwnd, 4222);
- SearchOptions.JASCII = IsDlgButtonChecked(hwnd, 4223);
- SearchOptions.WrapAround = IsDlgButtonChecked(hwnd, 4224);
- SearchOptions.WholeFile = IsDlgButtonChecked(hwnd, 4225);
- //SearchOptions.NoConfirm = IsDlgButtonChecked(hwnd, 4226);
-
- up = (UNIT far *) SendDlgItemMessage(hwnd, 4201, EM_GETLINE, 0, 0L);
-
- if (SearchOptions.Regex) {
- rp = CompileRegex(0, up, &up1, &errornum);
- if (rp == NULL) {
- ErrorMessage(hwnd, "Error in Regular Expression: %s.\n\n"
- "Please correct the regular expression and try again.",
- CompileErrors[errornum]);
- SendDlgItemMessage(hwnd, 4201, EM_SETSEL, up1 - up, 0L);
- SetFocus(GetDlgItem(hwnd, 4201));
- return (TRUE);
- }
- } else {
- rp = CompileText(up);
- if (rp == NULL) {
- ErrorMessage(hwnd, "You must enter something to search for!");
- SetFocus(GetDlgItem(hwnd, 4201));
- return (TRUE);
- }
- }
-
- if (Expression != NULL) FreeRegex(Expression);
- Expression = rp;
-
- if (ExpText != NULL) FreeBlock(ExpText);
-
- len = unitlen(up);
- ExpText = (KANJI far *) BlockAlloc((len + 5) * sizeof(KANJI));
- for (i = 0; i < len; i++) ExpText[i] = up[i].kanji;
- ExpText[len] = 0;
-
- EndDialog(hwnd, TRUE);
- return (TRUE);
- }
-
- case IDCANCEL:
- EndDialog(hwnd, FALSE);
- return (TRUE);
- }
- }
- return (FALSE);
- }
-
-
- BOOL FAR PASCAL ReplaceProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
- {
- switch (message) {
- case WM_INITDIALOG: {
- int len;
- FILEOPTIONS *f;
-
- /* Set the type and mode-change icon */
- SendDlgItemMessage(hwnd, 4201, EM_SETMODIFY, FN_CONTROL, 0L);
- SendDlgItemMessage(hwnd, 4201, EM_SETRECT, GetDlgItem(hwnd, 4241), 0L);
-
- SendDlgItemMessage(hwnd, 4202, EM_SETMODIFY, FN_CONTROL, 0L);
- SendDlgItemMessage(hwnd, 4202, EM_SETRECT, GetDlgItem(hwnd, 4241), 0L);
-
- f = (FILEOPTIONS *) SendDlgItemMessage(hwnd, 4201, EM_GETHANDLE, 0, 0L);
- SendDlgItemMessage(hwnd, 4241, EM_SETHANDLE, f->hwnd, 0L); /* mode-change icon */
-
- if (ExpText != NULL) {
- SendDlgItemMessage(hwnd, 4201, EM_REPLACESEL, 0, (LONG) ExpText);
- len = kanjilen(ExpText);
- if (len > 0) {
- SendDlgItemMessage(hwnd, 4201, EM_SETSEL, len, MAKELONG(0, len - 1));
- }
- }
- if (ReplaceText != NULL) {
- SendDlgItemMessage(hwnd, 4202, EM_REPLACESEL, 0, (LONG) ReplaceText);
- len = kanjilen(ReplaceText);
- }
-
- CheckDlgButton (hwnd, 4221, SearchOptions.IgnoreCase);
- CheckDlgButton (hwnd, 4222, SearchOptions.Regex);
- CheckDlgButton (hwnd, 4223, SearchOptions.JASCII);
- //CheckDlgButton (hwnd, 4224, SearchOptions.WrapAround);
- //CheckDlgButton (hwnd, 4225, SearchOptions.WholeFile);
- CheckDlgButton (hwnd, 4226, SearchOptions.NoConfirm);
-
- CenterDialogBox(hwnd);
- return (TRUE);
- }
-
- case WM_PAINT: {
- HDC hdc;
- PAINTSTRUCT ps;
-
- hdc = BeginPaint(hwnd, &ps);
-
- DrawBoundingBox(hwnd, hdc, 4201);
- DrawBoundingBox(hwnd, hdc, 4202);
-
- EndPaint(hwnd, &ps);
- return (TRUE);
- }
-
- case WM_COMMAND:
- switch (wParam) {
- case IDOK: {
- int i, len, errornum;
- KANJI far *kp;
- UNIT far *up, far *up1;
- REGEX far *rp;
-
- SearchOptions.IgnoreCase = IsDlgButtonChecked(hwnd, 4221);
- SearchOptions.Regex = IsDlgButtonChecked(hwnd, 4222);
- SearchOptions.JASCII = IsDlgButtonChecked(hwnd, 4223);
- //SearchOptions.WrapAround = IsDlgButtonChecked(hwnd, 4224);
- //SearchOptions.WholeFile = IsDlgButtonChecked(hwnd, 4225);
- SearchOptions.NoConfirm = IsDlgButtonChecked(hwnd, 4226);
-
- up = (UNIT far *) SendDlgItemMessage(hwnd, 4201, EM_GETLINE, 0, 0L);
-
- /* Compile the Search Text */
-
- if (SearchOptions.Regex) {
- rp = CompileRegex(0, up, &up1, &errornum);
- if (rp == NULL) {
- ErrorMessage(hwnd, "Error in Regular Expression: %s.\n\n"
- "Please correct the regular expression and try again.",
- CompileErrors[errornum]);
- SendDlgItemMessage(hwnd, 4201, EM_SETSEL, up1 - up, 0L);
- SetFocus(GetDlgItem(hwnd, 4201));
- return (TRUE);
- }
- } else {
- rp = CompileText(up);
- if (rp == NULL) {
- ErrorMessage(hwnd, "You must enter something to search for!");
- SetFocus(GetDlgItem(hwnd, 4201));
- return (TRUE);
- }
- }
-
- if (Expression != NULL) FreeRegex(Expression);
- Expression = rp;
-
- if (ExpText != NULL) FreeBlock(ExpText);
-
- len = unitlen(up);
- ExpText = (KANJI far *) BlockAlloc((len + 5) * sizeof(KANJI));
- for (i = 0; i < len; i++) ExpText[i] = up[i].kanji;
- ExpText[len] = 0;
-
- /* Compile the replace text */
-
- up = (UNIT far *) SendDlgItemMessage(hwnd, 4202, EM_GETLINE, 0, 0L);
-
- if (SearchOptions.Regex) {
- kp = CompileReplaceString(TRUE, up, &up1, &errornum);
- if (kp == NULL) {
- ErrorMessage(hwnd, "Error in the replacement text: %s.\n\n"
- "Please correct the expression and try again.",
- CompileErrors[errornum]);
- SendDlgItemMessage(hwnd, 4202, EM_SETSEL, up1 - up, 0L);
- SetFocus(GetDlgItem(hwnd, 4202));
- return (TRUE);
- }
- } else {
- kp = CompileReplaceString(FALSE, up, &up1, &errornum);
- }
-
- if (ReplaceExp != NULL) FreeBlock(ReplaceExp);
- ReplaceExp = kp;
-
- if (ReplaceText != NULL) FreeBlock(ReplaceText);
-
- len = unitlen(up);
- ReplaceText = (KANJI far *) BlockAlloc((len + 5) * sizeof(KANJI));
- for (i = 0; i < len; i++) ReplaceText[i] = up[i].kanji;
- ReplaceText[len] = 0;
-
- EndDialog(hwnd, TRUE);
- return (TRUE);
- }
-
- case IDCANCEL:
- EndDialog(hwnd, FALSE);
- return (TRUE);
- }
- }
- return (FALSE);
- }
-
-
-
- BOOL FAR PASCAL ReplaceDlgProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
- {
- switch (message) {
- case WM_INITDIALOG:
- if (Replacement != NULL) {
- SendDlgItemMessage(hwnd, 4211, EM_REPLACESEL, 0, (LONG) Replacement);
- }
- break;
-
- case WM_COMMAND:
- switch (wParam) {
- case IDOK: /* Yes */
- case IDCANCEL: /* Stop */
- case 4201: /* No */
- case 4203: /* All */
- EndDialog(hwnd, wParam);
- return (TRUE);
-
- case 4202: /* Change */
- if (DialogBox (hInstance, "EditReplacement", hwnd, EditReplacementProc)) {
- SendDlgItemMessage(hwnd, 4211, EM_REPLACESEL, 0, (LONG) Replacement);
- InvalidateRect(GetDlgItem(hwnd, 4211), NULL, TRUE);
- }
- return (TRUE);
- }
- break;
- }
- return (FALSE);
- }
-
-
-
- BOOL FAR PASCAL EditReplacementProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
- {
- switch (message) {
- case WM_INITDIALOG: {
- int len;
- FILEOPTIONS *f;
-
- /* Set the type and mode-change icon of the Jedit control */
- SendDlgItemMessage(hwnd, 4201, EM_SETMODIFY, FN_CONTROL, 0L);
- SendDlgItemMessage(hwnd, 4201, EM_SETRECT, GetDlgItem(hwnd, 4202), 0L);
-
- f = (FILEOPTIONS *) SendDlgItemMessage(hwnd, 4201, EM_GETHANDLE, 0, 0L);
- SendDlgItemMessage(hwnd, 4202, EM_SETHANDLE, f->hwnd, 0L); /* icon-change */
-
- len = kanjilen(Replacement);
- if (len > 0) {
- SendDlgItemMessage(hwnd, 4201, EM_REPLACESEL, 0, (LONG) Replacement);
- SendDlgItemMessage(hwnd, 4201, EM_SETSEL, len, MAKELONG(0, len - 1));
- }
-
- SetFocus(GetDlgItem(hwnd, 4201));
-
- CenterDialogBox(hwnd);
-
- return (TRUE);
- }
-
- case WM_PAINT: {
- HDC hdc;
- PAINTSTRUCT ps;
-
- hdc = BeginPaint(hwnd, &ps);
-
- DrawBoundingBox(hwnd, hdc, 4201);
-
- EndPaint(hwnd, &ps);
- return (TRUE);
- }
-
- case WM_COMMAND:
- switch (wParam) {
- case IDOK: {
- int i;
- UNIT far *up;
-
- /* Now replace the replacement string */
-
- up = (UNIT far *) SendDlgItemMessage(hwnd, 4201, EM_GETLINE, 0, 0L);
- for (i = 0; up[i].kanji; i++) Replacement[i] = up[i].kanji;
- Replacement[i] = 0;
- EndDialog(hwnd, TRUE);
- return (TRUE);
- }
-
- case IDCANCEL:
- EndDialog(hwnd, FALSE);
- return (TRUE);
- }
- break;
- }
- return (FALSE);
- }
-