home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD1.bin
/
gnu
/
src
/
baseline
/
jove-4.14.6.lha
/
jove-4.14.6
/
util.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-10
|
17KB
|
1,050 lines
/***************************************************************************
* This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
* is provided to you without charge, and with no warranty. You may give *
* away copies of JOVE, including sources, provided that this notice is *
* included in all the files. *
***************************************************************************/
#include "jove.h"
#include "ctype.h"
#include "termcap.h"
#include "disp.h"
#include "fp.h"
#include <signal.h>
#include <errno.h>
#ifdef MAC
# include "mac.h"
#else
# ifdef STDARGS
# include <stdarg.h>
# else
# include <varargs.h>
# endif
#endif
#ifdef MSDOS
#include <time.h>
#endif
#ifndef IBMPC
const
#endif
struct cmd *
FindCmd(proc)
register void (*proc) proto((void));
{
register const struct cmd *cp;
for (cp = commands; cp->Name; cp++)
if (cp->c_proc == proc)
return cp;
return NULL;
}
bool Interactive = NO; /* True when we invoke with the command handler? */
data_obj *LastCmd;
char *ProcFmt = ": %f ";
void
ExecCmd(cp)
register data_obj *cp;
{
LastCmd = cp;
if (cp->Type & MAJOR_MODE) {
SetMajor((cp->Type >> 8));
} else if (cp->Type & MINOR_MODE) {
TogMinor((cp->Type >> 8));
} else switch (cp->Type&TYPEMASK) {
case MACRO:
do_macro((struct macro *) cp);
break;
case FUNCTION:
{
register struct cmd *cmd = (struct cmd *) cp;
if (cmd->c_proc) {
if ((cmd->Type & MODIFIER) &&
(BufMinorMode(curbuf, ReadOnly))) {
rbell();
message("[Buffer is read-only]");
} else
(*cmd->c_proc)();
}
}
}
}
Line *
lastline(lp)
register Line *lp;
{
register Line *next;
while ((next = lp->l_next) != NULL)
lp = next;
return lp;
}
char key_strokes[100],
*keys_p = key_strokes;
void
pp_key_strokes(buffer, size)
char *buffer;
size_t size;
{
char *buf_end = buffer + size - 1,
*kp = key_strokes,
c;
*buffer = '\0';
while ((c = *kp++) != '\0') {
swritef(buffer, (size_t) (buf_end-buffer), "%p ", c);
buffer += strlen(buffer);
if (buffer >= buf_end)
break;
}
}
private int *slowp = NULL; /* for waitchar() */
private SIGRESULT
slowpoke(junk)
int junk;
{
int save_errno = errno; /* Subtle, but necessary! */
char buffer[100];
if (slowp)
*slowp = YES;
pp_key_strokes(buffer, sizeof (buffer));
f_mess(buffer);
errno = save_errno;
SIGRETURN;
}
#ifdef UNIX
# ifdef BSD4_2
# define N_SEC 1 /* will be precisely 1 second on 4.2 */
# else
# define N_SEC 2 /* but from 1 to 2 seconds otherwise */
# endif
#else /* !UNIX */
# define N_SEC 1
int in_macro();
#endif /* !UNIX */
int
waitchar(slow)
int *slow;
{
int c;
#ifdef UNIX
unsigned int old_time;
SIGRESULT (*oldproc) proto((int));
#else /* !UNIX */
long sw, time();
#endif /* !UNIX */
slowp = slow;
if (in_macro()) /* make macros faster ... */
return getch();
/* If slow is a valid pointer and it's value is yes, then
we know we have already been slow during this sequence,
so we just wait for the character and then echo it. */
if (slow != NULL && *slow == YES) {
c = getch();
slowpoke(0);
return c;
}
#ifdef UNIX
oldproc = signal(SIGALRM, slowpoke);
if ((old_time = alarm((unsigned) N_SEC)) == 0)
old_time = UpdFreq;
c = getch();
(void) alarm(old_time);
(void) signal(SIGALRM, oldproc);
if (slow != NULL && *slow == YES)
slowpoke(0);
return c;
#else /* !UNIX */
#ifdef MAC
Keyonly = YES;
if (charp() || in_macro()) {
c = getch(); /* to avoid flicker */
if (slow != NULL && *slow == YES)
slowpoke();
return c;
}
#endif
time(&sw);
sw += N_SEC;
while (time(NULL) <= sw)
if (charp() || in_macro())
return getch();
#ifdef MAC
menus_off();
#endif
slowpoke();
c = getch();
slowpoke();
return c;
#endif /* !UNIX */
}
char *
StrIndex(dir, buf, charpos, what)
int dir; /* FORWARD or BACKWARD */
register char *buf;
int charpos;
register int what;
{
register char *cp = &buf[charpos];
register int c;
if (dir > 0) {
while ((c = *cp++) != '\0')
if ((c == what) != '\0')
return (cp - 1);
} else {
while (cp >= buf && (c = *cp--)!='\0')
if (c == what)
return (cp + 1);
}
return NULL;
}
bool
blnkp(buf)
register char *buf;
{
register char c;
do ; while ((c = *buf++)!='\0' && (c == ' ' || c == '\t'));
return c == 0; /* It's zero if we got to the end of the Line */
}
bool
within_indent()
{
register char c;
register int i;
i = curchar;
do ; while (--i >= 0 && ((c = linebuf[i]) == ' ' || c == '\t'));
return i < 0; /* it's < 0 if we got to the beginning */
}
Line *
next_line(line, num)
register Line *line;
register int num;
{
if (num < 0)
return prev_line(line, -num);
if (line)
while (--num >= 0 && line->l_next != NULL)
line = line->l_next;
return line;
}
Line *
prev_line(line, num)
register Line *line;
register int num;
{
if (num < 0)
return next_line(line, -num);
if (line)
while (--num >= 0 && line->l_prev != NULL)
line = line->l_prev;
return line;
}
void
DotTo(line, col)
Line *line;
int col;
{
Bufpos bp;
bp.p_line = line;
bp.p_char = col;
SetDot(&bp);
}
/* If bp->p_line is != current line, then save current line. Then set dot
to bp->p_line, and if they weren't equal get that line into linebuf. */
void
SetDot(bp)
register Bufpos *bp;
{
register int notequal;
if (bp == NULL)
return;
notequal = bp->p_line != curline;
if (notequal)
lsave();
if (bp->p_line)
curline = bp->p_line;
if (notequal)
getDOT();
curchar = bp->p_char;
if (curchar > length(curline))
curchar = length(curline);
}
void
ToLast()
{
SetLine(curbuf->b_last);
Eol();
}
int MarkThresh = 22; /* average screen size ... */
static int line_diff;
int
LineDist(nextp, endp)
register Line *nextp,
*endp;
{
(void) inorder(nextp, 0, endp, 0);
return line_diff;
}
int
inorder(nextp, char1, endp, char2)
register Line *nextp,
*endp;
int char1,
char2;
{
register Line *prevp = nextp;
line_diff = 0;
if (nextp == endp)
return char1 < char2;
while (nextp && prevp) {
nextp = nextp->l_next;
prevp = prevp->l_prev;
line_diff += 1;
if (nextp == endp)
return TRUE;
if (prevp == endp)
return FALSE;
}
while (nextp!=NULL && nextp!=endp) {
nextp = nextp->l_next;
line_diff += 1;
}
while (prevp!=NULL && prevp!=endp) {
prevp = prevp->l_prev;
line_diff += 1;
}
/* nextp == prevp implies both are NULL: the lines are not ordered */
return nextp==prevp? -1 : nextp==endp;
}
void
PushPntp(line)
register Line *line;
{
if (LineDist(curline, line) >= MarkThresh)
set_mark();
}
void
ToFirst()
{
SetLine(curbuf->b_first);
}
int
length(line)
Line *line;
{
return strlen(lcontents(line));
}
void
to_word(dir)
register int dir;
{
register char c;
if (dir == FORWARD) {
while ((c = linebuf[curchar]) != '\0' && !jisword(c))
curchar += 1;
if (eolp()) {
if (curline->l_next == NULL)
return;
SetLine(curline->l_next);
to_word(dir);
return;
}
} else {
while (!bolp() && (c = linebuf[curchar - 1], !jisword(c)))
curchar -= 1;
if (bolp()) {
if (curline->l_prev == NULL)
return;
SetLine(curline->l_prev);
Eol();
to_word(dir);
}
}
}
/* Are there any modified buffers? Allp means include B_PROCESS
buffers in the check. */
bool
ModBufs(allp)
bool allp;
{
register Buffer *b;
for (b = world; b != NULL; b = b->b_next)
if (b->b_type != B_SCRATCH
&& (b->b_type == B_FILE || allp)
&& IsModified(b))
return YES;
return NO;
}
char *
filename(b)
register Buffer *b;
{
return b->b_fname ? pr_name(b->b_fname, YES) : "[No file]";
}
char *
itoa(num)
register int num;
{
static char line[15];
swritef(line, sizeof(line), "%d", num);
return line;
}
int
min(a, b)
register int a,
b;
{
return (a < b) ? a : b;
}
int
max(a, b)
register int a,
b;
{
return (a > b) ? a : b;
}
void
tiewind(w, bp)
register Window *w;
register Buffer *bp;
{
int not_tied = (w->w_bufp != bp);
UpdModLine = YES; /* kludge ... but speeds things up considerably */
w->w_line = bp->b_dot;
w->w_char = bp->b_char;
w->w_bufp = bp;
if (not_tied)
CalcWind(w); /* ah, this has been missing since the
beginning of time! */
}
char *
lcontents(line)
registe