Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

470 lines
14 KiB

/*** pick.c - pick a piece of text and put it into the put buffer
*
* Copyright <C> 1988, Microsoft Corporation
*
* Revision History:
* 26-Nov-1991 mz Strip off near/far
*
*************************************************************************/
#include "mep.h"
#define DEBFLAG PICK
flagType
zpick (
CMDDATA argData,
ARG * pArg,
flagType fMeta
) {
buffer pbuf;
/* LINEARG illegal */
/* BOXARG illegal */
switch (pArg->argType) {
case NOARG:
pick (0, pArg->arg.noarg.y, 0, pArg->arg.noarg.y, LINEARG);
return TRUE;
case TEXTARG:
if (pFilePick != pFileHead) {
DelFile (pFilePick, TRUE);
}
strcpy ((char *) pbuf, pArg->arg.textarg.pText);
PutLine ((LINE)0, pbuf, pFilePick);
kindpick = BOXARG;
return TRUE;
/* NULLARG is converted into TEXTARG */
case LINEARG:
pick (0, pArg->arg.linearg.yStart,
0, pArg->arg.linearg.yEnd, LINEARG);
return TRUE;
case BOXARG:
pick (pArg->arg.boxarg.xLeft, pArg->arg.boxarg.yTop,
pArg->arg.boxarg.xRight, pArg->arg.boxarg.yBottom, BOXARG);
return TRUE;
case STREAMARG:
pick (pArg->arg.streamarg.xStart, pArg->arg.streamarg.yStart,
pArg->arg.streamarg.xEnd, pArg->arg.streamarg.yEnd, STREAMARG);
return TRUE;
}
return FALSE;
argData; fMeta;
}
void
pick (
COL xstart,
LINE ystart,
COL xend,
LINE yend,
int kind
)
{
if (pFilePick != pFileHead) {
DelFile (pFilePick, TRUE);
}
kindpick = kind;
switch (kind) {
case LINEARG:
CopyLine (pFileHead, pFilePick, ystart, yend, (LINE)0);
break;
case BOXARG:
CopyBox (pFileHead, pFilePick, xstart, ystart, xend, yend, (COL)0, (LINE)0);
break;
case STREAMARG:
CopyStream (pFileHead, pFilePick, xstart, ystart, xend, yend, (COL)0, (LINE)0);
break;
}
}
flagType
put (
CMDDATA argData,
ARG *pArg,
flagType fMeta
)
{
flagType fTmp = FALSE;
int i;
buffer putbuf;
pathbuf filebuf;
FILEHANDLE fh;
PFILE pFileTmp;
char *pBuf;
switch (pArg->argType) {
case BOXARG:
case LINEARG:
case STREAMARG:
delarg (pArg);
break;
case TEXTARG:
strcpy ((char *) buf, pArg->arg.textarg.pText);
DelFile (pFilePick, TRUE);
if (pArg->arg.textarg.cArg > 1) {
pBuf = whiteskip (buf);
if (*pBuf == '!') {
findpath ("$TMP:z.$", filebuf, TRUE);
fTmp = TRUE;
sprintf (putbuf, "%s >%s", pBuf+1, filebuf);
zspawnp (putbuf, TRUE);
pBuf = filebuf;
}
if (*pBuf != '<') {
CanonFilename (pBuf, putbuf);
} else {
strcpy (putbuf, pBuf);
}
//
// If we find the file in the existing file history, read it in, if not already
// in, and just to a copy operation on the desired text.
//
if ((pFileTmp = FileNameToHandle (putbuf, pBuf)) != NULL) {
if (!TESTFLAG (FLAGS (pFileTmp), REAL)) {
if (!FileRead(pFileTmp->pName,pFileTmp, FALSE)) {
printerror ("Cannot read %s", pFileTmp->pName);
return FALSE;
}
}
CopyLine (pFileTmp, pFilePick, (LINE)0, pFileTmp->cLines-1, (LINE)0);
} else {
if ((fh = MepFOpen(putbuf, ACCESSMODE_READ, SHAREMODE_RW, FALSE)) == NULL) {
printerror ("%s does not exist", pBuf);
return FALSE;
}
readlines (pFilePick, fh);
MepFClose (fh);
}
if (fTmp) {
_unlink (filebuf);
}
kindpick = LINEARG;
} else {
PutLine ((LINE)0, buf, pFilePick);
kindpick = BOXARG;
}
break;
}
switch (kindpick) {
case LINEARG:
CopyLine (pFilePick, pFileHead, (LINE)0, pFilePick->cLines-1, YCUR (pInsCur));
break;
case BOXARG:
i = LineLength ((LINE)0, pFilePick);
CopyBox (pFilePick, pFileHead, 0, (LINE)0, i-1, pFilePick->cLines-1, XCUR (pInsCur), YCUR (pInsCur));
break;
case STREAMARG:
i = LineLength (pFilePick->cLines-1, pFilePick);
CopyStream (pFilePick, pFileHead, 0, (LINE)0, i, pFilePick->cLines-1, XCUR (pInsCur), YCUR (pInsCur));
break;
}
return TRUE;
argData; fMeta;
}
/*** CopyLine - copy lines between files
*
* If the source file is NULL, then we insert blank lines.
*
* Input:
* pFileSrc = source file handle
* pFileDst = destination file handle
* yStart = first line to be copied
* yEnd = last line to be copied
* yDst = location of destination of copy
*
*************************************************************************/
void
CopyLine (
PFILE pFileSrc,
PFILE pFileDst,
LINE yStart,
LINE yEnd,
LINE yDst
)
{
linebuf L_buf;
struct lineAttr * rgla = (struct lineAttr *)ZEROMALLOC (sizeof(linebuf)/sizeof(char) * sizeof(struct lineAttr));
if (pFileSrc != pFileDst) {
if (yStart <= yEnd) {
InsLine (TRUE, yDst, yEnd - yStart + 1, pFileDst);
if (pFileSrc != NULL) {
MarkCopyLine (pFileSrc, pFileDst, yStart, yEnd, yDst);
while (yStart <= yEnd) {
gettextline (TRUE, yStart++, L_buf, pFileSrc, ' ');
puttextline (TRUE, TRUE, yDst++, L_buf, pFileDst);
if (getcolorline (TRUE, yStart-1, rgla, pFileSrc)) {
putcolorline (TRUE, yDst-1, rgla, pFileDst);
}
}
}
}
}
FREE (rgla);
}
/*** CopyBox - copy a box from one place to another
*
* If the source file is NULL, then we insert blank space. We copy the box
* defined by the LOGICAL box xLeft-xRight and yTop-yBottom inclusive.
*
* Input:
* pFileSrc = source file handle
* pFileDst = destination file handle
* xLeft = column location of beginning of copy
* yTop = line location of beginning of copy
* xRight = column location of end of copy
* yBottom = line location of end of copy
* xDst = column location of destination of copy
* yDst = line location of destination of copy
*
*************************************************************************/
void
CopyBox (
PFILE pFileSrc,
PFILE pFileDst,
COL xLeft,
LINE yTop,
COL xRight,
LINE yBottom,
COL xDst,
LINE yDst
)
{
int cbDst; /* count of bytes in destination*/
int cbMove; /* count of bytes to move around*/
linebuf dstbuf; /* buffer for result */
char *pDst; /* physical pointer to dest */
char *pSrcLeft; /* physical pointer to src left */
char *pSrcRight; /* physical pointer to src right+1*/
linebuf L_srcbuf; /* buffer for source line */
struct lineAttr rgla[sizeof(linebuf)];
flagType fColor;
/*
* Do not allow overlapped copies.
*/
if ((pFileSrc == pFileDst)
&& (( fInRange ((LINE)xLeft, (LINE)xDst, (LINE)xRight)
&& fInRange (yTop, yDst, yBottom))
|| ( fInRange ((LINE)xLeft, (LINE)(xDst + xRight - xLeft), (LINE)xRight)
&& fInRange (yTop, yDst + yBottom - yTop, yBottom))
)
) {
return;
}
/*
* If valid left and right coordinates for box, then for each line...
*/
if (xLeft <= xRight) {
/*
* Let the Marker update any affected marks.
*/
MarkCopyBox (pFileSrc, pFileDst, xLeft, yTop, xRight, yBottom, xDst, yDst);
while (yTop <= yBottom) {
if (!pFileSrc) {
//
// File is not a file, just insert spaces.
//
if (!fInsSpace (xDst, yDst, xRight - xLeft + 1, pFileDst, dstbuf)) {
LengthCheck (yDst, 0, NULL);
}
pDst = pLog (dstbuf, xDst, TRUE);
} else {
//
// When source IS a file, we:
// - get both source and destination lines
// - ensure that the source line is detabbed (only way to ensure proper
// alignment in the copy.
// - get phsical pointers to right and left of source.
// - get phsical pointer to destination
// - get length of physical move and current destination
// - physical length check the potential destination result
// - open up a hole in the destination line for the source
// - copy the source range into the destination
// - perform logical length check.
//
fInsSpace (xRight+1, yTop, 0, pFileSrc, fRealTabs ? dstbuf : L_srcbuf);
if (fRealTabs) {
Untab (fileTab, dstbuf, strlen(dstbuf), L_srcbuf, ' ');
}
fInsSpace (xDst, yDst, 0, pFileDst, dstbuf);
pSrcLeft = pLog (L_srcbuf, xLeft, TRUE);
pSrcRight = pLog (L_srcbuf, xRight, TRUE) + 1;
pDst = pLog (dstbuf, xDst, TRUE);
cbMove = (int)(pSrcRight - pSrcLeft);
cbDst = strlen (dstbuf);
if (cbDst + cbMove > sizeof(linebuf)) {
LengthCheck (yDst, 0, NULL);
} else {
memmove (pDst + cbMove, pDst, strlen(dstbuf) - (int)(pDst - dstbuf) + 1);
memmove (pDst, pSrcLeft, cbMove);
if (cbLog(dstbuf) > sizeof(linebuf)) {
LengthCheck (yDst, 0, NULL);
*pLog (dstbuf, sizeof(linebuf) - 1, TRUE) = 0;
}
}
}
if (fColor = GetColor (yDst, rgla, pFileDst)) {
if (pFileSrc) {
CopyColor (pFileSrc, pFileDst, yTop, xLeft, cbMove, yDst, xDst);
} else {
ShiftColor (rgla, (int)(pDst - dstbuf), xRight - xLeft + 1);
ColorToLog (rgla, dstbuf);
}
}
PutLine (yDst, dstbuf, pFileDst);
if (fColor) {
PutColor (yDst, rgla, pFileDst);
}
yDst++;
yTop++;
}
}
}
/*** CopyStream - copy a stream of text (including end-of-lines)
*
* If source file is NULL, then we insert blank space. We copy starting at
* xStart/yStart and copy through to the character before xEnd/yEnd. This
* means that to copy line Y INCLUDING the line separator, we specify
* (xStart,yStart) = (0,Y) and (xEnd,yEnd) = (0, Y+1)
*
* Input:
* pFileSrc = source file handle
* pFileDst = destination file handle
* xStart = column location of beginning of copy
* yStart = line location of beginning of copy
* xEnd = column location of end of copy
* yEnd = line location of end of copy
* xDst = column location of destination of copy
* yDst = line location of destination of copy
*
*************************************************************************/
void
CopyStream (
PFILE pFileSrc,
PFILE pFileDst,
COL xStart,
LINE yStart,
COL xEnd,
LINE yEnd,
COL xDst,
LINE yDst
)
{
linebuf dstbuf; /* buffer for result */
char *pDst;
linebuf L_srcbuf; /* buffer for source line */
LINE yDstLast;
/*
* validate copy...must be different files, and coordinates must make sense.
*/
if (!(pFileSrc != pFileDst &&
(yStart < yEnd || (yStart == yEnd && xStart < xEnd)))) {
return;
}
/*
* Special case a single-line stream as a box copy
*/
if (yStart == yEnd) {
CopyBox (pFileSrc, pFileDst, xStart, yStart, xEnd-1, yEnd, xDst, yDst);
return;
}
/*
* Valid stream copy. First, copy the intermediate lines.
*/
CopyLine (pFileSrc, pFileDst, yStart+1, yEnd, yDst+1);
/*
* Form last line of destination stream. Copy last part of dest line onto
* last part of last source line. Make sure that each copy of the
* source/dest is correct length
*/
fInsSpace (xDst, yDst, 0, pFileDst, dstbuf); /* dddddeeeeee */
if (pFileSrc != NULL) {
fInsSpace (xEnd, yEnd, 0, pFileSrc, L_srcbuf);/* AAAABBBBB */
} else {
memset ((char *) L_srcbuf, ' ', xEnd);
}
pDst = pLog (dstbuf,xDst, TRUE);
yDstLast = yDst + yEnd - yStart;
LengthCheck (yDstLast, xEnd, pDst);
strcpy ( pLog(L_srcbuf,xEnd,TRUE), pDst); /* AAAAeeeeee */
PutLine (yDstLast, L_srcbuf, pFileDst);
/*
* Form first line of destination stream. Copy last part of first source
* line onto last part of dest line
*/
if (pFileSrc != NULL) {
fInsSpace (xStart, yStart, 0, pFileSrc, L_srcbuf);/* CCCCCDDDDD*/
LengthCheck (yDst, xDst, L_srcbuf + xStart);
strcpy (pDst, pLog(L_srcbuf,xStart,TRUE)); /* dddddDDDDD*/
} else {
*pDst = 0;
}
PutLine (yDst, dstbuf, pFileDst);
/*
* To update marks, we first adjust any marks at yDst, then add new
* marks from the src.
*/
MarkCopyBox (pFileDst, pFileDst, xDst, yDst, sizeof(linebuf), yDst, xEnd-1, yDstLast);
MarkCopyBox (pFileSrc, pFileDst, 0, yEnd, xEnd, yEnd, 0, yDstLast);
MarkCopyBox (pFileSrc, pFileDst, xStart, yStart, sizeof(linebuf), yStart, xDst, yDst);
}