📄 edstruct.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.20 01/31/02 */
/* */
/* */
/*******************************************************/
#include "setup.h"
#if EMACS_EDITOR && ! RUN_TIME
#define _EDSTRUCT_SOURCE_
#include "ed.h"
#include <stdarg.h>
/* ----------------------------
* Display management stuff
* ----------------------------
*/
typedef struct VIDEO {
short v_flag; /* Flags */
char v_text[1]; /* Screen data. */
} VIDEO;
#define VFCHG 0x0001 /* Changed. */
globle int mpresf = FALSE; /* TRUE if message in last line */
globle int sgarbf = TRUE; /* TRUE if screen is garbage */
static int vtrow = 0; /* Row location of SW cursor */
static int vtcol = 0; /* Column location of SW cursor */
static int ttrow = HUGE; /* Row location of HW cursor */
static int ttcol = HUGE; /* Column location of HW cursor */
static VIDEO **vscreen; /* Virtual screen. */
static VIDEO **pscreen; /* Physical screen. */
/* ----------------------------
* Line management stuff
* ----------------------------
*/
#define NBLOCK 16 /* Line block chunk size */
#define KBLOCK 256 /* Kill buffer block size */
static char *kbufp = NULL; /* Kill buffer data */
static int kused = 0; /* # of bytes used in KB */
static int ksize = 0; /* # of bytes allocated in KB */
static void int_to_ascii(char [],int,int);
/* ==========================================================================
* BUFFER MANAGEMENT FUNCTIONS
* ==========================================================================
*/
/*
* Some of the functions in this section are internal, and some are
* actually attached to user keys. Like everyone else, they set hints
* for the display system.
*/
/*
* Attach a buffer to a window. The
* values of dot and mark come from the buffer
* if the use count is 0. Otherwise, they come
* from some other window.
*/
#if IBM_TBC
#pragma argsused
#endif
globle int usebuffer(
void *theEnv,
int f,
int n)
{
register BUFFER *bp;
register WINDOW *wp;
register int s;
char bufn[NBUFN];
char prompt[NBUFN + 15];
sprintf(prompt,"Use buffer [%s]: ",lastbufn);
if ((s=mlreply(theEnv,prompt, bufn, NBUFN)) != TRUE) {
if (( s == FALSE) && (strlen(lastbufn) != 0))
strcpy(bufn, lastbufn);
else
return (s);
}
if ((bp=bfind(theEnv,bufn, TRUE, 0)) == NULL)
return (FALSE);
strcpy(lastbufn, curbp->b_bname); /* Save current bufname */
if (--curbp->b_nwnd == 0) { /* Last use. */
curbp->b_dotp = curwp->w_dotp;
curbp->b_doto = curwp->w_doto;
curbp->b_markp = curwp->w_markp;
curbp->b_marko = curwp->w_marko;
}
curbp = bp; /* Switch. */
curwp->w_bufp = bp;
curwp->w_linep = bp->b_linep; /* For macros, ignored. */
curwp->w_flag |= WFMODE|WFFORCE|WFHARD; /* Quite nasty. */
if (bp->b_nwnd++ == 0) { /* First use. */
curwp->w_dotp = bp->b_dotp;
curwp->w_doto = bp->b_doto;
curwp->w_markp = bp->b_markp;
curwp->w_marko = bp->b_marko;
return (TRUE);
}
wp = wheadp; /* Look for old. */
while (wp != NULL) {
if (wp!=curwp && wp->w_bufp==bp) {
curwp->w_dotp = wp->w_dotp;
curwp->w_doto = wp->w_doto;
curwp->w_markp = wp->w_markp;
curwp->w_marko = wp->w_marko;
break;
}
wp = wp->w_wndp;
}
return (TRUE);
}
/*
* Dispose of a buffer, by name.
* Ask for the name. Look it up (don't get too
* upset if it isn't there at all!). Get quite upset
* if the buffer is being displayed. Clear the buffer (ask
* if the buffer has been changed). Then free the header
* line and the buffer header. Bound to "C-X K".
*/
#if IBM_TBC
#pragma argsused
#endif
globle int killbuffer(
void *theEnv,
int f,
int n)
{
register BUFFER *bp;
register BUFFER *bp1;
register BUFFER *bp2;
register int s;
char bufn[NBUFN];
if ((s=mlreply(theEnv,"Kill buffer: ", bufn, NBUFN)) != TRUE)
return (s);
if ((bp=bfind(theEnv,bufn, FALSE, 0)) == NULL) /* Easy if unknown. */
return (TRUE);
if (bp->b_nwnd != 0) { /* Error if on screen. */
mlwrite("Buffer is being displayed");
return (FALSE);
}
if ((s=bclear(theEnv,bp)) != TRUE) /* Blow text away. */
return (s);
genfree(theEnv,(void *) bp->b_linep,(unsigned) (sizeof(LINE) + bp->b_linep->l_size));
bp1 = NULL; /* Find the header. */
bp2 = bheadp;
while (bp2 != bp) {
bp1 = bp2;
bp2 = bp2->b_bufp;
}
bp2 = bp2->b_bufp; /* Next one in chain. */
if (bp1 == NULL) /* Unlink it. */
bheadp = bp2;
else
bp1->b_bufp = bp2;
genfree(theEnv,(void *) bp, (unsigned) sizeof(BUFFER)); /* Release buffer block */
mlwrite("Buffer Killed!");
return (TRUE);
}
/*
* List all of the active
* buffers. First update the special
* buffer that holds the list. Next make
* sure at least 1 window is displaying the
* buffer list, splitting the screen if this
* is what it takes. Lastly, repaint all of
* the windows that are displaying the
* list. Bound to "C-X C-B".
*/
#if IBM_TBC
#pragma argsused
#endif
globle int listbuffers(
void *theEnv,
int f,
int n)
{
register WINDOW *wp;
register BUFFER *bp;
register int s;
if ((s=makelist(theEnv)) != TRUE)
return (s);
if (blistp->b_nwnd == 0) { /* Not on screen yet. */
if ((wp=wpopup(theEnv)) == NULL)
return (FALSE);
bp = wp->w_bufp;
if (--bp->b_nwnd == 0) {
bp->b_dotp = wp->w_dotp;
bp->b_doto = wp->w_doto;
bp->b_markp = wp->w_markp;
bp->b_marko = wp->w_marko;
}
wp->w_bufp = blistp;
++blistp->b_nwnd;
}
wp = wheadp;
while (wp != NULL) {
if (wp->w_bufp == blistp) {
wp->w_linep = lforw(blistp->b_linep);
wp->w_dotp = lforw(blistp->b_linep);
wp->w_doto = 0;
wp->w_markp = NULL;
wp->w_marko = 0;
wp->w_flag |= WFMODE|WFHARD;
}
wp = wp->w_wndp;
}
return (TRUE);
}
/*
* This routine rebuilds the
* text in the special secret buffer
* that holds the buffer list. It is called
* by the list buffers command. Return TRUE
* if everything works. Return FALSE if there
* is an error (if there is no memory).
*/
globle int makelist(
void *theEnv)
{
register char *cp1;
register char *cp2;
register int c;
register BUFFER *bp;
register LINE *lp;
register int nbytes;
register int s;
char b[6+1];
char line[128];
blistp->b_flag &= ~BFCHG; /* Don't complain! */
if ((s=bclear(theEnv,blistp)) != TRUE) /* Blow old text away */
return (s);
strcpy(blistp->b_fname, "");
if (addline(theEnv,blistp,"C Size Buffer File") == FALSE
|| addline(theEnv,blistp,"- ---- ------ ----") == FALSE)
return (FALSE);
bp = bheadp; /* For all buffers */
while (bp != NULL) {
if ((bp->b_flag&BFTEMP) != 0) { /* Skip magic ones. */
bp = bp->b_bufp;
continue;
}
cp1 = &line[0]; /* Start at left edge */
if ((bp->b_flag&BFCHG) != 0) /* "*" if changed */
*cp1++ = '*';
else
*cp1++ = ' ';
*cp1++ = ' '; /* Gap. */
nbytes = 0; /* Count bytes in buf. */
lp = lforw(bp->b_linep);
while (lp != bp->b_linep) {
nbytes += llength(lp)+1;
lp = lforw(lp);
}
int_to_ascii(b, 6, nbytes); /* 6 digit buffer size. */
cp2 = &b[0];
while ((c = *cp2++) != 0)
*cp1++ = (char) c;
*cp1++ = ' '; /* Gap. */
cp2 = &bp->b_bname[0]; /* Buffer name */
while ((c = *cp2++) != 0)
*cp1++ = (char) c;
cp2 = &bp->b_fname[0]; /* File name */
if (*cp2 != 0) {
while (cp1 < &line[1+1+6+1+NBUFN+1])
*cp1++ = ' ';
while ((c = *cp2++) != 0) {
if (cp1 < &line[128-1])
*cp1++ = (char) c;
}
}
*cp1 = 0; /* Add to the buffer. */
if (addline(theEnv,blistp,line) == FALSE)
return (FALSE);
bp = bp->b_bufp;
}
return (TRUE); /* All done */
}
/*
* The argument "text" points to
* a string. Append this line to the
* buffer. Handcraft the EOL
* on the end. Return TRUE if it worked and
* FALSE if you ran out of room.
*/
globle int addline(
void *theEnv,
BUFFER *bufferp,
char *text)
{
register LINE *lp;
register int i;
register int ntext;
ntext = strlen(text);
if ((lp=lalloc(theEnv,ntext)) == NULL)
return (FALSE);
for (i=0; i<ntext; ++i)
lputc(lp, i, text[i]);
bufferp->b_linep->l_bp->l_fp = lp; /* Hook onto the end */
lp->l_bp = bufferp->b_linep->l_bp;
bufferp->b_linep->l_bp = lp;
lp->l_fp = bufferp->b_linep;
if (bufferp->b_dotp == bufferp->b_linep) /* If "." is at the end */
bufferp->b_dotp = lp; /* move it to new line */
return (TRUE);
}
/*
* Look through the list of
* buffers. Return TRUE if there
* are any changed buffers. Buffers
* that hold magic internal stuff are
* not considered; who cares if the
* list of buffer names is hacked.
* Return FALSE if no buffers
* have been changed.
*/
globle int anycb()
{
register BUFFER *bp;
bp = bheadp;
while (bp != NULL) {
if ((bp->b_flag&BFTEMP)==0 && (bp->b_flag&BFCHG)!=0)
return (TRUE);
bp = bp->b_bufp;
}
return (FALSE);
}
/*
* Find a buffer, by name. Return a pointer
* to the BUFFER structure associated with it. If
* the named buffer is found, but is a TEMP buffer (like
* the buffer list) conplain. If the buffer is not found
* and the "cflag" is TRUE, create it. The "bflag" is
* the settings for the flags in in buffer.
*/
globle BUFFER *bfind(
void *theEnv,
char *bname,
int cflag,
int bflag)
{
register BUFFER *bp;
register LINE *lp;
bp = bheadp;
while (bp != NULL) {
if (strcmp(bname, bp->b_bname) == 0) {
if ((bp->b_flag&BFTEMP) != 0) {
mlwrite("Cannot select builtin buffer");
return (NULL);
}
return (bp);
}
bp = bp->b_bufp;
}
if (cflag != FALSE) {
if ((bp=(BUFFER *)genalloc(theEnv,(unsigned) sizeof(BUFFER))) == NULL)
return (NULL);
if ((lp=lalloc(theEnv,0)) == NULL) {
genfree(theEnv,(void *) bp,(unsigned) sizeof(BUFFER));
return (NULL);
}
bp->b_bufp = bheadp;
bheadp = bp;
bp->b_dotp = lp;
bp->b_doto = 0;
bp->b_markp = NULL;
bp->b_marko = 0;
bp->b_flag = (char) bflag;
bp->b_nwnd = 0;
bp->b_linep = lp;
strcpy(bp->b_fname, "");
strcpy(bp->b_bname, bname);
lp->l_fp = lp;
lp->l_bp = lp;
}
return (bp);
}
/*
* This routine blows away all of the text
* in a buffer. If the buffer is marked as changed
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -