442 lines
14 KiB
C
442 lines
14 KiB
C
|
/************************************************************/
|
|||
|
/* Windows Write, Copyright 1985-1992 Microsoft Corporation */
|
|||
|
/************************************************************/
|
|||
|
|
|||
|
/* trans4.c -- routines brought from trans2.c due to compiler stack overflow */
|
|||
|
|
|||
|
#define NOWINMESSAGES
|
|||
|
#define NOVIRTUALKEYCODES
|
|||
|
#define NOWINSTYLES
|
|||
|
#define NOCLIPBOARD
|
|||
|
#define NOGDICAPMASKS
|
|||
|
#define NOSYSMETRICS
|
|||
|
#define NOMENUS
|
|||
|
#define NOKEYSTATE
|
|||
|
#define NOGDI
|
|||
|
#define NORASTEROPS
|
|||
|
#define NOSYSCOMMANDS
|
|||
|
#define NOSHOWWINDOW
|
|||
|
#define NOCOLOR
|
|||
|
#define NOATOM
|
|||
|
#define NOBITMAP
|
|||
|
#define NOICON
|
|||
|
#define NOBRUSH
|
|||
|
#define NOCREATESTRUCT
|
|||
|
#define NOMB
|
|||
|
#define NOFONT
|
|||
|
#define NOMSG
|
|||
|
#define NOOPENFILE
|
|||
|
#define NOPEN
|
|||
|
#define NOPOINT
|
|||
|
#define NOREGION
|
|||
|
#define NOSCROLL
|
|||
|
#define NOSOUND
|
|||
|
#define NOWH
|
|||
|
#define NOWINOFFSETS
|
|||
|
#define NOWNDCLASS
|
|||
|
#define NOCOMM
|
|||
|
#include <windows.h>
|
|||
|
|
|||
|
#include "mw.h"
|
|||
|
#include "doslib.h"
|
|||
|
#include "propdefs.h"
|
|||
|
#define NOUAC
|
|||
|
#include "cmddefs.h"
|
|||
|
#include "docdefs.h"
|
|||
|
#include "filedefs.h"
|
|||
|
#include "fkpdefs.h"
|
|||
|
#include "editdefs.h"
|
|||
|
#include "printdef.h"
|
|||
|
#define NOKCCODES
|
|||
|
#include "ch.h"
|
|||
|
#define NOSTRUNDO
|
|||
|
#define NOSTRERRORS
|
|||
|
#include "str.h"
|
|||
|
#include "debug.h"
|
|||
|
#include "fontdefs.h"
|
|||
|
|
|||
|
|
|||
|
CHAR *PchGetPn();
|
|||
|
CHAR *PchFromFc();
|
|||
|
typePN PnAllocT2();
|
|||
|
struct PGTB **HpgtbGet();
|
|||
|
|
|||
|
|
|||
|
extern int vfnWriting;
|
|||
|
extern struct BPS *mpibpbps;
|
|||
|
extern typeTS tsMruBps;
|
|||
|
extern int vibpWriting;
|
|||
|
extern CHAR (**vhrgbSave)[];
|
|||
|
extern struct DOD (**hpdocdod)[];
|
|||
|
extern int docCur;
|
|||
|
extern int docMac;
|
|||
|
extern int docScrap;
|
|||
|
extern int docUndo;
|
|||
|
extern struct FCB (**hpfnfcb)[];
|
|||
|
extern int fnMac;
|
|||
|
extern int wwMac;
|
|||
|
extern int vfBuffersDirty;
|
|||
|
extern int vfDiskFull;
|
|||
|
extern int vfDiskError;
|
|||
|
extern typeCP vcpFetch;
|
|||
|
extern CHAR *vpchFetch;
|
|||
|
extern int vccpFetch;
|
|||
|
extern typeFC fcMacPapIns;
|
|||
|
extern typeFC fcMacChpIns;
|
|||
|
extern typeCP vcpLimParaCache;
|
|||
|
extern struct FKPD vfkpdCharIns;
|
|||
|
extern struct FKPD vfkpdParaIns;
|
|||
|
extern struct PAP vpapPrevIns;
|
|||
|
extern struct PAP vpapAbs;
|
|||
|
extern struct PAP *vppapNormal;
|
|||
|
extern struct CHP vchpNormal;
|
|||
|
extern struct CHP vchpInsert;
|
|||
|
extern struct CHP vchpFetch;
|
|||
|
extern unsigned cwHeapFree;
|
|||
|
extern struct FPRM fprmCache;
|
|||
|
|
|||
|
extern int ferror;
|
|||
|
extern CHAR szExtBackup[];
|
|||
|
extern CHAR (**hszTemp)[];
|
|||
|
|
|||
|
#ifdef INTL /* International version */
|
|||
|
|
|||
|
extern int vWordFmtMode; /* used during saves. If false, no conversion is
|
|||
|
done. True is convert to Word format,CVTFROMWORD
|
|||
|
is translate chars from Word character set at
|
|||
|
save */
|
|||
|
#endif /* International version */
|
|||
|
|
|||
|
|
|||
|
/*** WriteUnformatted - Write unformatted document to file
|
|||
|
*
|
|||
|
*
|
|||
|
*
|
|||
|
*/
|
|||
|
|
|||
|
|
|||
|
WriteUnformatted(fn, doc)
|
|||
|
int fn;
|
|||
|
int doc;
|
|||
|
{
|
|||
|
extern typeCP vcpLimParaCache;
|
|||
|
extern typeCP cpMinCur, cpMacCur;
|
|||
|
typeCP cpMinCurT = cpMinCur;
|
|||
|
typeCP cpMacCurT = cpMacCur;
|
|||
|
typeCP cpNow;
|
|||
|
typeCP cpLimPara;
|
|||
|
typeCP cpMac = (**hpdocdod) [doc].cpMac;
|
|||
|
|
|||
|
/* Expand range of interest to whole document (for CachePara) */
|
|||
|
|
|||
|
cpMinCur = cp0;
|
|||
|
cpMacCur = cpMac;
|
|||
|
|
|||
|
/* Loop on paras */
|
|||
|
|
|||
|
cpNow = cp0;
|
|||
|
for ( cpNow = cp0; cpNow < cpMac; cpNow = cpLimPara )
|
|||
|
{
|
|||
|
LRestart:
|
|||
|
CachePara( doc, cpNow );
|
|||
|
cpLimPara = vcpLimParaCache;
|
|||
|
if (vpapAbs.fGraphics)
|
|||
|
continue;
|
|||
|
|
|||
|
/* Now write out the para, a run at a time */
|
|||
|
|
|||
|
|
|||
|
while ((cpNow < cpLimPara && cpNow < cpMacCur)
|
|||
|
&& !(vfDiskFull || vfDiskError))
|
|||
|
{
|
|||
|
extern typeCP CpMin();
|
|||
|
extern int vccpFetch;
|
|||
|
int ccpAccept;
|
|||
|
CHAR bufT[cbSector + 1];
|
|||
|
CHAR *pch;
|
|||
|
|
|||
|
FetchCp( doc, cpNow, 0, fcmChars + fcmNoExpand );
|
|||
|
Assert (vccpFetch <= cbSector);
|
|||
|
#ifdef WINVER >= 0x300
|
|||
|
if (vccpFetch == 0)
|
|||
|
{
|
|||
|
/* In this case we've had an error with a "hole" in the
|
|||
|
the piece table due to hitting a mem-alloc error -- we
|
|||
|
won't ever advance cpNow! To get around this we bump
|
|||
|
cpNow to the cpMin of the next piece and continue by
|
|||
|
doing a CachePara on the next piece 3/14/90..pault */
|
|||
|
|
|||
|
struct PCTB *ppctb = *(**hpdocdod)[doc].hpctb;
|
|||
|
int ipcd = IpcdFromCp(ppctb, cpNow);
|
|||
|
struct PCD *ppcd = &ppctb->rgpcd[ipcd + 1]; /* NEXT piece */
|
|||
|
|
|||
|
cpNow = ppcd->cpMin;
|
|||
|
goto LRestart;
|
|||
|
}
|
|||
|
#endif
|
|||
|
ccpAccept = (int) CpMin( (typeCP)vccpFetch, (cpLimPara - cpNow));
|
|||
|
|
|||
|
#ifdef INTL /* International version */
|
|||
|
if (vWordFmtMode != TRUE) /* no character set conversion */
|
|||
|
#endif /* International version */
|
|||
|
|
|||
|
WriteRgch( fn, vpchFetch, ccpAccept );
|
|||
|
|
|||
|
#ifdef INTL /* International version */
|
|||
|
else /* convert to OEM set */
|
|||
|
{
|
|||
|
/* convert ANSI chars to OEM for Word format file */
|
|||
|
/* load chars into bufT and translate to OEM
|
|||
|
chars, and write out */
|
|||
|
pch = (CHAR *) bltbyte(vpchFetch, bufT,
|
|||
|
(int)ccpAccept);
|
|||
|
*pch = '\0';
|
|||
|
AnsiToOem((LPSTR)bufT, (LPSTR)bufT);
|
|||
|
WriteRgch(fn, bufT, (int)ccpAccept);
|
|||
|
}
|
|||
|
#endif /* International version */
|
|||
|
|
|||
|
cpNow += ccpAccept;
|
|||
|
}
|
|||
|
if ((vfDiskFull || vfDiskError))
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/* Restore cpMinCur, cpMacCur */
|
|||
|
|
|||
|
cpMinCur = cpMinCurT;
|
|||
|
cpMacCur = cpMacCurT;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*** PurgeTemps - Delete all temporary files not referenced in any doc
|
|||
|
*
|
|||
|
*/
|
|||
|
|
|||
|
PurgeTemps()
|
|||
|
{ /* Delete all temporary files not referenced in any doc */
|
|||
|
int fn;
|
|||
|
struct FCB *pfcb, *mpfnfcb;
|
|||
|
struct DOD *pdod;
|
|||
|
struct PCD *ppcd;
|
|||
|
int doc;
|
|||
|
|
|||
|
Assert(fnScratch == 0);
|
|||
|
FreezeHp();
|
|||
|
mpfnfcb = &(**hpfnfcb)[0];
|
|||
|
|
|||
|
#ifdef DFILE
|
|||
|
CommSz("PurgeTemps:\n\r");
|
|||
|
#endif
|
|||
|
|
|||
|
/* Prime the doc/piece table loop */
|
|||
|
/* Find the first valid doc (there is guaranteed to be one) */
|
|||
|
/* Set up doc, pdod, ppcd */
|
|||
|
for (doc = 0, pdod = &(**hpdocdod)[0]; pdod->hpctb == 0; doc++, pdod++)
|
|||
|
continue;
|
|||
|
ppcd = &(**pdod->hpctb).rgpcd[0];
|
|||
|
|
|||
|
/* Now go through the deletable files, looking for references */
|
|||
|
for (fn = fnScratch + 1, pfcb = &mpfnfcb[fnScratch + 1];
|
|||
|
fn < fnMac; fn++, pfcb++)
|
|||
|
{ /* For each file (don't bother with scratch file) */
|
|||
|
/* Fn must be valid, deletable, and not previously referenced */
|
|||
|
/* if (pfcb->rfn != rfnFree && pfcb->fDelete && !pfcb->fReferenced &&
|
|||
|
fn != fnPrint) */
|
|||
|
if (pfcb->rfn != rfnFree && pfcb->fDelete && !pfcb->fReferenced)
|
|||
|
{ /* For each deletable fn */
|
|||
|
int fnT;
|
|||
|
|
|||
|
for (;;)
|
|||
|
{ /* Until we determine there is or isn't a ref */
|
|||
|
if (doc >= docMac)
|
|||
|
goto OutOfDocs;
|
|||
|
while ((fnT = ppcd->fn) == fnNil)
|
|||
|
{ /* End of pctb */
|
|||
|
#ifdef CASHMERE
|
|||
|
struct SETB **hsetb = pdod->hsetb;
|
|||
|
if (hsetb != 0)
|
|||
|
{ /* Check section table. Doesn't need to be quite
|
|||
|
as smart as piece table checker; smaller. */
|
|||
|
int csed = (**hsetb).csed;
|
|||
|
struct SED *psed = &(**hsetb).rgsed[0];
|
|||
|
while (csed--)
|
|||
|
{
|
|||
|
fnT = psed->fn;
|
|||
|
if (fnT == fn) /* Referenced. */
|
|||
|
goto NextFn;
|
|||
|
if (fnT > fn) /* Future fn referenced */
|
|||
|
mpfnfcb[fnT].fReferenced = true;
|
|||
|
psed++;
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
while (++doc < docMac && (++pdod)->hpctb == 0)
|
|||
|
continue;
|
|||
|
if (doc >= docMac)
|
|||
|
{
|
|||
|
OutOfDocs: /* No references to this fn, delete it */
|
|||
|
MeltHp();
|
|||
|
#ifdef DFILE
|
|||
|
{
|
|||
|
char rgch[200];
|
|||
|
wsprintf(rgch," fn %d, %s \n\r", fn,(LPSTR)(**pfcb->hszFile));
|
|||
|
CommSz(rgch);
|
|||
|
}
|
|||
|
#endif
|
|||
|
FDeleteFn(fn); /* HEAP MOVEMENT */
|
|||
|
FreezeHp();
|
|||
|
|
|||
|
/* NOTE: Once we get here, there is no */
|
|||
|
/* further use of pdod or ppcd; we zip */
|
|||
|
/* through the remaining fn's and just */
|
|||
|
/* test fcb fields. Therefore, pdod */
|
|||
|
/* and ppcd are not updated although */
|
|||
|
/* there was (maybe) heap movement above */
|
|||
|
|
|||
|
mpfnfcb = &(**hpfnfcb)[0];
|
|||
|
pfcb = &mpfnfcb[fn];
|
|||
|
|
|||
|
goto NextFn;
|
|||
|
}
|
|||
|
ppcd = &(**pdod->hpctb).rgpcd[0];
|
|||
|
}
|
|||
|
if (fnT == fn) /* A reference to this fn */
|
|||
|
goto NextFn;
|
|||
|
if (fnT > fn) /* Ref to a future fn */
|
|||
|
mpfnfcb[fnT].fReferenced = true;
|
|||
|
++ppcd;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
pfcb->fReferenced = false;
|
|||
|
NextFn: ;
|
|||
|
}
|
|||
|
MeltHp();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#if WINVER >= 0x300
|
|||
|
/* We only use one document at a time, thus in general we won't have
|
|||
|
doc's referencing pieces from multiple fns (unless they've been
|
|||
|
pasted and reference docscrap or something).
|
|||
|
|
|||
|
In any case we want to free up these files esp. for network user
|
|||
|
convenience. The dilemma in particular is when someone's opened
|
|||
|
a file on the net and then does a File.New, File.SaveAs, or File.Open
|
|||
|
and is using another file -- we don't release the previous one so
|
|||
|
another user will get a sharing error even though it seems that file
|
|||
|
should be free!
|
|||
|
|
|||
|
Modeled after PurgeTemps() above ..pault 10/23/89 */
|
|||
|
|
|||
|
void FreeUnreferencedFns()
|
|||
|
{
|
|||
|
int fn;
|
|||
|
struct FCB *pfcb, *mpfnfcb;
|
|||
|
struct DOD *pdod;
|
|||
|
struct PCD *ppcd;
|
|||
|
int doc;
|
|||
|
|
|||
|
Assert(fnScratch == 0);
|
|||
|
FreezeHp();
|
|||
|
mpfnfcb = &(**hpfnfcb)[0];
|
|||
|
|
|||
|
/* Prime the doc/piece table loop */
|
|||
|
/* Find the first valid doc (there is guaranteed to be one) */
|
|||
|
/* Set up doc, pdod, ppcd */
|
|||
|
for (doc = 0, pdod = &(**hpdocdod)[0]; pdod->hpctb == 0; doc++, pdod++)
|
|||
|
continue;
|
|||
|
ppcd = &(**pdod->hpctb).rgpcd[0];
|
|||
|
#ifdef DFILE
|
|||
|
CommSz("FreeUnreferencedFns: \n\r");
|
|||
|
#endif
|
|||
|
|
|||
|
for (fn = fnScratch + 1, pfcb = &mpfnfcb[fnScratch + 1]; fn < fnMac; fn++, pfcb++)
|
|||
|
{ /* For each file (don't bother with scratch file) */
|
|||
|
|
|||
|
#ifdef DFILE
|
|||
|
{
|
|||
|
char rgch[200];
|
|||
|
wsprintf(rgch," fn %d, %s \trfnFree %d fRefd %d fDelete %d ",
|
|||
|
fn,(LPSTR)(**pfcb->hszFile),pfcb->rfn==rfnFree,pfcb->fReferenced,pfcb->fDelete);
|
|||
|
CommSz(rgch);
|
|||
|
}
|
|||
|
#endif
|
|||
|
/* For each unreferenced fn, we ask: is this file the current
|
|||
|
document being edited? If so then we definitely don't want
|
|||
|
to free up the file. However PREVIOUS documents that were
|
|||
|
being edited can now "be free". Temp files are not freed
|
|||
|
here because we want them to be remembered so they are deleted
|
|||
|
at the end of the Write session 2/1/90 ..pault */
|
|||
|
|
|||
|
if ((WCompSz(*(**hpdocdod)[ docCur ].hszFile,**pfcb->hszFile)==0)
|
|||
|
|| pfcb->fDelete)
|
|||
|
goto LRefd;
|
|||
|
else if (pfcb->rfn != rfnFree && !pfcb->fReferenced)
|
|||
|
{
|
|||
|
int fnT;
|
|||
|
|
|||
|
for (;;)
|
|||
|
{ /* Until we determine there is or isn't a ref */
|
|||
|
if (doc >= docMac)
|
|||
|
{
|
|||
|
goto OutOfDocs;
|
|||
|
}
|
|||
|
while ((fnT = ppcd->fn) == fnNil)
|
|||
|
{ /* End of pctb */
|
|||
|
while (++doc < docMac && (++pdod)->hpctb == 0)
|
|||
|
continue;
|
|||
|
if (doc >= docMac)
|
|||
|
{
|
|||
|
OutOfDocs: /* No references to this fn, delete it */
|
|||
|
|
|||
|
MeltHp();
|
|||
|
#ifdef DFILE
|
|||
|
CommSz(" FREEING!");
|
|||
|
#endif
|
|||
|
FreeFn(fn); /* HEAP MOVEMENT */
|
|||
|
FreezeHp();
|
|||
|
|
|||
|
/* NOTE: Once we get here, there is no */
|
|||
|
/* further use of pdod or ppcd; we zip */
|
|||
|
/* through the remaining fn's and just */
|
|||
|
/* test fcb fields. Therefore, pdod */
|
|||
|
/* and ppcd are not updated although */
|
|||
|
/* there was (maybe) heap movement above */
|
|||
|
|
|||
|
mpfnfcb = &(**hpfnfcb)[0];
|
|||
|
pfcb = &mpfnfcb[fn];
|
|||
|
|
|||
|
goto NextFn;
|
|||
|
}
|
|||
|
ppcd = &(**pdod->hpctb).rgpcd[0];
|
|||
|
}
|
|||
|
if (fnT == fn) /* A reference to this fn */
|
|||
|
{
|
|||
|
goto NextFn;
|
|||
|
}
|
|||
|
if (fnT > fn) /* Ref to a future fn */
|
|||
|
{
|
|||
|
mpfnfcb[fnT].fReferenced = true;
|
|||
|
}
|
|||
|
++ppcd;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
LRefd:
|
|||
|
pfcb->fReferenced = false;
|
|||
|
}
|
|||
|
NextFn: ;
|
|||
|
#ifdef DFILE
|
|||
|
CommSz("\n\r");
|
|||
|
#endif
|
|||
|
}
|
|||
|
MeltHp();
|
|||
|
}
|
|||
|
#endif /* WIN30 */
|
|||
|
|