Added source code
This commit is contained in:
@@ -0,0 +1,469 @@
|
||||
#if !defined(lint) && !defined(DOS)
|
||||
static char rcsid[] = "$Id: random.c 13654 2004-05-07 21:43:40Z jpf $";
|
||||
#endif
|
||||
/*
|
||||
* Program: Random routines
|
||||
*
|
||||
*
|
||||
* Michael Seibel
|
||||
* Networks and Distributed Computing
|
||||
* Computing and Communications
|
||||
* University of Washington
|
||||
* Administration Builiding, AG-44
|
||||
* Seattle, Washington, 98195, USA
|
||||
* Internet: mikes@cac.washington.edu
|
||||
*
|
||||
* Please address all bugs and comments to "pine-bugs@cac.washington.edu"
|
||||
*
|
||||
*
|
||||
* Pine and Pico are registered trademarks of the University of Washington.
|
||||
* No commercial use of these trademarks may be made without prior written
|
||||
* permission of the University of Washington.
|
||||
*
|
||||
* Pine, Pico, and Pilot software and its included text are Copyright
|
||||
* 1989-2004 by the University of Washington.
|
||||
*
|
||||
* The full text of our legal notices is contained in the file called
|
||||
* CPYRIGHT, included with this distribution.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* This file contains the command processing functions for a number of random
|
||||
* commands. There is no functional grouping here, for sure.
|
||||
*/
|
||||
|
||||
#include "headers.h"
|
||||
|
||||
#ifdef ANSI
|
||||
int getccol(int);
|
||||
#else
|
||||
int getccol();
|
||||
#endif
|
||||
|
||||
int tabsize; /* Tab size (0: use real tabs) */
|
||||
|
||||
|
||||
/*
|
||||
* Display the current position of the cursor, in origin 1 X-Y coordinates,
|
||||
* the character that is under the cursor (in octal), and the fraction of the
|
||||
* text that is before the cursor. The displayed column is not the current
|
||||
* column, but the column that would be used on an infinite width display.
|
||||
* Normally this is bound to "C-X =".
|
||||
*/
|
||||
showcpos(f, n)
|
||||
int f, n;
|
||||
{
|
||||
register LINE *clp;
|
||||
register long nch;
|
||||
register int cbo;
|
||||
register long nbc;
|
||||
register int lines;
|
||||
register int thisline;
|
||||
char buffer[80];
|
||||
|
||||
clp = lforw(curbp->b_linep); /* Grovel the data. */
|
||||
cbo = 0;
|
||||
nch = 0L;
|
||||
lines = 0;
|
||||
for (;;) {
|
||||
if (clp==curwp->w_dotp && cbo==curwp->w_doto) {
|
||||
thisline = lines;
|
||||
nbc = nch;
|
||||
}
|
||||
if (cbo == llength(clp)) {
|
||||
if (clp == curbp->b_linep)
|
||||
break;
|
||||
clp = lforw(clp);
|
||||
cbo = 0;
|
||||
lines++;
|
||||
} else
|
||||
++cbo;
|
||||
++nch;
|
||||
}
|
||||
|
||||
sprintf(buffer,"line %d of %d (%d%%%%), character %ld of %ld (%d%%%%)",
|
||||
thisline+1, lines+1, (int)((100L*(thisline+1))/(lines+1)),
|
||||
nbc, nch, (nch) ? (int)((100L*nbc)/nch) : 0);
|
||||
|
||||
emlwrite(buffer, NULL);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return current column. Stop at first non-blank given TRUE argument.
|
||||
*/
|
||||
getccol(bflg)
|
||||
int bflg;
|
||||
{
|
||||
register int c, i, col;
|
||||
|
||||
col = 0;
|
||||
for (i=0; i<curwp->w_doto; ++i) {
|
||||
c = lgetc(curwp->w_dotp, i).c;
|
||||
if (c!=' ' && c!='\t' && bflg)
|
||||
break;
|
||||
|
||||
if (c == '\t')
|
||||
col |= 0x07;
|
||||
else if (c<0x20 || c==0x7F)
|
||||
++col;
|
||||
|
||||
++col;
|
||||
}
|
||||
|
||||
return(col);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Set tab size if given non-default argument (n <> 1). Otherwise, insert a
|
||||
* tab into file. If given argument, n, of zero, change to true tabs.
|
||||
* If n > 1, simulate tab stop every n-characters using spaces. This has to be
|
||||
* done in this slightly funny way because the tab (in ASCII) has been turned
|
||||
* into "C-I" (in 10 bit code) already. Bound to "C-I".
|
||||
*/
|
||||
tab(f, n)
|
||||
int f, n;
|
||||
{
|
||||
if (n < 0)
|
||||
return (FALSE);
|
||||
|
||||
if (n == 0 || n > 1) {
|
||||
tabsize = n;
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
if (! tabsize)
|
||||
return(linsert(1, '\t'));
|
||||
|
||||
return(linsert(tabsize - (getccol(FALSE) % tabsize), ' '));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Insert a newline. Bound to "C-M".
|
||||
*/
|
||||
newline(f, n)
|
||||
int f, n;
|
||||
{
|
||||
register int s;
|
||||
|
||||
if (curbp->b_mode&MDVIEW) /* don't allow this command if */
|
||||
return(rdonly()); /* we are in read only mode */
|
||||
|
||||
if (n < 0)
|
||||
return (FALSE);
|
||||
|
||||
if(optimize && (curwp->w_dotp != curwp->w_bufp->b_linep)){
|
||||
int l;
|
||||
|
||||
if(worthit(&l)){
|
||||
if(curwp->w_doto != 0)
|
||||
l++;
|
||||
scrolldown(curwp, l, n);
|
||||
}
|
||||
}
|
||||
|
||||
/* if we are in C mode and this is a default <NL> */
|
||||
/* pico's never in C mode */
|
||||
|
||||
if(Pmaster && Pmaster->allow_flowed_text && curwp->w_doto
|
||||
&& isspace(lgetc(curwp->w_dotp, curwp->w_doto - 1).c)
|
||||
&& !(curwp->w_doto == 3
|
||||
&& lgetc(curwp->w_dotp, 0).c == '-'
|
||||
&& lgetc(curwp->w_dotp, 1).c == '-'
|
||||
&& lgetc(curwp->w_dotp, 2).c == ' ')){
|
||||
/*
|
||||
* flowed mode, make the newline a hard one by
|
||||
* stripping trailing space.
|
||||
*/
|
||||
int i, dellen;
|
||||
for(i = curwp->w_doto - 1;
|
||||
i && isspace(lgetc(curwp->w_dotp, i - 1).c);
|
||||
i--);
|
||||
dellen = curwp->w_doto - i;
|
||||
curwp->w_doto = i;
|
||||
ldelete(dellen, NULL);
|
||||
}
|
||||
/* insert some lines */
|
||||
while (n--) {
|
||||
if ((s=lnewline()) != TRUE)
|
||||
return (s);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Delete forward. This is real easy, because the basic delete routine does
|
||||
* all of the work. Watches for negative arguments, and does the right thing.
|
||||
* If any argument is present, it kills rather than deletes, to prevent loss
|
||||
* of text if typed with a big argument. Normally bound to "C-D".
|
||||
*/
|
||||
forwdel(f, n)
|
||||
int f, n;
|
||||
{
|
||||
if (curbp->b_mode&MDVIEW) /* don't allow this command if */
|
||||
return(rdonly()); /* we are in read only mode */
|
||||
|
||||
if (n < 0)
|
||||
return (backdel(f, -n));
|
||||
|
||||
if(optimize && (curwp->w_dotp != curwp->w_bufp->b_linep)){
|
||||
int l;
|
||||
|
||||
if(worthit(&l) && curwp->w_doto == llength(curwp->w_dotp))
|
||||
scrollup(curwp, l+1, 1);
|
||||
}
|
||||
|
||||
if (f != FALSE) { /* Really a kill. */
|
||||
if ((lastflag&CFKILL) == 0)
|
||||
kdelete();
|
||||
thisflag |= CFKILL;
|
||||
}
|
||||
|
||||
return (ldelete((long) n, f ? kinsert : NULL));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Delete backwards. This is quite easy too, because it's all done with other
|
||||
* functions. Just move the cursor back, and delete forwards. Like delete
|
||||
* forward, this actually does a kill if presented with an argument. Bound to
|
||||
* both "RUBOUT" and "C-H".
|
||||
*/
|
||||
backdel(f, n)
|
||||
int f, n;
|
||||
{
|
||||
register int s;
|
||||
|
||||
if (curbp->b_mode&MDVIEW) /* don't allow this command if */
|
||||
return(rdonly()); /* we are in read only mode */
|
||||
|
||||
if (n < 0)
|
||||
return (forwdel(f, -n));
|
||||
|
||||
if(optimize && curwp->w_dotp != curwp->w_bufp->b_linep){
|
||||
int l;
|
||||
|
||||
if(worthit(&l) && curwp->w_doto == 0 &&
|
||||
lback(curwp->w_dotp) != curwp->w_bufp->b_linep){
|
||||
if(l == curwp->w_toprow)
|
||||
scrollup(curwp, l+1, 1);
|
||||
else if(llength(lback(curwp->w_dotp)) == 0)
|
||||
scrollup(curwp, l-1, 1);
|
||||
else
|
||||
scrollup(curwp, l, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (f != FALSE) { /* Really a kill. */
|
||||
if ((lastflag&CFKILL) == 0)
|
||||
kdelete();
|
||||
|
||||
thisflag |= CFKILL;
|
||||
}
|
||||
|
||||
if ((s=backchar(f, n)) == TRUE)
|
||||
s = ldelete((long) n, f ? kinsert : NULL);
|
||||
|
||||
return (s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* killtext - delete the line that the cursor is currently in.
|
||||
* a greatly pared down version of its former self.
|
||||
*/
|
||||
killtext(f, n)
|
||||
int f, n;
|
||||
{
|
||||
register int chunk;
|
||||
int opt_scroll = 0;
|
||||
|
||||
if (curbp->b_mode&MDVIEW) /* don't allow this command if */
|
||||
return(rdonly()); /* we are in read only mode */
|
||||
|
||||
if ((lastflag&CFKILL) == 0) /* Clear kill buffer if */
|
||||
kdelete(); /* last wasn't a kill. */
|
||||
|
||||
if(gmode & MDDTKILL){ /* */
|
||||
if((chunk = llength(curwp->w_dotp) - curwp->w_doto) == 0){
|
||||
chunk = 1;
|
||||
if(optimize)
|
||||
opt_scroll = 1;
|
||||
}
|
||||
}
|
||||
else{
|
||||
gotobol(FALSE, 1); /* wack from bol past newline */
|
||||
chunk = llength(curwp->w_dotp) + 1;
|
||||
if(optimize)
|
||||
opt_scroll = 1;
|
||||
}
|
||||
|
||||
/* optimize what motion we can */
|
||||
if(opt_scroll && (curwp->w_dotp != curwp->w_bufp->b_linep)){
|
||||
int l;
|
||||
|
||||
if(worthit(&l))
|
||||
scrollup(curwp, l, 1);
|
||||
}
|
||||
|
||||
thisflag |= CFKILL;
|
||||
return(ldelete((long) chunk, kinsert));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Yank text back from the kill buffer. This is really easy. All of the work
|
||||
* is done by the standard insert routines. All you do is run the loop, and
|
||||
* check for errors. Bound to "C-Y".
|
||||
*/
|
||||
yank(f, n)
|
||||
int f, n;
|
||||
{
|
||||
register int c;
|
||||
register int i;
|
||||
|
||||
if (curbp->b_mode&MDVIEW) /* don't allow this command if */
|
||||
return(rdonly()); /* we are in read only mode */
|
||||
|
||||
if (n < 0)
|
||||
return (FALSE);
|
||||
|
||||
if(optimize && (curwp->w_dotp != curwp->w_bufp->b_linep)){
|
||||
int l;
|
||||
|
||||
if(worthit(&l) && !(lastflag&CFFILL)){
|
||||
register int t = 0;
|
||||
register int i = 0;
|
||||
register int ch;
|
||||
|
||||
while((ch=fremove(i++)) >= 0)
|
||||
if(ch == '\n')
|
||||
t++;
|
||||
if(t+l < curwp->w_toprow+curwp->w_ntrows)
|
||||
scrolldown(curwp, l, t);
|
||||
}
|
||||
}
|
||||
|
||||
if(lastflag & CFFILL){ /* if last command was fillpara() */
|
||||
REGION region;
|
||||
LINE *dotp;
|
||||
|
||||
if(lastflag & CFFLBF){
|
||||
gotoeob(FALSE, 1);
|
||||
dotp = curwp->w_dotp;
|
||||
gotobob(FALSE, 1);
|
||||
}
|
||||
else{
|
||||
backchar(FALSE, 1);
|
||||
dotp = curwp->w_dotp;
|
||||
gotobop(FALSE, 1); /* then go to the top of the para */
|
||||
}
|
||||
|
||||
curwp->w_doto = 0;
|
||||
getregion(®ion, dotp, llength(dotp));
|
||||
if(!ldelete(region.r_size, NULL))
|
||||
return(FALSE);
|
||||
} /* then splat out the saved buffer */
|
||||
|
||||
while (n--) {
|
||||
i = 0;
|
||||
while ((c = ((lastflag&CFFILL)
|
||||
? ((lastflag & CFFLBF) ? kremove(i) : fremove(i))
|
||||
: kremove(i))) >= 0) {
|
||||
if (c == '\n') {
|
||||
if (lnewline() == FALSE)
|
||||
return (FALSE);
|
||||
} else {
|
||||
if (linsert(1, c) == FALSE)
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
if(lastflag&CFFILL){ /* if last command was fillpara() */
|
||||
curwp->w_dotp = lforw(curwp->w_dotp);
|
||||
curwp->w_doto = 0;
|
||||
|
||||
curwp->w_flag |= WFMODE;
|
||||
|
||||
if(!Pmaster){
|
||||
sgarbk = TRUE;
|
||||
emlwrite("", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Original idea from Stephen Casner <casner@acm.org>.
|
||||
*
|
||||
* Apply the appropriate reverse color transformation to the given
|
||||
* color pair and return a new color pair. The caller should free the
|
||||
* color pair.
|
||||
*
|
||||
*/
|
||||
COLOR_PAIR *
|
||||
pico_apply_rev_color(cp, style)
|
||||
COLOR_PAIR *cp;
|
||||
int style;
|
||||
{
|
||||
COLOR_PAIR *rc = pico_get_rev_color();
|
||||
|
||||
if(rc){
|
||||
if(style == IND_COL_REV){
|
||||
/* just use Reverse color regardless */
|
||||
return(new_color_pair(rc->fg, rc->bg));
|
||||
}
|
||||
else if(style == IND_COL_FG){
|
||||
/*
|
||||
* If changing to Rev fg is readable and different
|
||||
* from what it already is, do it.
|
||||
*/
|
||||
if(strcmp(rc->fg, cp->bg) && strcmp(rc->fg, cp->fg))
|
||||
return(new_color_pair(rc->fg, cp->bg));
|
||||
}
|
||||
else if(style == IND_COL_BG){
|
||||
/*
|
||||
* If changing to Rev bg is readable and different
|
||||
* from what it already is, do it.
|
||||
*/
|
||||
if(strcmp(rc->bg, cp->fg) && strcmp(rc->bg, cp->bg))
|
||||
return(new_color_pair(cp->fg, rc->bg));
|
||||
}
|
||||
else if(style == IND_COL_FG_NOAMBIG){
|
||||
/*
|
||||
* If changing to Rev fg is readable, different
|
||||
* from what it already is, and not the same as
|
||||
* the Rev color, do it.
|
||||
*/
|
||||
if(strcmp(rc->fg, cp->bg) && strcmp(rc->fg, cp->fg) &&
|
||||
strcmp(rc->bg, cp->bg))
|
||||
return(new_color_pair(rc->fg, cp->bg));
|
||||
}
|
||||
else if(style == IND_COL_BG_NOAMBIG){
|
||||
/*
|
||||
* If changing to Rev bg is readable, different
|
||||
* from what it already is, and not the same as
|
||||
* the Rev color, do it.
|
||||
*/
|
||||
if(strcmp(rc->bg, cp->fg) && strcmp(rc->bg, cp->bg) &&
|
||||
strcmp(rc->fg, cp->fg))
|
||||
return(new_color_pair(cp->fg, rc->bg));
|
||||
}
|
||||
}
|
||||
|
||||
/* come here for IND_COL_FLIP and for the cases which fail the tests */
|
||||
return(new_color_pair(cp->bg, cp->fg)); /* flip the colors */
|
||||
}
|
||||
Reference in New Issue
Block a user