source: trunk/dll/mle.c@ 1210

Last change on this file since 1210 was 1210, checked in by John Small, 17 years ago

Ticket 187: Move data declarations/definitions out of fm3dll.h

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 29.4 KB
RevLine 
[2]1
[123]2/***********************************************************************
3
4 $Id: mle.c 1210 2008-09-13 06:51:37Z jbs $
5
6 MLE text editor/viewer
7
8 Copyright (c) 1993-97 M. Kimes
[574]9 Copyright (c) 2004, 2007 Steven H.Levine
[123]10
[301]11 01 Aug 04 SHL Rework lstrip/rstrip usage
12 16 Apr 06 SHL MLEexportfile: rework to avoid wrap problems
[350]13 14 Jul 06 SHL Use Runtime_Error
[528]14 03 Nov 06 SHL Count thread usage
[574]15 22 Mar 07 GKY Use QWL_USER
[775]16 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
[793]17 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
[814]18 26 Aug 07 GKY DosSleep(1) in loops changed to (0)
[888]19 17 Dec 07 GKY Make WPURLDEFAULTSETTINGS the fall back for ftp/httprun
[985]20 29 Feb 08 GKY Refactor global command line variables to notebook.h
[1029]21 22 Jun 08 GKY Fixed memory buffer access after it had been freed
[1042]22 06 Jul 08 GKY Rework LoadThread logic with Steven's help
[123]23
24***********************************************************************/
25
[2]26#include <stdlib.h>
27#include <string.h>
28#include <ctype.h>
29#include <share.h>
[689]30#include <process.h> // _beginthread
[350]31
[907]32#define INCL_DOS
33#define INCL_WIN
34#define INCL_LONGLONG
35
[1185]36#include "fm3dll.h"
[1210]37#include "init.h" // Data declaration(s)
38#include "mainwnd.h" // Data declaration(s)
39#include "newview.h" // Data declarations
[2]40#include "fm3dlg.h"
41#include "mle.h"
42#include "fm3str.h"
[907]43#include "errutil.h" // Dos_Error...
44#include "strutil.h" // GetPString
[985]45#include "notebook.h" // httprun etc
[1161]46#include "autoview.h" // CreateHexDump
47#include "saveclip.h" // SaveToClip
[1185]48#include "common.h" // DecrThreadUsage, IncrThreadUsage
49#include "chklist.h" // PosOverOkay
50#include "valid.h" // TestBinary
51#include "strips.h" // bstrip
52#include "systemf.h" // runemf2
53#include "wrappers.h" // xfopen
54#include "misc.h" // PostMsg
[1029]55#include "fortify.h"
[2]56
[350]57static PSZ pszSrcFile = __FILE__;
58
[2]59#define FAKEROT 1
[578]60#define DOROT13(c) (!isalpha((c)))?(c):((((c) >= (char) 'A') && \
[2]61 ((c) <= (char) 'M')) || (((c) >= (char) 'a') && ((c) <= (char) 'm')))?((c) + (char) 0xd)\
62 :((((c) >= (char) 'N') && ((c) <= (char) 'Z')) || (((c) >= (char) 'n') && ((c) <= (char) 'z')))?\
[578]63 ((c) - (char) 0xd):(c)
64
65/*((FAKEROT==0)?(c):(FAKEROT==1)?(!isalpha((c)))?(c):((((c) >= (char) 'A') && \
66 ((c) <= (char) 'M')) || (((c) >= (char) 'a') && ((c) <= (char) 'm')))?((c) + (char) 0xd)\
67 :((((c) >= (char) 'N') && ((c) <= (char) 'Z')) || (((c) >= (char) 'n') && ((c) <= (char) 'z')))?\
[2]68 ((c) - (char) 0xd):(c):((c) >= (char) '!') ? ((((c) + (char) 47) > (char) '~') ? ((c) - (char) 47) :\
[578]69 ((c) + (char) 47)) : (c))*/
[2]70
[551]71LONG MLEgetlinetext(HWND h, LONG l, CHAR * buf, INT maxlen)
[301]72{
[2]73 /* get text of line l from MLE */
74
[551]75 IPT s, e;
[2]76
[551]77 s = MLEstartofline(h, l);
78 e = MLElinelenleft(h, s);
79 return MLEtextatpos(h, s, buf, min((INT) e, maxlen));
[2]80}
81
[551]82LONG MLEdeleteline(HWND h, LONG l)
[301]83{
[2]84 /* delete line l from MLE */
85
[551]86 IPT s, e;
[2]87
[551]88 s = MLEstartofline(h, l);
89 e = MLElinelenleft(h, s);
90 return MLEdelete(h, s, e);
[2]91}
92
[551]93LONG MLEdeletecurline(HWND h)
[301]94{
[2]95 /* delete current line from MLE */
96
97 LONG l;
98
99 l = MLEcurline(h);
[551]100 return MLEdeleteline(h, l);
[2]101}
102
[551]103LONG MLEdeletetoeol(HWND h)
[301]104{
[2]105 /* delete from cursor pos to end of line */
106
[551]107 IPT s, e;
[2]108
109 s = MLEcurpos(h);
110 e = MLEcurlenleft(h);
[551]111 return MLEdelete(h, s, e);
[2]112}
113
[551]114VOID MLEclearall(HWND h)
[301]115{
[2]116 /* remove all text from MLE */
117 LONG len;
118
119 len = MLEgetlen(h);
[551]120 if (len)
121 MLEdelete(h, 0, len);
[2]122}
123
[551]124LONG MLEtextatcursor(HWND h, CHAR * buffer, INT buflen)
[301]125{
[2]126 /* place up to buflen chars of text from cursor pos into buffer
127 * return # of chars imported
128 */
129
[551]130 IPT i;
[2]131
132 i = MLEcurpos(h);
[551]133 return MLEtextatpos(h, i, buffer, buflen);
[2]134}
135
[551]136LONG MLEtextatpos(HWND h, IPT i, CHAR * buffer, INT buflen)
[301]137{
[2]138 /* place up to buflen chars of text from pos i in buffer
139 * return # of chars imported
140 */
141
[551]142 WinSendMsg(h, MLM_SETIMPORTEXPORT, MPFROMP(buffer),
143 MPFROMLONG((LONG) buflen));
144 return (LONG) WinSendMsg(h, MLM_EXPORT,
145 MPFROMP(&i), MPFROMLONG((PLONG) & buflen));
[2]146}
147
[551]148LONG MLEsizeofsel(HWND h)
[301]149{
[2]150 /* return length of selected text */
151
[551]152 IPT cursor, anchor, test;
[2]153
154 cursor = MLEcurpos(h);
155 anchor = MLEancpos(h);
[551]156 test = min(cursor, anchor);
[2]157 /* MLE fakes us out; get real length in bytes */
[551]158 return (LONG) WinSendMsg(h, MLM_QUERYFORMATTEXTLENGTH,
159 MPFROMLONG(test),
160 MPFROMLONG((LONG) ((cursor < anchor) ?
161 (anchor - cursor) :
162 (cursor - anchor))));
[2]163}
164
[551]165VOID MLEinternet(HWND h, BOOL ftp)
[301]166{
[2]167 CHAR *temp = NULL;
[551]168 IPT ancpos, curpos, here;
169 LONG len, oldlen;
[350]170 APIRET rc;
[892]171 ULONG size;
[2]172
173 len = MLEsizeofsel(h);
[551]174 len = min(2048, len);
[2]175 oldlen = len;
[350]176 if (len) {
[2]177 len++;
[551]178 rc = DosAllocMem((PVOID) & temp, 4096,
179 PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE);
[350]180 if (rc || !temp)
[551]181 Dos_Error(MB_CANCEL, rc, h, pszSrcFile, __LINE__,
182 GetPString(IDS_OUTOFMEMORY));
[350]183 else {
[2]184 ancpos = MLEancpos(h);
185 curpos = MLEcurpos(h);
[551]186 here = min(curpos, ancpos);
187 WinSendMsg(h, MLM_SETIMPORTEXPORT, MPFROMP(temp), MPFROMLONG(len));
188 len = (LONG) WinSendMsg(h, MLM_EXPORT, MPFROMP(&here), MPFROMP(&len));
[350]189 if (len <= 1)
[551]190 Runtime_Error(pszSrcFile, __LINE__, "len <= 1");
[350]191 else {
[551]192 if (len > oldlen)
193 len--;
194 temp[len] = 0;
195 bstripcr(temp);
196 if (*temp) {
[892]197 if (ftp) {
198 if (fFtpRunWPSDefault) {
199 CHAR WPSDefaultFtpRun[CCHMAXPATH], WPSDefaultFtpRunDir[CCHMAXPATH];
200
201 size = sizeof(WPSDefaultFtpRun);
202 PrfQueryProfileData(HINI_USERPROFILE, "WPURLDEFAULTSETTINGS",
203 "DefaultBrowserExe", WPSDefaultFtpRun, &size);
204 size = sizeof(WPSDefaultFtpRunDir);
205 PrfQueryProfileData(HINI_USERPROFILE, "WPURLDEFAULTSETTINGS",
206 "DefaultWorkingDir", WPSDefaultFtpRunDir, &size);
207 runemf2(SEPARATE | WINDOWED,
208 h, pszSrcFile, __LINE__,
209 WPSDefaultFtpRunDir,
210 fLibPathStrictFtpRun ? "SET LIBPATHSTRICT=TRUE" : NULL,
211 "%s %s", WPSDefaultFtpRun, temp);
212 }
213 else
214 runemf2(SEPARATE | WINDOWED,
215 h, pszSrcFile, __LINE__,
216 ftprundir, NULL, "%s %s", ftprun, temp);
217 }
218 else
219 if (fHttpRunWPSDefault) {
220 CHAR WPSDefaultHttpRun[CCHMAXPATH], WPSDefaultHttpRunDir[CCHMAXPATH];
221
222 size = sizeof(WPSDefaultHttpRun);
223 PrfQueryProfileData(HINI_USERPROFILE, "WPURLDEFAULTSETTINGS",
224 "DefaultBrowserExe", WPSDefaultHttpRun, &size);
225 size = sizeof(WPSDefaultHttpRunDir);
226 PrfQueryProfileData(HINI_USERPROFILE, "WPURLDEFAULTSETTINGS",
227 "DefaultWorkingDir", WPSDefaultHttpRunDir, &size);
228 runemf2(SEPARATE | WINDOWED,
229 h, pszSrcFile, __LINE__,
230 WPSDefaultHttpRunDir,
231 fLibPathStrictHttpRun ? "SET LIBPATHSTRICT=TRUE" : NULL,
232 "%s %s", WPSDefaultHttpRun, temp);
233 }
234 else
235 runemf2(SEPARATE | WINDOWED,
236 h, pszSrcFile, __LINE__,
237 httprundir, NULL, "%s %s", httprun, temp);
[551]238 }
[2]239 }
240 DosFreeMem(temp);
241 }
242 }
243}
244
[551]245BOOL MLEdoblock(HWND h, INT action, CHAR * filename)
[301]246{
[2]247 /* perform action on text in selection */
248
249 register CHAR *p;
[551]250 CHAR *sel, *temp = NULL;
251 IPT ancpos, curpos, here;
252 LONG sellen, oldlen;
[350]253 APIRET rc;
[2]254
255 oldlen = MLEsizeofsel(h);
[551]256 if (!oldlen)
[2]257 return TRUE;
[551]258 sel = xmallocz((size_t) (oldlen + 2), pszSrcFile, __LINE__);
[350]259 if (!sel)
[2]260 return FALSE;
[551]261 rc = DosAllocMem((PVOID) & temp, 32768L,
262 PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE);
[350]263 if (rc || !temp) {
[551]264 Dos_Error(MB_CANCEL, rc, h, pszSrcFile, __LINE__,
265 GetPString(IDS_OUTOFMEMORY));
[1039]266 free(sel);
[1063]267# ifdef FORTIFY
268 Fortify_LeaveScope();
269# endif
[2]270 DosPostEventSem(CompactSem);
271 return FALSE;
272 }
273
274 ancpos = MLEancpos(h);
275 curpos = MLEcurpos(h);
[551]276 here = min(curpos, ancpos);
[2]277 p = sel;
278 MLEdisable(h);
[551]279 while (oldlen > 0) {
280 sellen = min(oldlen + 1, 32701);
281 WinSendMsg(h, MLM_SETIMPORTEXPORT, MPFROMP(temp), MPFROMLONG(sellen));
282 sellen =
283 (LONG) WinSendMsg(h, MLM_EXPORT, MPFROMP(&here), MPFROMP(&sellen));
[350]284 if (sellen < 1) {
285 Runtime_Error(pszSrcFile, __LINE__, "len < 1");
[1039]286 free(sel);
[1063]287# ifdef FORTIFY
288 Fortify_LeaveScope();
289# endif
[2]290 DosPostEventSem(CompactSem);
291 return FALSE;
292 }
[551]293 if (sellen > min(oldlen, 32700))
[2]294 sellen--;
[551]295 memcpy(p, temp, sellen);
[2]296 p += sellen;
297 oldlen -= sellen;
298 }
[551]299 switch (action) {
300 case APPENDCLIP:
301 SaveToClip(h, sel, TRUE);
302 DosFreeMem(temp);
[1039]303 free(sel);
[1063]304# ifdef FORTIFY
305 Fortify_LeaveScope();
306# endif
[551]307 MLEenable(h);
308 DosPostEventSem(CompactSem);
309 return TRUE;
310
311 case WRITE:
312 {
313 FILE *fp;
314
315 fp = fopen(filename, "a+");
316 if (!fp)
317 fp = xfopen(filename, "w", pszSrcFile, __LINE__);
318 if (fp) {
319 fseek(fp, 0L, SEEK_END);
320 fwrite(sel, 1, strlen(sel), fp);
321 fclose(fp);
322 }
323#ifdef __DEBUG_ALLOC__
324 _heap_check();
325#endif
[2]326 DosFreeMem(temp);
[1039]327 free(sel);
[1063]328# ifdef FORTIFY
329 Fortify_LeaveScope();
330# endif
[2]331 MLEenable(h);
332 DosPostEventSem(CompactSem);
333 return TRUE;
[551]334 }
[2]335
[551]336 case UPPERCASE:
337 p = sel;
338 while (*p) {
339 if (isalpha(*p))
340 *p = toupper(*p);
341 p++;
342 }
343 break;
[2]344
[551]345 case LOWERCASE:
346 p = sel;
347 while (*p) {
348 if (isalpha(*p))
349 *p = tolower(*p);
350 p++;
351 }
352 break;
[2]353
[551]354 case TOGGLECASE:
355 p = sel;
356 while (*p) {
357 if (isalpha(*p)) {
358 if (islower(*p))
359 *p = toupper(*p);
360 else
361 *p = tolower(*p);
[2]362 }
[551]363 p++;
364 }
365 break;
[2]366
[551]367 case ROT13:
368 p = sel;
369 while (*p) {
370 *p = DOROT13(*p); // fixme condition both true and false?
371 p++;
372 }
373 break;
[2]374
[551]375 case XOR:
376 p = sel;
377 while (*p) {
378 *p = (~*p);
379 p++;
380 }
381 break;
[2]382
[551]383 case FORMAT:
384 p = sel;
385 while (*p) {
386 if (*p == '\r') {
387 memmove(p, p + 1, strlen(p));
388 continue;
[2]389 }
[551]390 if (*p == '\n') {
391 *p = ' ';
392 continue;
[2]393 }
[551]394 p++;
395 }
396 break;
[2]397
[551]398 default: /* unknown action */
[2]399#ifdef __DEBUG_ALLOC__
400 _heap_check();
401#endif
[551]402 DosFreeMem(temp);
[1039]403 free(sel);
[1063]404# ifdef FORTIFY
405 Fortify_LeaveScope();
406# endif
[551]407 DosPostEventSem(CompactSem);
408 MLEenable(h);
409 return FALSE;
[2]410 }
411
412 /* replace selection with altered text */
413 p = sel;
[551]414 here = min(curpos, ancpos);
415 MLEclear(h); /* delete current selection */
416 sellen = oldlen = strlen(sel); /* actual number of bytes */
417 while (oldlen > 0) {
418 sellen = min(oldlen, 32700);
419 memcpy(temp, p, sellen);
420 WinSendMsg(h, MLM_SETIMPORTEXPORT, MPFROMP(temp), MPFROMLONG(sellen));
421 sellen = (LONG) WinSendMsg(h,
422 MLM_IMPORT,
423 MPFROMP(&here), MPFROMLONG(sellen));
[350]424 if (!sellen) {
425 Runtime_Error(pszSrcFile, __LINE__, "sellen 0");
[2]426 break;
427 }
428 p += sellen;
429 oldlen -= sellen;
[551]430 if (oldlen && *p == '\n' /* && *(p - 1) == '\r' */ )
[2]431 p--;
[551]432 } // while
433 WinSendMsg(h, MLM_SETSEL, MPFROMLONG(ancpos), MPFROMLONG(curpos));
[2]434 MLEenable(h);
435#ifdef __DEBUG_ALLOC__
[551]436 _heap_check();
[2]437#endif
438 DosFreeMem(temp);
[1039]439 free(sel);
[1029]440# ifdef FORTIFY
441 Fortify_LeaveScope();
[1063]442# endif
[2]443 DosPostEventSem(CompactSem);
444 return TRUE;
445}
446
[551]447BOOL MLEquotepara(HWND h, CHAR * initials, BOOL fQuoteOld)
[301]448{
[2]449 LONG num;
[551]450 CHAR lineend[2], line[8], *p;
[2]451
[551]452 if (!initials || !*initials)
[2]453 initials = " > ";
454 num = MLEcurline(h);
[551]455 while (MLElinelen(h, num) < 3L && MLEnumlines(h) >= num)
[2]456 num++;
[551]457 while (MLElinelen(h, num) > 2L && MLEnumlines(h) >= num) {
458 memset(line, 0, 8);
459 MLEgetlinetext(h, num, line, 7L);
[2]460 line[7] = 0;
[551]461 if ((p = strchr(line, '>')) == NULL) {
462 MLEsetcurpos(h, MLEstartofline(h, num));
463 MLEinsert(h, initials);
464 MLEsetcurpos(h, (MLEstartofline(h, num) + MLElinelen(h, num)) - 1L);
465 MLEtextatcursor(h, lineend, 2L);
466 if (*lineend != '\r' && *lineend != '\n')
467 MLEinsert(h, "\n");
[2]468 }
[551]469 else if (fQuoteOld) {
470 while (isspace(line[strlen(line) - 1]))
471 line[strlen(line) - 1] = 0;
472 MLEsetcurpos(h, MLEstartofline(h, num) + (p - line));
473 MLEinsert(h, ">");
[2]474 }
475 num++;
476 }
[551]477 MLEsetcurpos(h, MLEstartofline(h, num));
[2]478 return TRUE;
479}
480
[551]481BOOL MLEAutoLoad(HWND h, CHAR * filename)
[301]482{
[2]483 XMLEWNDPTR *vw;
484
[574]485 vw = (XMLEWNDPTR *) WinQueryWindowPtr(WinQueryWindow(h, QW_PARENT), QWL_USER);
[551]486 if (vw && vw->size != sizeof(XMLEWNDPTR))
[2]487 vw = NULL;
[551]488 if (TestBinary(filename)) {
489 if (vw)
[2]490 vw->hex = 1;
[551]491 return MLEHexLoad(h, filename);
[2]492 }
[551]493 if (vw)
[2]494 vw->hex = 2;
[551]495 return MLEloadfile(h, filename);
[2]496}
497
[551]498BOOL MLEHexLoad(HWND h, CHAR * filename)
[301]499{
[2]500 /* insert a file into the current position in the MLE */
501
[551]502 HAB hab;
503 CHAR *buffer = NULL, *hexbuff = NULL;
[841]504 IPT iptOffset = -1;
505 ULONG numread, howmuch, numimport, action, len, left = 0;
[551]506 BOOL ret = TRUE, first = TRUE;
507 CHAR titletext[512];
508 HWND grandpa;
[2]509 XMLEWNDPTR *vw;
[551]510 HFILE handle;
511 APIRET rc;
[2]512
513 *titletext = 0;
514 hab = WinQueryAnchorBlock(h);
[574]515 vw = (XMLEWNDPTR *) WinQueryWindowPtr(WinQueryWindow(h, QW_PARENT), QWL_USER);
[551]516 if (vw && vw->size != sizeof(XMLEWNDPTR))
[2]517 vw = NULL;
518 grandpa = GrandparentOf(h);
519 *titletext = 0;
[551]520 WinQueryWindowText(grandpa, 512, titletext);
[844]521 rc = DosOpen(filename, &handle, &action, 0, 0,
522 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
523 OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NOINHERIT |
524 OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYNONE |
525 OPEN_ACCESS_READONLY, 0);
[350]526 if (rc) {
527 ret = FALSE;
528 }
529 else {
[841]530 DosChgFilePtr(handle, 0, FILE_END, &len);
531 DosChgFilePtr(handle, 0, FILE_BEGIN, &action);
[350]532 if (len) {
[841]533 rc = DosAllocMem((PVOID) & hexbuff, 50001,
[551]534 PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE);
[350]535 if (rc || !hexbuff) {
[551]536 Dos_Error(MB_CANCEL, rc, h, pszSrcFile, __LINE__,
537 GetPString(IDS_OUTOFMEMORY));
538 ret = FALSE;
[350]539 }
540 else {
[551]541 buffer = xmalloc(10000, pszSrcFile, __LINE__);
542 if (!buffer)
543 ret = FALSE;
[350]544 else {
[551]545 MLEclearall(h);
546 WinSendMsg(h, MLM_SETIMPORTEXPORT, MPFROMP(hexbuff),
547 MPFROMLONG(50000L));
548 if (!DosRead(handle, buffer, min(10000, len), &numread) && numread) {
[2]549
[551]550 CHAR s[81];
[2]551
[551]552 MLEsetwrap(h, FALSE);
553 WinSetSysValue(HWND_DESKTOP, SV_INSERTMODE, FALSE);
554 *hexbuff = 0;
555 numimport = CreateHexDump(buffer,
556 numread, hexbuff, 50000, left, TRUE);
557 while (len && numimport) { /* import entire file */
558 left += numread;
559 len -= numread;
560 if (!WinIsWindow(hab, h) || (vw && vw->killme))
561 break;
562 howmuch = (INT) WinSendMsg(h,
563 MLM_IMPORT,
564 MPFROMP(&iptOffset),
565 MPFROMLONG(numimport));
566 if (first && len) {
567 MLEdisable(h);
568 WinEnableWindowUpdate(h, FALSE);
569 first = FALSE;
570 }
[2]571// fprintf(stderr,"%d bytes of %d imported\n",howmuch,numimport);
[551]572 if (howmuch < 1) {
573 numimport = 0;
574 break;
575 }
576 while (howmuch < numimport) {
577 numimport -= howmuch;
578 memmove(hexbuff, hexbuff + howmuch, numimport);
[814]579 DosSleep(0); //26 Aug 07 GKY 1
[551]580 if (!WinIsWindow(hab, h) || (vw && vw->killme))
581 break;
582 howmuch = (INT) WinSendMsg(h,
583 MLM_IMPORT,
584 MPFROMP(&iptOffset),
585 MPFROMLONG((LONG) numimport));
586 if (howmuch < 1)
587 break;
588 }
589 if (DosRead(handle, buffer, min(10000, len), &numread)
590 || !numread) {
591 numimport = 0;
592 break;
593 }
594 *hexbuff = 0;
595 numimport =
596 CreateHexDump(buffer, numread, hexbuff, 50000, left, TRUE);
597 if (numimport < 1 || !WinIsWindow(hab, h) || (vw && vw->killme)) {
598 numimport = 0;
599 break;
600 }
601 sprintf(s, GetPString(IDS_LOADINGMLETEXT), len);
602 WinSetWindowText(grandpa, s);
603 }
[771]604 DosSleep(1);
[551]605 }
606 else
607 ret = FALSE;
[1039]608 free(buffer);
[1063]609# ifdef FORTIFY
610 Fortify_LeaveScope();
611# endif
[551]612 }
613 DosFreeMem(hexbuff);
[2]614 }
615 }
[551]616 if (WinIsWindow(hab, h))
617 WinSetWindowText(grandpa, titletext);
[2]618 DosClose(handle);
619 }
[551]620 if (!first) {
621 WinEnableWindowUpdate(h, TRUE);
[2]622 MLEenable(h);
623 }
[551]624 MLEsetchanged(h, FALSE);
[2]625 return ret;
626}
627
[350]628//== MLEinsertfile() insert a file into the current position in the MLE ==
629
[551]630BOOL MLEinsertfile(HWND h, CHAR * filename)
[301]631{
[2]632
[551]633 HAB hab;
[2]634 FILE *fp;
[551]635 CHAR *buffer = NULL;
636 INT len;
637 IPT iptOffset = -1L;
638 INT numread, howmuch, tempnum, x;
639 BOOL ret = TRUE, first = TRUE, once = FALSE, dont = FALSE;
640 CHAR titletext[512];
641 HWND grandpa;
[2]642 XMLEWNDPTR *vw;
643 APIRET rc;
644
645 *titletext = 0;
646 hab = WinQueryAnchorBlock(h);
[574]647 vw = (XMLEWNDPTR *) WinQueryWindowPtr(WinQueryWindow(h, QW_PARENT), QWL_USER);
[551]648 if (vw && vw->size != sizeof(XMLEWNDPTR))
[2]649 vw = NULL;
650 grandpa = GrandparentOf(h);
651 *titletext = 0;
[551]652 WinQueryWindowText(grandpa, 512, titletext);
653 fp = _fsopen(filename, "r", SH_DENYNO);
[350]654 if (!fp)
655 ret = FALSE;
656 else {
[551]657 setvbuf(fp, NULL, _IONBF, 0);
658 fseek(fp, 0L, SEEK_END);
659 len = (INT) ftell(fp);
660 fseek(fp, 0L, SEEK_SET);
661 if (len && len != -1) {
662 rc = DosAllocMem((PVOID) & buffer,
663 50000L, PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE);
[350]664 if (rc || !buffer) {
[551]665 Dos_Error(MB_CANCEL, rc, h, pszSrcFile, __LINE__,
666 GetPString(IDS_OUTOFMEMORY));
667 ret = FALSE;
[350]668 }
669 else {
[551]670 WinSendMsg(h,
671 MLM_SETIMPORTEXPORT, MPFROMP(buffer), MPFROMLONG(50000L));
672 numread = fread(buffer, 1, min(50000, len), fp);
673 if (numread < 1)
674 ret = FALSE;
675 while (len && numread > 0) { /* here we go... */
[2]676
[551]677 CHAR s[81];
[2]678
[551]679 while (numread > 0) { /* import entire file */
680 if (!WinIsWindow(hab, h) || (vw && vw->killme))
681 break;
682 if (strlen(buffer) < numread) {
683 if (!once && !dont)
684 rc = saymsg(MB_YESNOCANCEL,
685 HWND_DESKTOP,
686 GetPString(IDS_WARNINGTEXT),
687 GetPString(IDS_TEXTNULSTEXT));
688 else if (once)
689 rc = MBID_YES;
690 else if (dont)
691 rc = MBID_NO;
692 if (rc == MBID_YES) {
693 once = FALSE;
694 for (x = 0; x < numread; x++) {
695 if (!buffer[x])
696 buffer[x] = ' ';
697 }
698 }
699 else if (rc == MBID_CANCEL) {
700 len = 0;
701 numread = 0;
702 saymsg(MB_ENTER,
703 HWND_DESKTOP,
704 GetPString(IDS_OBEYTEXT),
705 GetPString(IDS_LOADCANCELLEDTEXT));
706 break;
707 }
708 else if (rc == MBID_NO)
709 dont = TRUE;
710 }
711 howmuch = (INT) WinSendMsg(h,
712 MLM_IMPORT,
713 MPFROMP(&iptOffset),
714 MPFROMLONG((LONG) numread));
715 if (first && !feof(fp)) {
716 MLEdisable(h);
717 WinEnableWindowUpdate(h, FALSE);
718 first = FALSE;
719 }
[2]720// fprintf(stderr,"%d bytes of %d imported\n",howmuch,numread);
[551]721 if (howmuch < 1) {
722 numread = 0;
723 break;
724 }
725 len -= howmuch;
726 if (howmuch < numread) {
727 numread -= howmuch;
728 memmove(buffer, buffer + howmuch, numread);
729 if (numread && len) {
730 tempnum = numread;
731 numread = fread(buffer + tempnum,
732 1, min(50000 - tempnum, len), fp);
733 if (numread > 1)
734 numread += tempnum;
735 else
736 numread = tempnum;
737 }
[814]738 DosSleep(0); //26 Aug 07 GKY 1
[551]739 }
740 else
741 numread = fread(buffer, 1, min(50000, len), fp);
742 if (numread < 1 || !WinIsWindow(hab, h) || (vw && vw->killme)) {
743 numread = 0;
744 break;
745 }
746 sprintf(s, GetPString(IDS_LOADINGMLETEXT), len);
747 WinSetWindowText(grandpa, s);
748 }
[814]749 DosSleep(0); //26 Aug 07 GKY 1
[551]750 }
751 DosFreeMem(buffer);
[2]752 }
753 }
[551]754 if (WinIsWindow(hab, h))
755 WinSetWindowText(grandpa, titletext);
[2]756 fclose(fp);
757 }
[551]758 if (!first) {
759 WinEnableWindowUpdate(h, TRUE);
[2]760 MLEenable(h);
761 }
762 return ret;
763}
764
[551]765typedef struct
766{
[2]767 USHORT size;
768 USHORT hex;
[551]769 HWND h;
770 CHAR filename[CCHMAXPATH];
771 HWND hwndReport;
772 HWND msg;
773}
774BKGLOAD;
[2]775
[551]776VOID LoadThread(VOID * arg)
[301]777{
[2]778 BKGLOAD *bkg;
[551]779 BOOL fSuccess;
780 HAB thab;
781 HMQ thmq;
[2]782
783 DosError(FERR_DISABLEHARDERR);
784
[1042]785# ifdef FORTIFY
786 Fortify_EnterScope();
[1063]787# endif
[1042]788
[551]789 bkg = (BKGLOAD *) arg;
790 if (bkg) {
[2]791 thab = WinInitialize(0);
[551]792 if (thab) {
793 thmq = WinCreateMsgQueue(thab, 0);
794 if (thmq) {
795 WinCancelShutdown(thmq, TRUE);
796 IncrThreadUsage();
797 priority_normal();
798 if (bkg->hex == 1)
799 fSuccess = MLEHexLoad(bkg->h, bkg->filename);
800 else if (bkg->hex == 2)
801 fSuccess = MLEloadfile(bkg->h, bkg->filename);
802 else
803 fSuccess = MLEAutoLoad(bkg->h, bkg->filename);
804 priority_bumped();
805 if (bkg->hwndReport && WinIsWindow(thab, bkg->hwndReport))
806 PostMsg(bkg->hwndReport, bkg->msg, MPFROMLONG(fSuccess),
807 MPFROMP(bkg->filename));
[2]808#ifdef __DEBUG_ALLOC__
[551]809 _heap_check();
[2]810#endif
[551]811 WinDestroyMsgQueue(thmq);
[2]812 }
[1039]813 else
814 PostMsg(bkg->hwndReport, bkg->msg, MPVOID, MPVOID);
[528]815 DecrThreadUsage();
[2]816 WinTerminate(thab);
817 }
[1039]818 else {
[1042]819 // fixme to be gone? - can not PostMsg without HAB
[1029]820 PostMsg(bkg->hwndReport, bkg->msg, MPVOID, MPVOID);
[1042]821 }
822 free(bkg);
823 } // if bkg
[1029]824# ifdef FORTIFY
825 Fortify_LeaveScope();
[1063]826# endif
[1042]827 _endthread();
[2]828}
829
[551]830INT MLEbackgroundload(HWND hwndReport, ULONG msg, HWND h, CHAR * filename,
831 INT hex)
[350]832{
833 /* load a file into the MLE in the background (via a separate thread)
834 * return _beginthread status
835 */
[2]836
837 BKGLOAD *bkg;
[350]838 INT rc;
[2]839
[551]840 bkg = xmallocz(sizeof(BKGLOAD), pszSrcFile, __LINE__);
[350]841 if (!bkg)
842 return -1;
843 bkg->size = sizeof(BKGLOAD);
[551]844 bkg->hex = (USHORT) hex;
[350]845 bkg->hwndReport = hwndReport;
846 bkg->msg = msg;
847 bkg->h = h;
[551]848 strcpy(bkg->filename, filename);
849 rc = _beginthread(LoadThread, NULL, 65536, bkg);
[350]850 if (rc == -1)
[551]851 Runtime_Error(pszSrcFile, __LINE__,
852 GetPString(IDS_COULDNTSTARTTHREADTEXT));
[350]853 return rc;
[2]854}
855
[551]856BOOL MLEloadfile(HWND h, CHAR * filename)
[301]857{
[2]858 /* load a file into the MLE, getting rid of whatever was already
859 * there. Note this returns without erasing existing text if the
860 * file to load does not exist
861 */
862
[843]863 FILESTATUS3 fsa;
[551]864 BOOL ret;
[2]865
[843]866 if (!DosQueryPathInfo(filename, FIL_STANDARD, &fsa, sizeof(fsa)) &&
867 ~fsa.attrFile & FILE_DIRECTORY) {
[2]868 MLEclearall(h);
[551]869 ret = MLEinsertfile(h, filename);
870 MLEsetchanged(h, FALSE);
[2]871 return ret;
872 }
873 return FALSE;
874}
875
[551]876BOOL MLEexportfile(HWND h, CHAR * filename, INT tabspaces,
877 BOOL striptraillines, BOOL striptrailspaces)
[301]878{
[2]879 /* save the MLE contents as a file. Format the output so that
880 * the file is CR/LF terminated as presented in the MLE.
881 */
882
[301]883 FILE *fp = NULL;
884 CHAR *buffer = NULL;
885 CHAR *p;
886 BOOL ok = TRUE;
[551]887 INT blanklines = 0;
[301]888 BOOL fWrap = MLEgetwrap(h);
[350]889 APIRET rc;
[2]890
[301]891 // saymsg(MB_ENTER,h,DEBUG_STRING,"len = %ld",MLEgetlen(h));
[551]892 if (!MLEgetlen(h)) /* nothing to save; forget it */
[2]893 return TRUE;
894
[551]895 MLEsetwrap(h, FALSE); // Need wrap off to export MLFIE_NOTRANS
[301]896
[551]897 if (striptraillines) {
[2]898
899 register LONG x;
[551]900 LONG numlines;
[2]901
902 numlines = MLEnumlines(h);
[551]903 for (x = numlines; x; x--) {
904 if (MLElinelen(h, x - 1L) < 2)
905 MLEdeleteline(h, x - 1L);
[2]906 else
[551]907 break;
[2]908 }
[551]909 if (!MLEgetlen(h)) {
[301]910 /* nothing to save; forget it */
911 MLEsetwrap(h, fWrap); // Restore
[2]912 return TRUE;
[301]913 }
[2]914 }
915
[551]916 rc = DosAllocMem((PVOID) & buffer, 4096L,
917 PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE);
[350]918 if (rc || !buffer) {
[551]919 Dos_Error(MB_CANCEL, rc, h, pszSrcFile, __LINE__,
920 GetPString(IDS_OUTOFMEMORY));
[350]921 ok = FALSE;
922 }
[551]923 else {
924 fp = fopen(filename, "a+");
[350]925 if (!fp)
[551]926 fp = xfopen(filename, "w", pszSrcFile, __LINE__);
[350]927 if (!fp)
928 ok = FALSE;
929 else {
[551]930 LONG numlines, ret, len, wl, temp;
931 IPT s;
[2]932
[551]933 fseek(fp, 0L, SEEK_END);
[2]934 numlines = MLEnumlines(h);
935
[551]936 WinSendMsg(h, MLM_SETIMPORTEXPORT, MPFROMP(buffer), MPFROMLONG(4095L));
937 for (temp = 0; temp < numlines; temp++) {
938 s = MLEstartofline(h, temp);
939 wl = len = (LONG) MLElinelenleft(h, s);
940 ret = (LONG) WinSendMsg(h, MLM_EXPORT, MPFROMP(&s), MPFROMP(&len));
941 if (ret < 0)
942 break;
943 wl = min(wl, ret);
944 buffer[wl] = 0;
945 if (*buffer) {
946 p = buffer + strlen(buffer) - 1;
947 while (p >= buffer && (*p == '\n' || *p == '\r')) {
948 *p = 0;
949 p--;
950 }
951 }
952 if (tabspaces) {
953 p = buffer;
954 while (*p) {
955 if (*p == '\t') {
956 *p = ' ';
957 memmove((p + tabspaces) - 1, p, strlen(p) + 1);
958 memset(p, ' ', tabspaces);
959 }
960 p++;
961 }
962 }
963 if (striptrailspaces && *buffer) {
964 p = buffer + strlen(buffer) - 1;
965 while (p >= buffer && (*p == ' ' || *p == '\t')) {
966 *p = 0;
967 p--;
968 }
969 }
970 if (striptraillines) {
971 if (!*buffer) {
972 blanklines++;
973 continue;
974 }
975 else {
976 while (blanklines) {
977 fwrite("\n", 1, 1, fp);
978 blanklines--;
979 }
980 }
981 }
982 strcat(buffer, "\n");
983 // buffer = translate_out(buffer,4095,h,filename);
984 if (fwrite(buffer, 1, strlen(buffer), fp) < 1) {
985 saymsg(MB_ENTER,
986 h, GetPString(IDS_ARGHTEXT), GetPString(IDS_WRITEERRORTEXT));
987 break;
988 }
989 } // for lines
[2]990 }
991 }
[301]992
[551]993 MLEsetwrap(h, fWrap); // Restore
[301]994
995 if (fp)
996 fclose(fp);
997 if (buffer)
998 DosFreeMem(buffer);
999
1000 return ok;
[2]1001}
1002
[551]1003MRESULT EXPENTRY SandRDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
[301]1004{
[2]1005 /* initiate search(/replace)s in edit mode */
1006
1007 SRCHPTR *vw;
1008
[551]1009 if (msg != WM_INITDLG)
[574]1010 vw = (SRCHPTR *) WinQueryWindowPtr(hwnd, QWL_USER);
[2]1011 else
1012 vw = NULL;
1013
[551]1014 switch (msg) {
1015 case WM_INITDLG:
1016 vw = (SRCHPTR *) mp2;
1017 if (!vw) {
1018 WinDismissDlg(hwnd, 0);
[2]1019 break;
[551]1020 }
[574]1021 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) mp2);
[551]1022 WinSendDlgItemMsg(hwnd, SRCH_SEARCH, EM_SETTEXTLIMIT,
1023 MPFROM2SHORT(256, 0), MPVOID);
1024 WinSendDlgItemMsg(hwnd, SRCH_REPLACE, EM_SETTEXTLIMIT,
1025 MPFROM2SHORT(256, 0), MPVOID);
1026 if (*vw->search)
1027 WinSetDlgItemText(hwnd, SRCH_SEARCH, vw->search);
1028 if (!MLEgetreadonly(vw->hwndmle)) {
1029 if (*vw->replace)
1030 WinSetDlgItemText(hwnd, SRCH_REPLACE, vw->replace);
1031 WinSendDlgItemMsg(hwnd, SRCH_SANDR, BM_SETCHECK,
1032 MPFROM2SHORT(vw->sandr, 0), MPVOID);
1033 WinSendDlgItemMsg(hwnd, SRCH_RALL, BM_SETCHECK,
1034 MPFROM2SHORT(vw->rall, 0), MPVOID);
1035 }
1036 else {
1037 WinEnableWindow(WinWindowFromID(hwnd, SRCH_SANDR), FALSE);
1038 WinEnableWindow(WinWindowFromID(hwnd, SRCH_RALL), FALSE);
1039 WinEnableWindow(WinWindowFromID(hwnd, SRCH_REPLACE), FALSE);
1040 WinShowWindow(WinWindowFromID(hwnd, SRCH_REPLACE), FALSE);
1041 *vw->replace = 0;
1042 vw->sandr = FALSE;
1043 vw->rall = FALSE;
1044 }
1045 memset(&vw->se, 0, sizeof(MLE_SEARCHDATA));
1046 vw->se.cb = sizeof(MLE_SEARCHDATA);
1047 vw->se.pchFind = (PCHAR) vw->search;
1048 vw->se.cchFind = (SHORT) strlen(vw->search);
1049 vw->se.pchReplace = (PCHAR) vw->replace;
1050 vw->se.cchReplace = (SHORT) strlen(vw->replace);
1051 vw->se.iptStart = MLEcurpos(vw->hwndmle);
1052 vw->se.iptStop = -1L;
1053 vw->se.cchFound = 0;
1054 PosOverOkay(hwnd);
1055 break;
[2]1056
[551]1057 case WM_CONTROL:
1058 return 0;
[2]1059
[551]1060 case WM_COMMAND:
1061 switch (SHORT1FROMMP(mp1)) {
1062 case IDM_HELP:
1063 saymsg(MB_ENTER | MB_ICONASTERISK,
1064 hwnd,
1065 NullStr,
1066 GetPString(IDS_ENTERSEARCHSTRINGTEXT),
1067 (MLEgetreadonly(vw->hwndmle)) ?
1068 "." : GetPString(IDS_REPLACESTRINGTEXT));
1069 break;
[2]1070
[551]1071 case DID_CANCEL:
1072 WinDismissDlg(hwnd, 0);
1073 break;
[2]1074
[551]1075 case DID_OK:
1076 WinShowWindow(hwnd, FALSE);
1077 {
1078 CHAR temp[257];
1079 APIRET ret;
[2]1080
[551]1081 if ((USHORT) WinSendDlgItemMsg(hwnd, SRCH_SANDR, BM_QUERYCHECK,
1082 MPVOID, MPVOID))
1083 vw->sandr = TRUE;
1084 else
1085 vw->sandr = FALSE;
1086 if ((USHORT) WinSendDlgItemMsg(hwnd, SRCH_RALL, BM_QUERYCHECK,
1087 MPVOID, MPVOID))
1088 vw->rall = TRUE;
1089 else
1090 vw->rall = FALSE;
1091 *vw->replace = 0;
1092 WinQueryDlgItemText(hwnd, SRCH_REPLACE, 256, vw->replace);
1093 vw->se.cchReplace = (SHORT) strlen(vw->replace);
1094 WinQueryDlgItemText(hwnd, SRCH_SEARCH, 256, temp);
1095 if (*temp) {
1096 strcpy(vw->search, temp);
1097 vw->se.cchFind = (SHORT) strlen(vw->search);
1098 if (!WinSendMsg(vw->hwndmle, MLM_SEARCH,
1099 MPFROMLONG(MLFSEARCH_SELECTMATCH |
1100 (MLFSEARCH_CASESENSITIVE *
1101 (vw->fInsensitive ==
1102 FALSE)) | (MLFSEARCH_CHANGEALL *
1103 (vw->rall != 0))),
1104 MPFROMP(&vw->se))) {
1105 saymsg(MB_ENTER | MB_ICONASTERISK, hwnd, NullStr,
1106 GetPString(IDS_STRINGNOTFOUNDTEXT), vw->search);
1107 WinDismissDlg(hwnd, 0);
1108 break;
1109 }
1110 else if (vw->sandr && !vw->rall) {
1111 ret = saymsg(MB_YESNOCANCEL,
1112 hwnd,
1113 NullStr,
1114 GetPString(IDS_CONFIRMREPLACETEXT), vw->replace);
1115 if (ret == MBID_YES)
1116 MLEinsert(vw->hwndmle, vw->replace);
1117 else if (ret == MBID_CANCEL) {
1118 WinDismissDlg(hwnd, 0);
1119 break;
1120 }
1121 WinDismissDlg(hwnd, 1);
1122 break;
1123 }
1124 }
1125 WinDismissDlg(hwnd, 0);
[2]1126 }
[551]1127 break;
1128 }
1129 return 0;
[2]1130
[551]1131 case WM_CLOSE:
1132 break;
[2]1133 }
1134
[551]1135 return WinDefDlgProc(hwnd, msg, mp1, mp2);
[2]1136}
1137
[551]1138BOOL MLEfindfirst(HWND hwnd, SRCHPTR * vw)
[301]1139{
[551]1140 if (MLEsizeofsel(vw->hwndmle) < 256L) {
1141 MLEgetseltext(vw->hwndmle, vw->search);
[2]1142 vw->search[255] = 0;
1143 }
[551]1144 if (WinDlgBox(HWND_DESKTOP, hwnd, SandRDlgProc, FM3ModHandle,
1145 SRCH_FRAME, MPFROMP(vw)) && *vw->search)
[2]1146 return TRUE;
1147 return FALSE;
1148}
1149
[551]1150INT MLEfindnext(HWND hwnd, SRCHPTR * vw)
[301]1151{
[551]1152 if (!*vw->search)
[2]1153 return -1;
1154 else {
1155 vw->se.iptStart++;
[551]1156 if (!WinSendMsg(vw->hwndmle, MLM_SEARCH,
1157 MPFROMLONG(MLFSEARCH_SELECTMATCH |
1158 (MLFSEARCH_CASESENSITIVE *
1159 (vw->fInsensitive ==
1160 FALSE)) | (MLFSEARCH_CHANGEALL *
1161 (vw->rall))), MPFROMP(&vw->se)))
1162 saymsg(MB_ENTER | MB_ICONASTERISK, hwnd, NullStr,
1163 GetPString(IDS_STRINGNOTFOUNDTEXT), vw->search);
1164 else if (vw->sandr && !vw->rall) {
[2]1165
1166 APIRET ret;
1167
1168 ret = saymsg(MB_YESNOCANCEL,
[551]1169 hwnd,
1170 NullStr, GetPString(IDS_CONFIRMREPLACETEXT), vw->replace);
1171 if (ret == MBID_YES)
1172 MLEinsert(vw->hwndmle, vw->replace);
1173 if (ret != MBID_CANCEL)
1174 return 1;
[2]1175 }
1176 }
1177 return 0;
1178}
[793]1179
1180#pragma alloc_text(FMMLE,MLEgetlinetext,MLEdeleteline,MLEdeletecurline,MLEdeletetoeol)
1181#pragma alloc_text(FMMLE,MLEclearall,MLEtextatcursor,MLEtextatpos,MLEsizeofsel)
1182#pragma alloc_text(FMMLE3,MLEdoblock,MLEquotepara,MLEinternet)
1183#pragma alloc_text(FMMLE4,MLEAutoLoad,MLEHexLoad,MLEinsertfile,LoadThread,MLEbackgroundload)
1184#pragma alloc_text(FMMLE5,MLEloadfile,MLEexportfile)
1185#pragma alloc_text(FMMLE3,MLEfindfirst,MLEfindnext,SandRDlgProc)
Note: See TracBrowser for help on using the repository browser.