home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / pine / pico / random.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-06  |  16.0 KB  |  428 lines

  1. #if    !defined(lint) && !defined(DOS)
  2. static char rcsid[] = "$Id: random.c,v 4.3 1993/07/08 00:00:13 dlm Exp $";
  3. #endif
  4. /*
  5.  * Program:    Random routines
  6.  *
  7.  *
  8.  * Michael Seibel
  9.  * Networks and Distributed Computing
  10.  * Computing and Communications
  11.  * University of Washington
  12.  * Administration Builiding, AG-44
  13.  * Seattle, Washington, 98195, USA
  14.  * Internet: mikes@cac.washington.edu
  15.  *
  16.  * Please address all bugs and comments to "pine-bugs@cac.washington.edu"
  17.  *
  18.  * Copyright 1991-1993  University of Washington
  19.  *
  20.  *  Permission to use, copy, modify, and distribute this software and its
  21.  * documentation for any purpose and without fee to the University of
  22.  * Washington is hereby granted, provided that the above copyright notice
  23.  * appears in all copies and that both the above copyright notice and this
  24.  * permission notice appear in supporting documentation, and that the name
  25.  * of the University of Washington not be used in advertising or publicity
  26.  * pertaining to distribution of the software without specific, written
  27.  * prior permission.  This software is made available "as is", and
  28.  * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
  29.  * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
  30.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
  31.  * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
  32.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  33.  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
  34.  * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
  35.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  36.  *
  37.  * Pine and Pico are trademarks of the University of Washington.
  38.  * No commercial use of these trademarks may be made without prior
  39.  * written permission of the University of Washington.
  40.  *
  41.  */
  42. /*
  43.  * This file contains the command processing functions for a number of random
  44.  * commands. There is no functional grouping here, for sure.
  45.  */
  46.  
  47. #include        <stdio.h>
  48. #include    "estruct.h"
  49. #include    "pico.h"
  50. #include        "edef.h"
  51. #ifdef HEBREW
  52. #include "hebrew.h"
  53. static char firstdel=1;
  54. #endif
  55.  
  56. #ifdef    ANSI
  57.     int getccol(int);
  58. #else
  59.     int getccol();
  60. #endif
  61.  
  62. int     tabsize;                        /* Tab size (0: use real tabs)  */
  63.  
  64. /*
  65.  * Set fill column to n.
  66.  */
  67. setfillcol(f, n)
  68. int f, n;
  69. {
  70.     char    numbuf[16];
  71.     register int s;
  72.  
  73.     sprintf(numbuf,"%d",fillcol);
  74.     s = mlreplyd("Set fill column to : ", numbuf, 4, QDEFLT);
  75.     fillcol = atoi(numbuf);
  76.     return(s);
  77. }
  78.  
  79.  
  80. /*
  81.  * Display the current position of the cursor, in origin 1 X-Y coordinates,
  82.  * the character that is under the cursor (in octal), and the fraction of the
  83.  * text that is before the cursor. The displayed column is not the current
  84.  * column, but the column that would be used on an infinite width display.
  85.  * Normally this is bound to "C-X =".
  86.  */
  87. showcpos(f, n)
  88. int f, n;
  89. {
  90.     register LINE   *clp;
  91.     register long   nch;
  92.     register int    cbo;
  93.     register long   nbc;
  94.     register int    lines;
  95.     register int    thisline;
  96.     char     buffer[80];
  97.  
  98.     clp = lforw(curbp->b_linep);            /* Grovel the data.     */
  99.     cbo = 0;
  100.     nch = 0L;
  101.     lines = 0;
  102.     for (;;) {
  103.     if (clp==curwp->w_dotp && cbo==curwp->w_doto) {
  104.         thisline = lines;
  105.         nbc = nch;
  106.     }
  107.     if (cbo == llength(clp)) {
  108.         if (clp == curbp->b_linep)
  109.           break;
  110.         clp = lforw(clp);
  111.         cbo = 0;
  112.         lines++;
  113.     } else
  114.       ++cbo;
  115.     ++nch;
  116.     }
  117.  
  118.     sprintf(buffer,"line %d of %d (%d%%%%), character %ld of %ld (%d%%%%)",
  119.         thisline+1, lines+1, (int)((100L*(thisline+1))/(lines+1)),
  120.         nbc, nch, (nch) ? (int)((100L*nbc)/nch) : 0);
  121.  
  122.     emlwrite(buffer, NULL);
  123.     return (TRUE);
  124. }
  125.  
  126.  
  127. /*
  128.  * Return current column.  Stop at first non-blank given TRUE argument.
  129.  */
  130. getccol(bflg)
  131. int bflg;
  132. {
  133.     register int c, i, col;
  134.  
  135.     col = 0;
  136.     for (i=0; i<curwp->w_doto; ++i) {
  137.     c = lgetc(curwp->w_dotp, i).c;
  138.     if (c!=' ' && c!='\t' && bflg)
  139.       break;
  140.  
  141.     if (c == '\t')
  142.       col |= 0x07;
  143.     else if (c<0x20 || c==0x7F)
  144.       ++col;
  145.  
  146.     ++col;
  147.     }
  148.  
  149.     return(col);
  150. }
  151.  
  152.  
  153.  
  154. /*
  155.  * Set tab size if given non-default argument (n <> 1).  Otherwise, insert a
  156.  * tab into file.  If given argument, n, of zero, change to true tabs.
  157.  * If n > 1, simulate tab stop every n-characters using spaces. This has to be
  158.  * done in this slightly funny way because the tab (in ASCII) has been turned
  159.  * into "C-I" (in 10 bit code) already. Bound to "C-I".
  160.  */
  161. tab(f, n)
  162. {
  163.     if (n < 0)
  164.       return (FALSE);
  165.  
  166.     if (n == 0 || n > 1) {
  167.     tabsize = n;
  168.     return(TRUE);
  169.     }
  170.  
  171.     if (! tabsize)
  172.       return(linsert(1, '\t'));
  173.  
  174.     return(linsert(tabsize - (getccol(FALSE) % tabsize), ' '));
  175. }
  176.  
  177.  
  178. /*
  179.  * Insert a newline. Bound to "C-M". If we are in CMODE, do automatic
  180.  * indentation as specified.
  181.  */
  182. newline(f, n)
  183. {
  184.     register int    s;
  185.  
  186.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  187.       return(rdonly());    /* we are in read only mode    */
  188.  
  189.     if (n < 0)
  190.       return (FALSE);
  191.  
  192.     if(optimize && (curwp->w_dotp != curwp->w_bufp->b_linep)){
  193.     int l;
  194.  
  195.     if(worthit(&l)){
  196.         if(curwp->w_doto != 0)
  197.           l++;
  198.         scrolldown(curwp, l, n);
  199.     }
  200.     }
  201.  
  202.     /* if we are in C mode and this is a default <NL> */
  203.     /* pico's never in C mode */
  204.  
  205.     /* insert some lines */
  206.     while (n--) {
  207.     if ((s=lnewline()) != TRUE)
  208.       return (s);
  209.     }
  210.     return (TRUE);
  211. }
  212.  
  213.  
  214.  
  215. /*
  216.  * Delete forward. This is real easy, because the basic delete routine does
  217.  * all of the work. Watches for negative arguments, and does the right thing.
  218.  * If any argument is present, it kills rather than deletes, to prevent loss
  219.  * of text if typed with a big argument. Normally bound to "C-D".
  220.  */
  221. forwdel(f, n)
  222. {
  223. #ifdef HEBREW
  224.   int ret;
  225. #endif
  226.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  227.       return(rdonly());    /* we are in read only mode    */
  228.  
  229. #ifdef HEBREW
  230.     if(eng_in_heb){
  231.       if(firstdel){
  232.         firstdel=0;
  233.         ret=backdel(f, n);
  234.         firstdel=1;
  235.         return ret;
  236.       }
  237.     }
  238. #endif
  239.  
  240.     if (n < 0)
  241.       return (backdel(f, -n));
  242.  
  243.     if(optimize && (curwp->w_dotp != curwp->w_bufp->b_linep)){
  244.     int l;
  245.  
  246.     if(worthit(&l) && curwp->w_doto == llength(curwp->w_dotp))
  247.       scrollup(curwp, l+1, 1);
  248.     }
  249.  
  250.     if (f != FALSE) {                       /* Really a kill.       */
  251.     if ((lastflag&CFKILL) == 0)
  252.       kdelete();
  253.     thisflag |= CFKILL;
  254.     }
  255.  
  256.     return (ldelete(n, f));
  257. }
  258.  
  259.  
  260.  
  261. /*
  262.  * Delete backwards. This is quite easy too, because it's all done with other
  263.  * functions. Just move the cursor back, and delete forwards. Like delete
  264.  * forward, this actually does a kill if presented with an argument. Bound to
  265.  * both "RUBOUT" and "C-H".
  266.  */
  267. backdel(f, n)
  268. {
  269.     register int    s;
  270. #ifdef HEBREW
  271.   int ret;
  272. #endif
  273.  
  274.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  275.       return(rdonly());    /* we are in read only mode    */
  276.  
  277. #ifdef HEBREW
  278.     if(eng_in_heb){
  279.       if(firstdel){
  280.         firstdel=0;
  281.         ret=forwdel(f, n);
  282.         firstdel=1;
  283.         return ret;
  284.       }
  285.     }
  286. #endif
  287.     if (n < 0)
  288.       return (forwdel(f, -n));
  289.  
  290.     if(optimize && curwp->w_dotp != curwp->w_bufp->b_linep){
  291.     int l;
  292.     
  293.     if(worthit(&l) && curwp->w_doto == 0 &&
  294.        lback(curwp->w_dotp) != curwp->w_bufp->b_linep){
  295.         if(l == curwp->w_toprow)
  296.           scrollup(curwp, l+1, 1);
  297.         else if(llength(lback(curwp->w_dotp)) == 0)
  298.           scrollup(curwp, l-1, 1);
  299.         else
  300.           scrollup(curwp, l, 1);
  301.     }
  302.     }
  303.  
  304.     if (f != FALSE) {                       /* Really a kill.       */
  305.     if ((lastflag&CFKILL) == 0)
  306.       kdelete();
  307.  
  308.     thisflag |= CFKILL;
  309.     }
  310.  
  311.     if ((s=backchar(f, n)) == TRUE)
  312.       s = ldelete(n, f);
  313.  
  314.     return (s);
  315. }
  316.  
  317.  
  318.  
  319. /*
  320.  * killtext - delete the line that the cursor is currently in.
  321.  *          a greatly pared down version of its former self.
  322.  */
  323. killtext(f, n)
  324. int f, n;
  325. {
  326.     register int    chunk;
  327.  
  328.     if (curbp->b_mode&MDVIEW)       /* don't allow this command if  */
  329.       return(rdonly());       /* we are in read only mode     */
  330.  
  331.     if(optimize && (curwp->w_dotp != curwp->w_bufp->b_linep)){
  332.     int l;
  333.     
  334.     if(worthit(&l))
  335.       scrollup(curwp, l, 1);
  336.     }
  337.  
  338.     if ((lastflag&CFKILL) == 0)             /* Clear kill buffer if */
  339.       kdelete();                      /* last wasn't a kill.  */
  340.  
  341.     thisflag |= CFKILL;
  342.     curwp->w_doto = 0;        /* wack from the beginning of line */
  343.     chunk = llength(curwp->w_dotp) + 1;    /* for the whole length. */
  344.     return(ldelete(chunk, TRUE));
  345. }
  346.  
  347.  
  348. /*
  349.  * Yank text back from the kill buffer. This is really easy. All of the work
  350.  * is done by the standard insert routines. All you do is run the loop, and
  351.  * check for errors. Bound to "C-Y".
  352.  */
  353. yank(f, n)
  354. int f, n;
  355. {
  356.     register int    c;
  357.     register int    i;
  358.     extern   int    kused;
  359.  
  360.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  361.       return(rdonly());    /* we are in read only mode    */
  362.  
  363.     if (n < 0)
  364.       return (FALSE);
  365.  
  366.     if(optimize && (curwp->w_dotp != curwp->w_bufp->b_linep)){
  367.     int l;
  368.  
  369.     if(worthit(&l) && !(lastflag&CFFILL)){
  370.         register int  t = 0; 
  371.         register int  i = 0;
  372.         register int  ch;
  373.  
  374.         while((ch=kremove(i++)) >= 0)
  375.           if(ch == '\n')
  376.         t++;
  377.         if(t+l < curwp->w_toprow+curwp->w_ntrows)
  378.           scrolldown(curwp, l, t);
  379.     }
  380.     }
  381.  
  382.     if(lastflag&CFFILL)        /* if last command was fillpara() */
  383.       gotobop(FALSE, 1);        /* then go to the top of the para */
  384.                     /* then splat out the saved buffer */
  385.     while (n--) {
  386.     i = 0;
  387.     while ((c=kremove(i)) >= 0) {
  388.         if (c == '\n') {
  389.         if (lnewline(FALSE, 1) == FALSE)
  390.           return (FALSE);
  391.         } else {
  392.         if (linsert(1, c) == FALSE)
  393.           return (FALSE);
  394.         }
  395.  
  396.         ++i;
  397.     }
  398.     }
  399.  
  400.     if(lastflag&CFFILL){            /* if last command was fillpara() */
  401.     register LINE *botline;     /* blast the filled paragraph */
  402.     register LINE *topline;
  403.     register int  done = 0;
  404.     
  405.     kdelete();
  406.     topline = curwp->w_dotp;
  407.     gotoeop(FALSE, 1);
  408.     botline = lforw(curwp->w_dotp);
  409.     curwp->w_dotp = topline;
  410.     if(topline != botline){
  411.         while(!done){
  412.         if(lforw(curwp->w_dotp) == botline)
  413.           done++;
  414.         curwp->w_doto = 0;
  415.         ldelete((llength(curwp->w_dotp) + 1), FALSE);
  416.         }
  417.     }
  418.     curwp->w_flag |= WFMODE;
  419.     
  420.     if(Pmaster == NULL){
  421.         sgarbk = TRUE;
  422.         emlwrite("");
  423.     }
  424.     }
  425.  
  426.     return (TRUE);
  427. }