Esempio n. 1
0
void
scrinterp::putch(int ch)
{
  cell_t x, y, mx, my;

  // We can handle all of the standard control chrs here
  switch (ch)
  {
  case '\r':                  // CR
    flushbuf();
    vs.wherexy(x, y);
    vs.gotoxy(0, y);
    break;

  case '\t':                  // TAB
    flushbuf();
    vs.wherexy(x, y);
    vs.maxxy(mx, my);
    x = cell_t((((x + 8) / 8) + 1) * 8);
    if (x >= mx)
    {
      x = cell_t(x % mx);
      goto dolf;
    }
    vs.gotoxy(x, y);
    break;

  case '\n':                  // NL
    flushbuf();
    vs.wherexy(x, y);
    vs.maxxy(mx, my);
  dolf:
    if (y == cell_t(my - 1))  // On last line
      vs.scroll(0, 0, mx, my, 1);
    else
      ++y;
    vs.gotoxy(x, y);
    break;

  case '\007':                 // BELL
    // beep() !
    break;

  case '\b':
    vs.wherexy(x, y);
    if (x > 0)
      vs.gotoxy(--x, y);
    break;

  case '\x0c':                // LF
    // Should to a cls here with home, perhaps...
    break;

  default:
    putbuf(ch);
    if (flushevery)
      flushbuf();
    break;
  }
}
Esempio n. 2
0
void
avatar::putch(int ch)
{
  if (dispfunc)
    (this->*dispfunc)(ch);
  else
  {
    switch (ch)
    {
      case ctrl('L'):             // cls
        flushbuf();
        vs.gotoxy(0, 0);
        vs.setattr(AVT_DEFAULT);
        vs.cls();
        insertmode = 0;
        break;

      case ctrl('Y'):             // repeat chr
        flushbuf();
        dispfunc = &avatar::rptchar;
        counter = -1;
        break;

      case ctrl('V'):             // Video
        flushbuf();
        dispfunc = &avatar::setvideo;
        break;

      default:
        scrinterp::putch(ch);
        break;
    }
  }
}
Esempio n. 3
0
static int
write_dirent(VenusFid *fid, const char *name, void *arg)
{
     struct nnpfs_dirent dirent, *real;
     struct write_dirent_args *args = (struct write_dirent_args *)arg;

     dirent.d_namlen = strlen (name);
#ifdef _GENERIC_DIRSIZ
     dirent.d_reclen = _GENERIC_DIRSIZ(&dirent);
#elif defined(DIRENT_SIZE)
     dirent.d_reclen = DIRENT_SIZE(&dirent);
#else
     dirent.d_reclen = DIRSIZ(&dirent);
#endif

     if (args->ptr + dirent.d_reclen > args->buf + blocksize)
	  flushbuf (args);
     real = (struct nnpfs_dirent *)args->ptr;

     real->d_namlen = dirent.d_namlen;
     real->d_reclen = dirent.d_reclen;
#if defined(HAVE_STRUCT_DIRENT_D_TYPE) && !defined(__linux__)
     real->d_type   = DT_UNKNOWN;
#endif
     
     real->d_fileno = dentry2ino (name, fid, args->e);
     strlcpy (real->d_name, name, sizeof(real->d_name));
     args->ptr += real->d_reclen;
     args->off += real->d_reclen;
     args->last = real;
     return 0;
}
Esempio n. 4
0
void
scrinterp::putbuf(int ch)
{
  if (chridx >= CBUFSZ)
    flushbuf();
  chrbuf[chridx++] = char(ch);
}
Esempio n. 5
0
int gzfilebuf::overflow( int c ) {

  if ( !is_open() || !(mode & ios::out) )
    return EOF;

  if ( !base() ) {
    if ( allocate() == EOF )
      return EOF;
    setg(0,0,0);
  } else {
    if (in_avail()) {
	return EOF;
    }
    if (out_waiting()) {
      if (flushbuf() == EOF)
	return EOF;
    }
  }

  int bl = blen();
  setp( base(), base() + bl);

  if ( c != EOF ) {

    *pptr() = c;
    pbump(1);

  }

  return 0;

}
Esempio n. 6
0
void
scrinterp::display(istream & is)
{
  int ch =0;
  reset();
  while (is.good() && (ch = is.get()) != EOF)
    putch(ch);
  flushbuf();
}
 void writeint(int n) 
 {         
 	if(bp>BUFSIZE-16) flushbuf();
     int k=1000000000;
     while(k>n) k/=10;
     for( ; k; n%=k, k/=10)
      buf[bp++] = n/k + 48;
      	buf[bp++]='\n';
   }
Esempio n. 8
0
int gzfilebuf::sync() {

  if ( !is_open() )
    return EOF;

  if ( out_waiting() )
    return flushbuf();

  return 0;

}
Esempio n. 9
0
int
buffer_tlv(int type, const unsigned char *data, int datalen,
           const struct sockaddr_in6 *sin6, struct interface *interface)
{
    if(interface && sin6) {
        errno = EINVAL;
        return -1;
    }

    if(sendbuf == NULL)
        sendbuf = allocate_buffer(SENDBUF_SIZE);
    if(sendbuf == NULL)
        return -1;

    if(buffered &&
       ((interface && interface != buffered_interface) ||
        (!interface && (buffered_interface ||
                        memcmp(sin6, &buffered_sin6, sizeof(*sin6)) != 0)) ||
        buffered + datalen > 1400))
        flushbuf();

    if(buffered + datalen + 4 > SENDBUF_SIZE) {
        errno = EMSGSIZE;
        return -1;
    }

    if(!buffered) {
        /* NODE-ENDPOINT */
        DO_HTONS(sendbuf + 0, 3);
        DO_HTONS(sendbuf + 2, 8);
        memcpy(sendbuf + 4, myid, 4);
        DO_HTONL(sendbuf + 8,
                 interface ? interface->ifindex : sin6->sin6_scope_id);
        buffered = 12;
    }

    if(interface)
        buffered_interface = interface;
    else
        memcpy(&buffered_sin6, sin6, sizeof(*sin6));

    DO_HTONS(sendbuf + buffered, type); buffered += 2;
    DO_HTONS(sendbuf + buffered, datalen); buffered += 2;
    memcpy(sendbuf + buffered, data, datalen); buffered += datalen;

    if(debug_level >= 3)
        debugf("Buffering %s %d (%d)\n",
               interface ? "multicast" : "unicast", type, datalen);

    return 1;
}
Esempio n. 10
0
File: nt.c Progetto: mingpen/OpenNT
/*
 * inchar() - get a character from the keyboard
 */
int
inchar()
{
    INPUT_RECORD    InputRec;
    DWORD           NumRead;

    got_int = FALSE;

    flushbuf(); /* flush any pending output */

    while(1) {    /* loop until we get a valid console event */

        ReadConsoleInput(ConsoleIn,&InputRec,1,&NumRead);
        if((InputRec.EventType == KEY_EVENT)
        && (InputRec.Event.KeyEvent.bKeyDown))
        {
            KEY_EVENT_RECORD *KE = &InputRec.Event.KeyEvent;
            unsigned char *Table;

            if(KE->dwControlKeyState & ALT_PRESSED) {
                continue;       // no ALT keys allowed.
            } else if(KE->dwControlKeyState & CTL_PRESSED) {
                Table = ControlTable;
            } else if(KE->uChar.AsciiChar) {    // no control, no alt
                return(KE->uChar.AsciiChar);
            } else if(KE->dwControlKeyState & SHIFT_PRESSED) {
                Table = ShiftedTable;
            } else {
                Table = RegularTable;
            }

            if((KE->wVirtualKeyCode > MAX_VK) || !Table[KE->wVirtualKeyCode]) {
                continue;
            }
            return(Table[KE->wVirtualKeyCode]);
        }
    }
}
Esempio n. 11
0
int gzfilebuf::underflow() {

  // If the file hasn't been opened for reading, error.
  if ( !is_open() || !(mode & ios::in) )
    return EOF;

  // if a buffer doesn't exists, allocate one.
  if ( !base() ) {

    if ( (allocate()) == EOF )
      return EOF;
    setp(0,0);

  } else {

    if ( in_avail() )
      return (unsigned char) *gptr();

    if ( out_waiting() ) {
      if ( flushbuf() == EOF )
	return EOF;
    }

  }

  // Attempt to fill the buffer.

  int result = fillbuf();
  if ( result == EOF ) {
    // disable get area
    setg(0,0,0);
    return EOF;
  }

  return (unsigned char) *gptr();

}
Esempio n. 12
0
	void
normal()
{
	register int	c;
	long 			n;
	int				flag = FALSE;
	int				flag2 = FALSE;
	int 			type = 0;				/* type of operation */
	int 			dir = FORWARD;			/* search direction */
	int				nchar = NUL;
	int				finish_op;
	linenr_t		Prenum1;
	char_u			searchbuff[CMDBUFFSIZE];/* buffer for search string */
	FPOS			*pos = NULL;			/* init for gcc */
	register char_u	*ptr;
	int				command_busy = FALSE;
	static int		didwarn = FALSE;		/* warned for broken inversion */
	int				modified = FALSE;		/* changed current buffer */
	int				ctrl_w = FALSE;			/* got CTRL-W command */

		/* the visual area is remembered for reselection */
	static linenr_t	resel_Visual_nlines;		/* number of lines */
	static int		resel_Visual_type = 0;	/* type 'v', 'V' or CTRL-V */
	static colnr_t	resel_Visual_col;		/* number of columns or end column */
		/* the visual area is remembered for redo */
	static linenr_t	redo_Visual_nlines;		/* number of lines */
	static int		redo_Visual_type = 0;	/* type 'v', 'V' or CTRL-V */
	static colnr_t	redo_Visual_col;		/* number of columns or end column */
	static long		redo_Visual_Prenum;		/* Prenum for operator */

	Prenum = 0;
	/*
	 * If there is an operator pending, then the command we take this time
	 * will terminate it. Finish_op tells us to finish the operation before
	 * returning this time (unless the operation was cancelled).
	 */
	finish_op = (operator != NOP);

	if (!finish_op && !yankbuffer)
		opnum = 0;

	if (p_sc && (vpeekc() == NUL || KeyTyped == TRUE))
		premsg(NUL, NUL);
	State = NORMAL_BUSY;
	c = vgetc();

getcount:
	/* Pick up any leading digits and compute 'Prenum' */
	while ((c >= '1' && c <= '9') || (Prenum != 0 && (c == DEL || c == '0')))
	{
		if (c == DEL)
				Prenum /= 10;
		else
				Prenum = Prenum * 10 + (c - '0');
		if (Prenum < 0)			/* got too large! */
			Prenum = 999999999;
		premsg(ctrl_w ? Ctrl('W') : ' ', NUL);
		c = vgetc();
	}

/*
 * If we got CTRL-W there may be a/another count
 */
	if (c == Ctrl('W') && !ctrl_w)
	{
		ctrl_w = TRUE;
		opnum = Prenum;						/* remember first count */
		Prenum = 0;
		State = ONLYKEY;					/* no mapping for nchar, but keys */
		premsg(c, NUL);
		c = vgetc();						/* get next character */
		goto getcount;						/* jump back */
	}

	/*
	 * If we're in the middle of an operator (including after entering a yank
	 * buffer with ") AND we had a count before the
	 * operator, then that count overrides the current value of Prenum. What
	 * this means effectively, is that commands like "3dw" get turned into
	 * "d3w" which makes things fall into place pretty neatly.
	 * If you give a count before AND after the operator, they are multiplied.
	 */
	if (opnum != 0)
	{
			if (Prenum)
				Prenum *= opnum;
			else
				Prenum = opnum;
			opnum = 0;
	}

	Prenum1 = (Prenum == 0 ? 1 : Prenum);		/* Prenum often defaults to 1 */
	premsg(c, NUL);

	/*
	 * get an additional character if we need one
	 * for CTRL-W we already got it when looking for a count
	 */
	if (ctrl_w)
	{
		nchar = c;
		c = Ctrl('W');
		premsg(c, nchar);
	}
	else if (strchr("@zZtTfF[]mg'`\"", c) || (c == 'q' && !Recording && !Exec_reg) ||
										(c == 'r' && !VIsual.lnum))
	{
		State = NOMAPPING;
		nchar = vgetc();		/* no macro mapping for this char */
		premsg(c, nchar);
	}
	if (p_sc)
		flushbuf();		/* flush the premsg() characters onto the screen so we can
							see them while the command is being executed */

/*
 * For commands that don't get another character we can put the State back to
 * NORMAL and check for a window size change.
 */
	if (STRCHR("z:/?", c) == NULL)
		State = NORMAL;
	if (nchar == ESC)
	{
		CLEAROP;
		goto normal_end;
	}
	switch (c)
	{

/*
 * 0: Macros
 */
	  case 'q': 		/* (stop) recording into a named register */
		CHECKCLEAROP;
						/* command is ignored while executing a register */
		if (!Exec_reg && dorecord(nchar) == FAIL)
			CLEAROPBEEP;
		break;

	 case '@':			/* execute a named buffer */
		CHECKCLEAROP;
		while (Prenum1--)
		{
			if (doexecbuf(nchar) == FAIL)
			{
				CLEAROPBEEP;
				break;
			}
		}
		break;

/*
 * 1: Screen positioning commands
 */
	  case Ctrl('D'):
		flag = TRUE;

	  case Ctrl('U'):
		CHECKCLEAROP;
		if (Prenum)
			curwin->w_p_scroll = (Prenum > curwin->w_height) ? curwin->w_height : Prenum;
		n = (curwin->w_p_scroll <= curwin->w_height) ? curwin->w_p_scroll : curwin->w_height;
		if (flag)
		{
				curwin->w_topline += n;
				if (curwin->w_topline > curbuf->b_ml.ml_line_count)
					curwin->w_topline = curbuf->b_ml.ml_line_count;
				comp_Botline(curwin);		/* compute curwin->w_botline */
				(void)onedown(n);
		}
		else
		{
				if (n >= curwin->w_cursor.lnum)
					n = curwin->w_cursor.lnum - 1;
				Prenum1 = curwin->w_cursor.lnum - n;
				scrolldown(n);
				if (Prenum1 < curwin->w_cursor.lnum)
					curwin->w_cursor.lnum = Prenum1;
		}
		beginline(TRUE);
		updateScreen(VALID);
		break;

	  case Ctrl('B'):
	  case K_SUARROW:
		dir = BACKWARD;

	  case Ctrl('F'):
	  case K_SDARROW:
		CHECKCLEAROP;
		(void)onepage(dir, Prenum1);
		break;

	  case Ctrl('E'):
		CHECKCLEAROP;
		scrollup(Prenum1);
				/* We may have moved to another line -- webb */
		coladvance(curwin->w_curswant);
		updateScreen(VALID);
		break;

	  case Ctrl('Y'):
		CHECKCLEAROP;
		scrolldown(Prenum1);
				/* We may have moved to another line -- webb */
		coladvance(curwin->w_curswant);
		updateScreen(VALID);
		break;

	  case 'z':
		CHECKCLEAROP;
		if (isdigit(nchar))
		{
			/*
			 * we misuse some variables to be able to call premsg()
			 */
			operator = c;
			opnum = Prenum;
			Prenum = nchar - '0';
			for (;;)
			{
				premsg(' ', NUL);
				nchar = vgetc();
				State = NORMAL;
				if (nchar == DEL)
					Prenum /= 10;
				else if (isdigit(nchar))
					Prenum = Prenum * 10 + (nchar - '0');
				else if (nchar == CR)
				{
					win_setheight((int)Prenum);
					break;
				}
				else
				{
					CLEAROPBEEP;
					break;
				}
			}
			operator = NOP;
			break;
		}

		if (Prenum && Prenum != curwin->w_cursor.lnum)	/* line number given */
		{
			setpcmark();
			if (Prenum > curbuf->b_ml.ml_line_count)
				curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
			else
				curwin->w_cursor.lnum = Prenum;
		}
		State = NORMAL;			/* for updateScreen() */
		switch (nchar)
		{
		  case NL:				/* put curwin->w_cursor at top of screen */
		  case CR:
			beginline(TRUE);
		  case 't':
			curwin->w_topline = curwin->w_cursor.lnum;
			break;

		  case '.': 			/* put curwin->w_cursor in middle of screen */
		  case 'z':
			n = (curwin->w_height + plines(curwin->w_cursor.lnum)) / 2;
			goto dozcmd;

		  case '-': 			/* put curwin->w_cursor at bottom of screen */
		  case 'b':
			n = curwin->w_height;
			/* FALLTHROUGH */

	dozcmd:
			{
				register linenr_t	lp = curwin->w_cursor.lnum;
				register long		l = plines(lp);

				do
				{
					curwin->w_topline = lp;
					if (--lp == 0)
						break;
					l += plines(lp);
				} while (l <= n);
			}
			if (nchar != 'z' && nchar != 'b')
				beginline(TRUE);
			break;

		  case Ctrl('S'):	/* ignore CTRL-S and CTRL-Q to avoid problems */
		  case Ctrl('Q'):	/* with terminals that use xon/xoff */
		  	break;

		  default:
			CLEAROPBEEP;
		}
		updateScreen(VALID);
		break;

/*
 *	  2: Control commands
 */
	  case ':':
	    if (VIsual.lnum)
			goto dooperator;
		CHECKCLEAROP;
		/*
		 * translate "count:" into ":.,.+(count - 1)"
		 */
		if (Prenum)
		{
			stuffReadbuff((char_u *)".");
			if (Prenum > 1)
			{
				stuffReadbuff((char_u *)",.+");
				stuffnumReadbuff((long)Prenum - 1L);
			}
		}
		docmdline(NULL);
		modified = TRUE;
		break;

	  case K_HELP:
		CHECKCLEAROP;
		help();
		break;

	  case Ctrl('L'):
		CHECKCLEAROP;
		updateScreen(CLEAR);
		break;

	  case Ctrl('G'):
		CHECKCLEAROP;
		fileinfo(did_cd || Prenum);	/* print full name if count given or :cd used */
		break;

	  case K_CCIRCM:			/* CTRL-^, short for ":e #" */
		CHECKCLEAROPQ;
		(void)buflist_getfile((int)Prenum, (linenr_t)0, TRUE);
		break;

	  case 'Z': 		/* write, if changed, and exit */
		CHECKCLEAROPQ;
		if (nchar != 'Z')
		{
			CLEAROPBEEP;
			break;
		}
		stuffReadbuff((char_u *)":x\n");
		break;

	  case Ctrl(']'):			/* :ta to current identifier */
		CHECKCLEAROPQ;
	  case '*': 				/* / to current identifier or string */
	  case '#': 				/* ? to current identifier or string */
	  case 'K':					/* run program for current identifier */
		{
			register int 	col;
			register int	i;

			/*
			 * if i == 0: try to find an identifier
			 * if i == 1: try to find any string
			 */
			ptr = ml_get(curwin->w_cursor.lnum);
			for (i = 0;	i < 2; ++i)
			{
				/*
				 * skip to start of identifier/string
				 */
				col = curwin->w_cursor.col;
				while (ptr[col] != NUL &&
							(i == 0 ? !isidchar(ptr[col]) : iswhite(ptr[col])))
					++col;

				/*
				 * Back up to start of identifier/string. This doesn't match the
				 * real vi but I like it a little better and it shouldn't bother
				 * anyone.
				 */
				while (col > 0 && (i == 0 ? isidchar(ptr[col - 1]) :
							(!iswhite(ptr[col - 1]) && !isidchar(ptr[col - 1]))))
					--col;

				/*
				 * if identifier found or not '*' or '#' command, stop searching
				 */
				if (isidchar(ptr[col]) || (c != '*' && c != '#'))
					break;
			}
			/*
			 * did't find an identifier of string
			 */
			if (ptr[col] == NUL || (!isidchar(ptr[col]) && i == 0))
			{
				CLEAROPBEEP;
				break;
			}

			if (Prenum)
				stuffnumReadbuff(Prenum);
			switch (c)
			{
				case '*':
					stuffReadbuff((char_u *)"/");
					goto sow;

				case '#':
					stuffReadbuff((char_u *)"?");
sow:				if (i == 0)
						stuffReadbuff((char_u *)"\\<");
					break;

				case 'K':
					stuffReadbuff((char_u *)":! ");
					stuffReadbuff(p_kp);
					stuffReadbuff((char_u *)" ");
					break;
				default:
					stuffReadbuff((char_u *)":ta ");
			}

			/*
			 * Now grab the chars in the identifier
			 */
			while (i == 0 ? isidchar(ptr[col]) :
								(ptr[col] != NUL && !iswhite(ptr[col])))
			{
				stuffcharReadbuff(ptr[col]);
				++col;
			}
			if ((c == '*' || c == '#') && i == 0)
				stuffReadbuff((char_u *)"\\>");
			stuffReadbuff((char_u *)"\n");
		}
		break;

	  case Ctrl('T'):		/* backwards in tag stack */
			CHECKCLEAROPQ;
	  		dotag((char_u *)"", 2, (int)Prenum1);
			break;

/*
 * Cursor motions
 */
	  case 'G':
		mtype = MLINE;
		setpcmark();
		if (Prenum == 0 || Prenum > curbuf->b_ml.ml_line_count)
				curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
		else
				curwin->w_cursor.lnum = Prenum;
		beginline(TRUE);
		break;

	  case 'H':
	  case 'M':
		if (c == 'M')
				n = (curwin->w_height - curwin->w_empty_rows) / 2;
		else
				n = Prenum;
		mtype = MLINE;
		setpcmark();
		curwin->w_cursor.lnum = curwin->w_topline;
		while (n && onedown((long)1) == OK)
				--n;
		beginline(TRUE);
		break;

	  case 'L':
		mtype = MLINE;
		setpcmark();
		curwin->w_cursor.lnum = curwin->w_botline - 1;
		for (n = Prenum; n && oneup((long)1) == OK; n--)
				;
		beginline(TRUE);
		break;

	  case 'l':
	  case K_RARROW:
	  case ' ':
		mtype = MCHAR;
		mincl = FALSE;
		n = Prenum1;
		while (n--)
		{
			if (oneright() == FAIL)
			{
					/* space wraps to next line if 'whichwrap' bit 1 set */
					/* 'l' wraps to next line if 'whichwrap' bit 2 set */
					/* CURS_RIGHT wraps to next line if 'whichwrap' bit 3 set */
				if (((c == ' ' && (p_ww & 2)) ||
					 (c == 'l' && (p_ww & 4)) ||
					 (c == K_RARROW && (p_ww & 8))) &&
					 	curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
				{
					++curwin->w_cursor.lnum;
					curwin->w_cursor.col = 0;
					curwin->w_set_curswant = TRUE;
					continue;
				}
				if (operator == NOP)
					beep();
				else
				{
					if (lineempty(curwin->w_cursor.lnum))
						CLEAROPBEEP;
					else
					{
						mincl = TRUE;
						if (n)
							beep();
					}
				}
				break;
			}
		}
		break;

	  case Ctrl('H'):
	  case 'h':
	  case K_LARROW:
	  case DEL:
		mtype = MCHAR;
		mincl = FALSE;
		n = Prenum1;
		while (n--)
		{
			if (oneleft() == FAIL)
			{
					/* backspace and del wrap to previous line if 'whichwrap'
					 *											bit 0 set */
					/* 'h' wraps to previous line if 'whichwrap' bit 2 set */
					/* CURS_LEFT wraps to previous line if 'whichwrap' bit 3 set */
				if ((((c == Ctrl('H') || c == DEL) && (p_ww & 1)) ||
					 (c == 'h' && (p_ww & 4)) ||
					 (c == K_LARROW && (p_ww & 8))) &&
							curwin->w_cursor.lnum > 1)
				{
					--(curwin->w_cursor.lnum);
					coladvance(MAXCOL);
					curwin->w_set_curswant = TRUE;
					continue;
				}
				else if (operator != DELETE && operator != CHANGE)
					beep();
				else if (Prenum1 == 1)
					CLEAROPBEEP;
				break;
			}
		}
		break;

	  case '-':
		flag = TRUE;
		/* FALLTHROUGH */

	  case 'k':
	  case K_UARROW:
	  case Ctrl('P'):
		mtype = MLINE;
		if (oneup(Prenum1) == FAIL)
			CLEAROPBEEP;
		else if (flag)
			beginline(TRUE);
		break;

	  case '+':
	  case CR:
		flag = TRUE;
		/* FALLTHROUGH */

	  case 'j':
	  case K_DARROW:
	  case Ctrl('N'):
	  case NL:
		mtype = MLINE;
		if (onedown(Prenum1) == FAIL)
			CLEAROPBEEP;
		else if (flag)
			beginline(TRUE);
		break;

		/*
		 * This is a strange motion command that helps make operators more
		 * logical. It is actually implemented, but not documented in the
		 * real 'vi'. This motion command actually refers to "the current
		 * line". Commands like "dd" and "yy" are really an alternate form of
		 * "d_" and "y_". It does accept a count, so "d3_" works to delete 3
		 * lines.
		 */
	  case '_':
lineop:
		mtype = MLINE;
		if (onedown((long)(Prenum1 - 1)) == FAIL)
			CLEAROPBEEP;
		if (operator != YANK)			/* 'Y' does not move cursor */
			beginline(TRUE);
		break;

	  case '|':
		mtype = MCHAR;
		mincl = TRUE;
		beginline(FALSE);
		if (Prenum > 0)
			coladvance((colnr_t)(Prenum - 1));
		curwin->w_curswant = (colnr_t)(Prenum - 1);
			/* keep curswant at the column where we wanted to go, not where
				we ended; differs is line is too short */
		curwin->w_set_curswant = FALSE;
		break;

		/*
		 * Word Motions
		 */

	  case 'B':
		type = 1;
		/* FALLTHROUGH */

	  case 'b':
	  case K_SLARROW:
		mtype = MCHAR;
		mincl = FALSE;
		curwin->w_set_curswant = TRUE;
		if (bck_word(Prenum1, type))
			CLEAROPBEEP;
		break;

	  case 'E':
		type = 1;
		/* FALLTHROUGH */

	  case 'e':
		mincl = TRUE;
		goto dowrdcmd;

	  case 'W':
		type = 1;
		/* FALLTHROUGH */

	  case 'w':
	  case K_SRARROW:
		mincl = FALSE;
		flag = TRUE;
		/*
		 * This is a little strange. To match what the real vi does, we
		 * effectively map 'cw' to 'ce', and 'cW' to 'cE', provided that we are
		 * not on a space or a TAB. This seems
		 * impolite at first, but it's really more what we mean when we say
		 * 'cw'.
		 * Another strangeness: When standing on the end of a word "ce" will
		 * change until the end of the next wordt, but "cw" will change only
		 * one character! This is done by setting type to 2.
		 */
		if (operator == CHANGE && (n = gchar_cursor()) != ' ' && n != TAB &&
																n != NUL)
		{
			mincl = TRUE;
			flag = FALSE;
			flag2 = TRUE;
		}

dowrdcmd:
		mtype = MCHAR;
		curwin->w_set_curswant = TRUE;
		if (flag)
			n = fwd_word(Prenum1, type, operator != NOP);
		else
			n = end_word(Prenum1, type, flag2);
		if (n)
		{
			CLEAROPBEEP;
			break;
		}
#if 0
		/*
		 * If we do a 'dw' for the last word in a line, we only delete the rest
		 * of the line, not joining the two lines, unless the current line is empty.
		 */
		if (operator == DELETE && Prenum1 == 1 &&
				curbuf->b_startop.lnum != curwin->w_cursor.lnum && !lineempty(startop.lnum))
		{
				curwin->w_cursor = curbuf->b_startop;
				while (oneright() == OK)
					;
				mincl = TRUE;
		}
#endif
		break;

	  case '$':
		mtype = MCHAR;
		mincl = TRUE;
		curwin->w_curswant = MAXCOL;				/* so we stay at the end */
		if (onedown((long)(Prenum1 - 1)) == FAIL)
		{
			CLEAROPBEEP;
			break;
		}
		break;

	  case '^':
		flag = TRUE;
		/* FALLTHROUGH */

	  case '0':
		mtype = MCHAR;
		mincl = FALSE;
		beginline(flag);
		break;

/*
 * 4: Searches
 */
	  case '?':
	  case '/':
		if (!getcmdline(c, searchbuff))
		{
			CLEAROP;
			break;
		}
		mtype = MCHAR;
		mincl = FALSE;
		curwin->w_set_curswant = TRUE;

		n = dosearch(c, searchbuff, FALSE, Prenum1, TRUE, TRUE);
		if (n == 0)
			CLEAROP;
		else if (n == 2)
			mtype = MLINE;
		break;

	  case 'N':
		flag = 1;

	  case 'n':
		mtype = MCHAR;
		mincl = FALSE;
		curwin->w_set_curswant = TRUE;
		if (!dosearch(0, NULL, flag, Prenum1, TRUE, TRUE))
			CLEAROP;
		break;

		/*
		 * Character searches
		 */
	  case 'T':
		dir = BACKWARD;
		/* FALLTHROUGH */

	  case 't':
		type = 1;
		goto docsearch;

	  case 'F':
		dir = BACKWARD;
		/* FALLTHROUGH */

	  case 'f':
docsearch:
		mtype = MCHAR;
		if (dir == BACKWARD)
			mincl = FALSE;
		else
			mincl = TRUE;
		curwin->w_set_curswant = TRUE;
		if (!searchc(nchar, dir, type, Prenum1))
			CLEAROPBEEP;
		break;

	  case ',':
		flag = 1;
		/* FALLTHROUGH */

	  case ';':
	    dir = flag;
	    goto docsearch;		/* nchar == NUL, thus repeat previous search */

		/*
		 * section or C function searches
		 */
	  case '[':
		dir = BACKWARD;
		/* FALLTHROUGH */

	  case ']':
		mtype = MCHAR;
		mincl = FALSE;

		/*
		 * "[f" or "]f" : Edit file under the cursor (same as "gf")
		 */
		if ((c == ']' || c == '[') && nchar == 'f')
			goto gotofile;

		/*
		 * "[{", "[(", "]}" or "])": go to Nth unclosed '{', '(', '}' or ')'
		 */
		if ((c == '[' && (nchar == '{' || nchar == '(')) ||
		   ((c == ']' && (nchar == '}' || nchar == ')'))))
		{
			FPOS old_pos;

			old_pos = curwin->w_cursor;
			while (Prenum1--)
			{
				if ((pos = showmatch(nchar)) == NULL)
				{
					CLEAROPBEEP;
					break;
				}
				curwin->w_cursor = *pos;
			}
			curwin->w_cursor = old_pos;
			if (pos != NULL)
			{
				setpcmark();
				curwin->w_cursor = *pos;
				curwin->w_set_curswant = TRUE;
			}
			break;
		}

		/*
		 * "[[", "[]", "]]" and "][": move to start or end of function
		 */
		if (nchar == '[' || nchar == ']')
		{
			if (nchar == c)				/* "]]" or "[[" */
				flag = '{';
			else
				flag = '}';				/* "][" or "[]" */

			curwin->w_set_curswant = TRUE;
			/*
			 * Imitate strange vi behaviour: When using "]]" with an operator we
			 * also stop at '}'.
			 */
			if (!findpar(dir, Prenum1, flag,
							(operator != NOP && dir == FORWARD && flag == '{')))
				CLEAROPBEEP;
			break;
		}

		/*
		 * "[p" and "]p": put with indent adjustment
		 */
		if (nchar == 'p')
		{
			doput((c == ']') ? FORWARD : BACKWARD, Prenum1, TRUE);
			modified = TRUE;
			break;
		}

		/*
		 * end of '[' and ']': not a valid nchar
		 */
		CLEAROPBEEP;
		break;

	  case '%':
		mincl = TRUE;
	    if (Prenum)		/* {cnt}% : goto {cnt} percentage in file */
		{
			if (Prenum > 100)
				CLEAROPBEEP;
			else
			{
				mtype = MLINE;
				setpcmark();
						/* round up, so CTRL-G will give same value */
				curwin->w_cursor.lnum = (curbuf->b_ml.ml_line_count * Prenum + 99) / 100;
				beginline(TRUE);
			}
		}
		else			/* % : go to matching paren */
		{
			mtype = MCHAR;
			if ((pos = showmatch(NUL)) == NULL)
				CLEAROPBEEP;
			else
			{
				setpcmark();
				curwin->w_cursor = *pos;
				curwin->w_set_curswant = TRUE;
			}
		}
		break;

	  case '(':
		dir = BACKWARD;
		/* FALLTHROUGH */

	  case ')':
		mtype = MCHAR;
		if (c == ')')
			mincl = FALSE;
		else
			mincl = TRUE;
		curwin->w_set_curswant = TRUE;

		if (!findsent(dir, Prenum1))
			CLEAROPBEEP;
		break;

	  case '{':
		dir = BACKWARD;
		/* FALLTHROUGH */

	  case '}':
		mtype = MCHAR;
		mincl = FALSE;
		curwin->w_set_curswant = TRUE;
		if (!findpar(dir, Prenum1, NUL, FALSE))
			CLEAROPBEEP;
		break;

/*
 * 5: Edits
 */
	  case '.':
		CHECKCLEAROPQ;
		if (start_redo(Prenum) == FAIL)
			CLEAROPBEEP;
		modified = TRUE;
		break;

	  case 'u':
	    if (VIsual.lnum)
			goto dooperator;
	  case K_UNDO:
		CHECKCLEAROPQ;
		u_undo((int)Prenum1);
		curwin->w_set_curswant = TRUE;
		modified = TRUE;
		break;

	  case Ctrl('R'):
		CHECKCLEAROPQ;
	  	u_redo((int)Prenum1);
		curwin->w_set_curswant = TRUE;
		modified = TRUE;
		break;

	  case 'U':
	    if (VIsual.lnum)
			goto dooperator;
		CHECKCLEAROPQ;
		u_undoline();
		curwin->w_set_curswant = TRUE;
		modified = TRUE;
		break;

	  case 'r':
	    if (VIsual.lnum)
		{
			c = 'c';
			goto dooperator;
		}
		CHECKCLEAROPQ;
		ptr = ml_get_cursor();
		if (STRLEN(ptr) < (unsigned)Prenum1)	/* not enough characters to replace */
		{
			CLEAROPBEEP;
			break;
		}
		/*
		 * Replacing with a line break or tab is done by edit(), because it
         * is complicated.
		 * Other characters are done below to avoid problems with things like
		 * CTRL-V 048 (for edit() this would be R CTRL-V 0 ESC).
		 */
		if (nchar == '\r' || nchar == '\n' || nchar == '\t')
		{
			prep_redo(Prenum1, 'r', nchar, NUL);
			stuffnumReadbuff(Prenum1);
			stuffcharReadbuff('R');
			stuffcharReadbuff(nchar);
			stuffcharReadbuff(ESC);
			break;
		}

		if (nchar == Ctrl('V'))				/* get another character */
		{
			c = Ctrl('V');
			nchar = get_literal(&type);
			if (type)						/* typeahead */
				stuffcharReadbuff(type);
		}
		else
			c = NUL;
		prep_redo(Prenum1, 'r', c, nchar);
		if (!u_save_cursor())				/* save line for undo */
			break;
			/*
			 * Get ptr again, because u_save will have released the line.
			 * At the same time we let know that the line will be changed.
			 */
		ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE) + curwin->w_cursor.col;
		curwin->w_cursor.col += Prenum1 - 1;
		while (Prenum1--)					/* replace the characters */
			*ptr++ = nchar;
		curwin->w_set_curswant = TRUE;
		CHANGED;
		updateline();
		modified = TRUE;
		break;

	  case 'J':
	    if (VIsual.lnum)		/* join the visual lines */
		{
			if (curwin->w_cursor.lnum > VIsual.lnum)
			{
				Prenum = curwin->w_cursor.lnum - VIsual.lnum + 1;
				curwin->w_cursor.lnum = VIsual.lnum;
			}
			else
				Prenum = VIsual.lnum - curwin->w_cursor.lnum + 1;
			VIsual.lnum = 0;
		}
		CHECKCLEAROP;
		if (Prenum <= 1)
			Prenum = 2; 			/* default for join is two lines! */
		if (curwin->w_cursor.lnum + Prenum - 1 > curbuf->b_ml.ml_line_count)	/* beyond last line */
		{
			CLEAROPBEEP;
			break;
		}

		prep_redo(Prenum, 'J', NUL, NUL);
		dodojoin(Prenum, TRUE, TRUE);
		modified = TRUE;
		break;

	  case 'P':
		dir = BACKWARD;
		/* FALLTHROUGH */

	  case 'p':
		CHECKCLEAROPQ;
		prep_redo(Prenum, c, NUL, NUL);
		doput(dir, Prenum1, FALSE);
		modified = TRUE;
		break;

	  case Ctrl('A'):			/* add to number */
	  case Ctrl('X'):			/* subtract from number */
		CHECKCLEAROPQ;
		if (doaddsub((int)c, Prenum1) == OK)
			prep_redo(Prenum1, c, NUL, NUL);
		modified = TRUE;
		break;

/*
 * 6: Inserts
 */
	  case 'A':
		curwin->w_set_curswant = TRUE;
		while (oneright() == OK)
				;
		/* FALLTHROUGH */

	  case 'a':
		CHECKCLEAROPQ;
		/* Works just like an 'i'nsert on the next character. */
		if (u_save_cursor())
		{
			if (!lineempty(curwin->w_cursor.lnum))
				inc_cursor();
			startinsert(c, FALSE, Prenum1);
			modified = TRUE;
			command_busy = TRUE;
		}
		break;

	  case 'I':
		beginline(TRUE);
		/* FALLTHROUGH */

	  case 'i':
		CHECKCLEAROPQ;
		if (u_save_cursor())
		{
			startinsert(c, FALSE, Prenum1);
			modified = TRUE;
			command_busy = TRUE;
		}
		break;

	  case 'o':
	  	if (VIsual.lnum)	/* switch start and end of visual */
		{
			Prenum = VIsual.lnum;
			VIsual.lnum = curwin->w_cursor.lnum;
			curwin->w_cursor.lnum = Prenum;
			if (VIsual.col != VISUALLINE)
			{
				n = VIsual.col;
				VIsual.col = curwin->w_cursor.col;
				curwin->w_cursor.col = (int)n;
				curwin->w_set_curswant = TRUE;
			}
			break;
		}
		CHECKCLEAROP;
		if (u_save(curwin->w_cursor.lnum, (linenr_t)(curwin->w_cursor.lnum + 1)) &&
							Opencmd(FORWARD, TRUE, TRUE))
		{
			startinsert('o', TRUE, Prenum1);
			modified = TRUE;
			command_busy = TRUE;
		}
		break;

	  case 'O':
		CHECKCLEAROPQ;
		if (u_save((linenr_t)(curwin->w_cursor.lnum - 1), curwin->w_cursor.lnum) && Opencmd(BACKWARD, TRUE, TRUE))
		{
			startinsert('O', TRUE, Prenum1);
			modified = TRUE;
			command_busy = TRUE;
		}
		break;

	  case 'R':
	    if (VIsual.lnum)
		{
			c = 'c';
			VIsual.col = VISUALLINE;
			goto dooperator;
		}
		CHECKCLEAROPQ;
		if (u_save_cursor())
		{
			startinsert('R', FALSE, Prenum1);
			modified = TRUE;
			command_busy = TRUE;
		}
		break;

/*
 * 7: Operators
 */
	  case '~': 		/* swap case */
	  /*
	   * if tilde is not an operator and Visual is off: swap case
	   * of a single character
	   */
		if (!p_to && !VIsual.lnum)
		{
			CHECKCLEAROPQ;
			if (lineempty(curwin->w_cursor.lnum))
			{
				CLEAROPBEEP;
				break;
			}
			prep_redo(Prenum, '~', NUL, NUL);

			if (!u_save_cursor())
				break;

			for (; Prenum1 > 0; --Prenum1)
			{
				if (gchar_cursor() == NUL)
					break;
				swapchar(&curwin->w_cursor);
				inc_cursor();
			}

			curwin->w_set_curswant = TRUE;
			CHANGED;
			updateline();
			modified = TRUE;
			break;
		}
		/*FALLTHROUGH*/

	  case 'd':
	  case 'c':
	  case 'y':
	  case '>':
	  case '<':
	  case '!':
	  case '=':
	  case 'Q':
dooperator:
		n = STRCHR(opchars, c) - opchars + 1;
		if (n == operator)		/* double operator works on lines */
			goto lineop;
		CHECKCLEAROP;
		if (Prenum != 0)
			opnum = Prenum;
		curbuf->b_startop = curwin->w_cursor;
		operator = (int)n;
		break;

/*
 * 8: Abbreviations
 */

	 /* when Visual the next commands are operators */
	  case 'S':
	  case 'Y':
	  case 'D':
	  case 'C':
	  case 'x':
	  case 'X':
	  case 's':
	  	if (VIsual.lnum)
		{
			static char_u trans[] = "ScYyDdCcxdXdsc";

			if (isupper(c) && !Visual_block)		/* uppercase means linewise */
				VIsual.col = VISUALLINE;
			c = *(STRCHR(trans, c) + 1);
			goto dooperator;
		}

	  case '&':
		CHECKCLEAROPQ;
		if (Prenum)
			stuffnumReadbuff(Prenum);

		if (c == 'Y' && p_ye)
			c = 'Z';
		{
				static char_u *(ar[9]) = {(char_u *)"dl", (char_u *)"dh", (char_u *)"d$", (char_u *)"c$", (char_u *)"cl", (char_u *)"cc", (char_u *)"yy", (char_u *)"y$", (char_u *)":s\r"};
				static char_u *str = (char_u *)"xXDCsSYZ&";

				stuffReadbuff(ar[(int)(STRCHR(str, c) - str)]);
		}
		break;

/*
 * 9: Marks
 */

	  case 'm':
		CHECKCLEAROP;
		if (setmark(nchar) == FAIL)
			CLEAROPBEEP;
		break;

	  case '\'':
		flag = TRUE;
		/* FALLTHROUGH */

	  case '`':
		pos = getmark(nchar, (operator == NOP));
		if (pos == (FPOS *)-1)	/* jumped to other file */
		{
			if (flag)
				beginline(TRUE);
			break;
		}

		if (pos != NULL)
			setpcmark();

cursormark:
		if (pos == NULL || pos->lnum == 0)
			CLEAROPBEEP;
		else
		{
			curwin->w_cursor = *pos;
			if (flag)
				beginline(TRUE);
		}
		mtype = flag ? MLINE : MCHAR;
		mincl = FALSE;		/* ignored if not MCHAR */
		curwin->w_set_curswant = TRUE;
		break;

	case Ctrl('O'):			/* goto older pcmark */
		Prenum1 = -Prenum1;
		/* FALLTHROUGH */

	case Ctrl('I'):			/* goto newer pcmark */
		CHECKCLEAROPQ;
		pos = movemark((int)Prenum1);
		if (pos == (FPOS *)-1)	/* jump to other file */
		{
			curwin->w_set_curswant = TRUE;
			break;
		}
		goto cursormark;

/*
 * 10. Buffer setting
 */
	  case '"':
		CHECKCLEAROP;
		if (nchar != NUL && is_yank_buffer(nchar, FALSE))
		{
			yankbuffer = nchar;
			opnum = Prenum;		/* remember count before '"' */
		}
		else
			CLEAROPBEEP;
		break;

/*
 * 11. Visual
 */
 	  case 'v':
	  case 'V':
	  case Ctrl('V'):
		CHECKCLEAROP;
		Visual_block = FALSE;

			/* stop Visual */
		if (VIsual.lnum)
		{
			VIsual.lnum = 0;
			updateScreen(NOT_VALID);		/* delete the inversion */
		}
			/* start Visual */
		else
		{
			if (!didwarn && set_highlight('v') == FAIL)/* cannot highlight */
			{
				EMSG("Warning: terminal cannot highlight");
				didwarn = TRUE;
			}
			if (Prenum)						/* use previously selected part */
			{
				if (!resel_Visual_type)		/* there is none */
				{
					beep();
					break;
				}
				VIsual = curwin->w_cursor;
				if (resel_Visual_nlines > 1)
					curwin->w_cursor.lnum += resel_Visual_nlines * Prenum - 1;
				switch (resel_Visual_type)
				{
				case 'V':	VIsual.col = VISUALLINE;
							break;

				case Ctrl('V'):
							Visual_block = TRUE;
							break;

				case 'v':		
							if (resel_Visual_nlines <= 1)
								curwin->w_cursor.col += resel_Visual_col * Prenum - 1;
							else
								curwin->w_cursor.col = resel_Visual_col;
							break;
				}
				if (resel_Visual_col == MAXCOL)
				{
					curwin->w_curswant = MAXCOL;
					coladvance(MAXCOL);
				}
				else if (Visual_block)
					coladvance((colnr_t)(curwin->w_virtcol + resel_Visual_col * Prenum - 1));
				curs_columns(TRUE);			/* recompute w_virtcol */
				updateScreen(NOT_VALID);	/* show the inversion */
			}
			else
			{
				VIsual = curwin->w_cursor;
				if (c == 'V')				/* linewise */
					VIsual.col = VISUALLINE;
				else if (c == Ctrl('V'))	/* blockwise */
					Visual_block = TRUE;
				updateline();				/* start the inversion */
			}
		}
		break;

/*
 * 12. Suspend
 */

 	case Ctrl('Z'):
		CLEAROP;
		VIsual.lnum = 0;					/* stop Visual */
		stuffReadbuff((char_u *)":st\r");	/* with autowrite */
		break;

/*
 * 13. Window commands
 */

 	case Ctrl('W'):
		CHECKCLEAROP;
		do_window(nchar, Prenum);			/* everything is in window.c */
		break;

/*
 *   14. extended commands (starting with 'g')
 */
 	case 'g':
		switch (nchar)
		{
						/*
						 * "gf": goto file, edit file under cursor
						 * "]f" and "[f": can also be used.
						 */
			case 'f':
gotofile:
						ptr = file_name_at_cursor();
							/* do autowrite if necessary */
						if (curbuf->b_changed && curbuf->b_nwindows <= 1 && !p_hid)
							autowrite(curbuf);
						if (ptr != NULL)
						{
							setpcmark();
							stuffReadbuff((char_u *) ":e ");
							stuffReadbuff(ptr);
							stuffReadbuff((char_u *) "\n");
							free(ptr);
						}
						else
							CLEAROPBEEP;
						break;

						/*
						 * "gs": goto sleep
						 */
			case 's':	while (Prenum1-- && !got_int)
						{
							sleep(1);
							breakcheck();
						}
						break;

			default:	CLEAROPBEEP;
						break;
		}
		break;

/*
 * The end
 */
	  case ESC:
	    if (VIsual.lnum)
		{
			VIsual.lnum = 0;			/* stop Visual */
			updateScreen(NOT_VALID);
			CLEAROP;					/* don't beep */
			break;
		}
		/* Don't drop through and beep if we are canceling a command: */
		else if (operator != NOP || opnum || Prenum || yankbuffer)
		{
			CLEAROP;					/* don't beep */
			break;
		}
		/* FALLTHROUGH */

	  default:					/* not a known command */
		CLEAROPBEEP;
		break;

	}	/* end of switch on command character */

/*
 * if we didn't start or finish an operator, reset yankbuffer, unless we
 * need it later.
 */
	if (!finish_op && !operator && strchr("\"DCYSsXx.", c) == NULL)
		yankbuffer = 0;

	/*
	 * If an operation is pending, handle it...
	 */
	if ((VIsual.lnum || finish_op) && operator != NOP)
	{
		if (operator != YANK && !VIsual.lnum)		/* can't redo yank */
		{
			prep_redo(Prenum, opchars[operator - 1], c, nchar);
			if (c == '/' || c == '?')				/* was a search */
			{
				AppendToRedobuff(searchbuff);
				AppendToRedobuff(NL_STR);
			}
		}

		if (redo_Visual_busy)
		{
			curbuf->b_startop = curwin->w_cursor;
			curwin->w_cursor.lnum += redo_Visual_nlines - 1;
			switch (redo_Visual_type)
			{
			case 'V':	VIsual.col = VISUALLINE;
						break;

			case Ctrl('V'):
						Visual_block = TRUE;
						break;

			case 'v':		
						if (redo_Visual_nlines <= 1)
							curwin->w_cursor.col += redo_Visual_col - 1;
						else
							curwin->w_cursor.col = redo_Visual_col;
						break;
			}
			if (redo_Visual_col == MAXCOL)
			{
				curwin->w_curswant = MAXCOL;
				coladvance(MAXCOL);
			}
			Prenum = redo_Visual_Prenum;
			if (Prenum == 0)
				Prenum1 = 1L;
			else
				Prenum1 = Prenum;
		}
		else if (VIsual.lnum)
			curbuf->b_startop = VIsual;

		if (lt(curbuf->b_startop, curwin->w_cursor))
		{
			curbuf->b_endop = curwin->w_cursor;
			curwin->w_cursor = curbuf->b_startop;
		}
		else
		{
			curbuf->b_endop = curbuf->b_startop;
			curbuf->b_startop = curwin->w_cursor;
		}
		nlines = curbuf->b_endop.lnum - curbuf->b_startop.lnum + 1;

		if (VIsual.lnum || redo_Visual_busy)
		{
			if (Visual_block)				/* block mode */
			{
				startvcol = getvcol(curwin, &(curbuf->b_startop), 2);
				n = getvcol(curwin, &(curbuf->b_endop), 2);
				if (n < startvcol)
					startvcol = (colnr_t)n;

			/* if '$' was used, get endvcol from longest line */
				if (curwin->w_curswant == MAXCOL)
				{
					curwin->w_cursor.col = MAXCOL;
					endvcol = 0;
					for (curwin->w_cursor.lnum = curbuf->b_startop.lnum; curwin->w_cursor.lnum <= curbuf->b_endop.lnum; ++curwin->w_cursor.lnum)
						if ((n = getvcol(curwin, &curwin->w_cursor, 3)) > endvcol)
							endvcol = (colnr_t)n;
					curwin->w_cursor = curbuf->b_startop;
				}
				else if (redo_Visual_busy)
					endvcol = startvcol + redo_Visual_col - 1;
				else
				{
					endvcol = getvcol(curwin, &(curbuf->b_startop), 3);
					n = getvcol(curwin, &(curbuf->b_endop), 3);
					if (n > endvcol)
						endvcol = (colnr_t)n;
				}
				coladvance(startvcol);
			}

	/*
	 * prepare to reselect and redo Visual: this is based on the size
	 * of the Visual text
	 */
			if (Visual_block)
				resel_Visual_type = Ctrl('V');
			else if (VIsual.col == VISUALLINE)
				resel_Visual_type = 'V';
			else
				resel_Visual_type = 'v';
			if (curwin->w_curswant == MAXCOL)
				resel_Visual_col = MAXCOL;
			else if (Visual_block)
				resel_Visual_col = endvcol - startvcol + 1;
			else if (nlines > 1)
				resel_Visual_col = curbuf->b_endop.col;
			else
				resel_Visual_col = curbuf->b_endop.col - curbuf->b_startop.col + 1;
			resel_Visual_nlines = nlines;
			if (operator != YANK && operator != COLON)	/* can't redo yank and : */
			{
				prep_redo(0L, 'v', opchars[operator - 1], NUL);
				redo_Visual_type = resel_Visual_type;
				redo_Visual_col = resel_Visual_col;
				redo_Visual_nlines = resel_Visual_nlines;
				redo_Visual_Prenum = Prenum;
			}

			/*
			 * Mincl defaults to TRUE.
			 * If endop is on a NUL (empty line) mincl becomes FALSE
			 * This makes "d}P" and "v}dP" work the same.
			 */
			mincl = TRUE;
			if (VIsual.col == VISUALLINE)
				mtype = MLINE;
			else
			{
				mtype = MCHAR;
				if (*ml_get_pos(&(curbuf->b_endop)) == NUL)
					mincl = FALSE;
			}

			redo_Visual_busy = FALSE;
			/*
			 * Switch Visual off now, so screen updating does
			 * not show inverted text when the screen is redrawn.
			 * With YANK and sometimes with COLON and FILTER there is no screen
			 * redraw, so it is done here to remove the inverted part.
			 */
			VIsual.lnum = 0;
			if (operator == YANK || operator == COLON || operator == FILTER)
				updateScreen(NOT_VALID);
		}
		else if (operator == LSHIFT || operator == RSHIFT)
			Prenum1 = 1L;		/* if not visual mode: shift one indent */

		curwin->w_set_curswant = 1;

			/* no_op is set when start and end are the same */
		no_op = (mtype == MCHAR && !mincl && equal(curbuf->b_startop, curbuf->b_endop));

	/*
	 * If the end of an operator is in column one while mtype is MCHAR and mincl
	 * is FALSE, we put endop after the last character in the previous line.
	 * If startop is on or before the first non-blank in the line, the operator
	 * becomes linewise (strange, but that's the way vi does it).
	 */
		if (mtype == MCHAR && mincl == FALSE && curbuf->b_endop.col == 0 && nlines > 1)
		{
			--nlines;
			--curbuf->b_endop.lnum;
			if (inindent())
				mtype = MLINE;
			else
			{
				curbuf->b_endop.col = STRLEN(ml_get(curbuf->b_endop.lnum));
				if (curbuf->b_endop.col)
				{
					--curbuf->b_endop.col;
					mincl = TRUE;
				}
			}
		}
		switch (operator)
		{
		  case LSHIFT:
		  case RSHIFT:
			doshift(operator, TRUE, (int)Prenum1);
			modified = TRUE;
			break;

		  case DELETE:
			if (!no_op)
			{
				dodelete();
				modified = TRUE;
			}
			break;

		  case YANK:
			if (!no_op)
				(void)doyank(FALSE);
			break;

		  case CHANGE:
			dochange();
			modified = TRUE;
			command_busy = TRUE;
			break;

		  case FILTER:
			bangredo = TRUE;			/* dobang() will put cmd in redo buffer */

		  case INDENT:
		  case COLON:
dofilter:
			sprintf((char *)IObuff, ":%ld,%ld", (long)curbuf->b_startop.lnum, (long)curbuf->b_endop.lnum);
			stuffReadbuff(IObuff);
			if (operator != COLON)
				stuffReadbuff((char_u *)"!");
			if (operator == INDENT)
			{
				stuffReadbuff(p_ep);
				stuffReadbuff((char_u *)"\n");
			}
			else if (operator == FORMAT)
			{
				stuffReadbuff(p_fp);
				stuffReadbuff((char_u *)"\n");
			}
				/*	docmdline() does the rest */
			break;

		  case TILDE:
		  case UPPER:
		  case LOWER:
			if (!no_op)
			{
				dotilde();
				modified = TRUE;
			}
			break;

		  case FORMAT:
			if (*p_fp != NUL)
				goto dofilter;		/* use external command */
			doformat();				/* use internal function */
			modified = TRUE;
			break;

		  default:
			CLEAROPBEEP;
		}
		operator = NOP;
		Visual_block = FALSE;
		yankbuffer = 0;
	}

normal_end:
	premsg(-1, NUL);

	if (restart_edit && operator == NOP && VIsual.lnum == 0 && !command_busy && stuff_empty() && yankbuffer == 0)
	{
		startinsert(restart_edit, FALSE, 1L);
		modified = TRUE;
	}

	checkpcmark();			/* check if we moved since setting pcmark */

/*
 * TEMPORARY: update the other windows for the current buffer if modified
 */
	if (modified)
	{
		WIN		*wp;

        for (wp = firstwin; wp; wp = wp->w_next)
			if (wp != curwin && wp->w_buffer == curbuf)
			{
				cursor_off();
				wp->w_redr_type = NOT_VALID;
				win_update(wp);
			}
	}
}
Esempio n. 13
0
int main(int argc,char **argv)
{
  FILE *fpi,*fpo;
  char buf[576*2*2];

  static REAL bc[] =
  {1.0,  0,1.0,  0,1.0,  0,1.0,  0,1.0,  0,1.0,  0,1.0,  0,1.0,  0,1.0,  0};

  init(14);
  makeTable(bc,44100);

  if (argc != 3 && argc != 4) exit(-1);

  fpi = fopen(argv[1],"r");
  fpo = fopen(argv[2],"w");

  if (!fpi || !fpo) exit(-1);

  /* generate wav header */

  {
    short word;
    int dword;

    fwrite("RIFF",4,1,fpo);
    dword = 0;
    fwrite(&dword,4,1,fpo);

    fwrite("WAVEfmt ",8,1,fpo);
    dword = 16;
    fwrite(&dword,4,1,fpo);
    word = 1;
    fwrite(&word,2,1,fpo);  /* format category, PCM */
    word = 2;
    fwrite(&word,2,1,fpo);  /* channels */
    dword = 44100;
    fwrite(&dword,4,1,fpo); /* sampling rate */
    dword = 44100*2*2;
    fwrite(&dword,4,1,fpo); /* bytes per sec */
    word = 4;
    fwrite(&word,2,1,fpo);  /* block alignment */
    word = 16;
    fwrite(&word,2,1,fpo);  /* ??? */

    fwrite("data",4,1,fpo);
    dword = 0;
    fwrite(&dword,4,1,fpo);
  }

  preamp = 65536;
  maxamp = 0;

  if (argc == 4) {
    preamp = 32767*65536/atoi(argv[3]);
    fprintf(stderr,"preamp = %d\n",preamp);
  }

  for(;;)
    {
      int n,m;

      n = fread(buf,1,576*2*2,fpi);
      if (n <= 0) break;
      m = modifySamples((short *)buf,n/4,2);
      fwrite(buf,4,m,fpo);
    }

#if 0
  for(;;)
    {
      int n = flushbuf((short *)buf,576);
      if (n == 0) break;
      fwrite(buf,4,n,fpo);
    }
#endif

  {
    short word;
    int dword;
    int len = ftell(fpo);

    fseek(fpo,4,SEEK_SET);
    dword = len-8;
    fwrite(&dword,4,1,fpo);

    fseek(fpo,40,SEEK_SET);
    dword = len-44;
    fwrite(&dword,4,1,fpo);
  }

  if (maxamp != 0) {
    fprintf(stderr,"maxamp = %d\n",maxamp);
  }

  quit();
}
Esempio n. 14
0
int
command(char *buf, int defcom)
{
	char	*reg;
	char	savc;
	char	*savlp=lp;
	char	savlc = lastc;
	char	savpc = peekc;
	static char lastcom = '=', savecom = '=';

	if (defcom == 0)
		defcom = lastcom;
	if (buf) {
		if (*buf==EOR)
			return(FALSE);
		clrinp();
		lp=buf;
	}
	do {
		adrflg=expr(0);		/* first address */
		if (adrflg){
			dot=expv;
			ditto=expv;
		}
		adrval=dot;

		if (rdc()==',' && expr(0)) {	/* count */
			cntflg=TRUE;
			cntval=expv;
		} else {
			cntflg=FALSE;
			cntval=1;
			reread();
		}

		if (!eol(rdc()))
			lastcom=lastc;		/* command */
		else {
			if (adrflg==0)
				dot=inkdot(dotinc);
			reread();
			lastcom=defcom;
		}
		switch(lastcom) {
		case '/':
		case '=':
		case '?':
			savecom = lastcom;
			acommand(lastcom);
			break;

		case '>':
			lastcom = savecom; 
			savc=rdc();
			if (reg=regname(savc))
				rput(correg, reg, dot);
			else	
				error("bad variable");
			break;

		case '!':
			lastcom=savecom;
			shell(); 
			break;

		case '$':
			lastcom=savecom;
			printdollar(nextchar()); 
			break;

		case ':':
			if (!executing) { 
				executing=TRUE;
				subpcs(nextchar());
				executing=FALSE;
				lastcom=savecom;
			}
			break;

		case 0:
			prints(DBNAME);
			break;

		default: 
			error("bad command");
		}
		flushbuf();
	} while (rdc()==';');
	if (buf == 0)
		reread();
	else {
		clrinp();
		lp=savlp;
		lastc = savlc;
		peekc = savpc;
	}

	if(adrflg)
		return dot;
	return 1;
}
int main(void)
{
 
int j,t,p[3401]={2,3,5,7,11,13,17,19,23,29
,31,37,41,43,47,53,59,61,67,71
,73,79,83,89,97,101,103,107,109,113
,127,131,137,139,149,151,157,163,167,173
,179,181,191,193,197,199,211,223,227,229
,233,239,241,251,257,263,269,271,277,281
,283,293,307,311,313,317,331,337,347,349
,353,359,367,373,379,383,389,397,401,409
,419,421,431,433,439,443,449,457,461,463
,467,479,487,491,499,503,509,521,523,541
,547,557,563,569,571,577,587,593,599,601
,607,613,617,619,631,641,643,647,653,659
,661,673,677,683,691,701,709,719,727,733
,739,743,751,757,761,769,773,787,797,809
,811,821,823,827,829,839,853,857,859,863
,877,881,883,887,907,911,919,929,937,941
,947,953,967,971,977,983,991,997,1009,1013
,1019,1021,1031,1033,1039,1049,1051,1061,1063,1069
,1087,1091,1093,1097,1103,1109,1117,1123,1129,1151
,1153,1163,1171,1181,1187,1193,1201,1213,1217,1223
,1229,1231,1237,1249,1259,1277,1279,1283,1289,1291
,1297,1301,1303,1307,1319,1321,1327,1361,1367,1373
,1381,1399,1409,1423,1427,1429,1433,1439,1447,1451
,1453,1459,1471,1481,1483,1487,1489,1493,1499,1511
,1523,1531,1543,1549,1553,1559,1567,1571,1579,1583
,1597,1601,1607,1609,1613,1619,1621,1627,1637,1657
,1663,1667,1669,1693,1697,1699,1709,1721,1723,1733
,1741,1747,1753,1759,1777,1783,1787,1789,1801,1811
,1823,1831,1847,1861,1867,1871,1873,1877,1879,1889
,1901,1907,1913,1931,1933,1949,1951,1973,1979,1987
,1993,1997,1999,2003,2011,2017,2027,2029,2039,2053
,2063,2069,2081,2083,2087,2089,2099,2111,2113,2129
,2131,2137,2141,2143,2153,2161,2179,2203,2207,2213
,2221,2237,2239,2243,2251,2267,2269,2273,2281,2287
,2293,2297,2309,2311,2333,2339,2341,2347,2351,2357
,2371,2377,2381,2383,2389,2393,2399,2411,2417,2423
,2437,2441,2447,2459,2467,2473,2477,2503,2521,2531
,2539,2543,2549,2551,2557,2579,2591,2593,2609,2617
,2621,2633,2647,2657,2659,2663,2671,2677,2683,2687
,2689,2693,2699,2707,2711,2713,2719,2729,2731,2741
,2749,2753,2767,2777,2789,2791,2797,2801,2803,2819
,2833,2837,2843,2851,2857,2861,2879,2887,2897,2903
,2909,2917,2927,2939,2953,2957,2963,2969,2971,2999
,3001,3011,3019,3023,3037,3041,3049,3061,3067,3079
,3083,3089,3109,3119,3121,3137,3163,3167,3169,3181
,3187,3191,3203,3209,3217,3221,3229,3251,3253,3257
,3259,3271,3299,3301,3307,3313,3319,3323,3329,3331
,3343,3347,3359,3361,3371,3373,3389,3391,3407,3413
,3433,3449,3457,3461,3463,3467,3469,3491,3499,3511
,3517,3527,3529,3533,3539,3541,3547,3557,3559,3571
,3581,3583,3593,3607,3613,3617,3623,3631,3637,3643
,3659,3671,3673,3677,3691,3697,3701,3709,3719,3727
,3733,3739,3761,3767,3769,3779,3793,3797,3803,3821
,3823,3833,3847,3851,3853,3863,3877,3881,3889,3907
,3911,3917,3919,3923,3929,3931,3943,3947,3967,3989
,4001,4003,4007,4013,4019,4021,4027,4049,4051,4057
,4073,4079,4091,4093,4099,4111,4127,4129,4133,4139
,4153,4157,4159,4177,4201,4211,4217,4219,4229,4231
,4241,4243,4253,4259,4261,4271,4273,4283,4289,4297
,4327,4337,4339,4349,4357,4363,4373,4391,4397,4409
,4421,4423,4441,4447,4451,4457,4463,4481,4483,4493
,4507,4513,4517,4519,4523,4547,4549,4561,4567,4583
,4591,4597,4603,4621,4637,4639,4643,4649,4651,4657
,4663,4673,4679,4691,4703,4721,4723,4729,4733,4751
,4759,4783,4787,4789,4793,4799,4801,4813,4817,4831
,4861,4871,4877,4889,4903,4909,4919,4931,4933,4937
,4943,4951,4957,4967,4969,4973,4987,4993,4999,5003
,5009,5011,5021,5023,5039,5051,5059,5077,5081,5087
,5099,5101,5107,5113,5119,5147,5153,5167,5171,5179
,5189,5197,5209,5227,5231,5233,5237,5261,5273,5279
,5281,5297,5303,5309,5323,5333,5347,5351,5381,5387
,5393,5399,5407,5413,5417,5419,5431,5437,5441,5443
,5449,5471,5477,5479,5483,5501,5503,5507,5519,5521
,5527,5531,5557,5563,5569,5573,5581,5591,5623,5639
,5641,5647,5651,5653,5657,5659,5669,5683,5689,5693
,5701,5711,5717,5737,5741,5743,5749,5779,5783,5791
,5801,5807,5813,5821,5827,5839,5843,5849,5851,5857
,5861,5867,5869,5879,5881,5897,5903,5923,5927,5939
,5953,5981,5987,6007,6011,6029,6037,6043,6047,6053
,6067,6073,6079,6089,6091,6101,6113,6121,6131,6133
,6143,6151,6163,6173,6197,6199,6203,6211,6217,6221
,6229,6247,6257,6263,6269,6271,6277,6287,6299,6301
,6311,6317,6323,6329,6337,6343,6353,6359,6361,6367
,6373,6379,6389,6397,6421,6427,6449,6451,6469,6473
,6481,6491,6521,6529,6547,6551,6553,6563,6569,6571
,6577,6581,6599,6607,6619,6637,6653,6659,6661,6673
,6679,6689,6691,6701,6703,6709,6719,6733,6737,6761
,6763,6779,6781,6791,6793,6803,6823,6827,6829,6833
,6841,6857,6863,6869,6871,6883,6899,6907,6911,6917
,6947,6949,6959,6961,6967,6971,6977,6983,6991,6997
,7001,7013,7019,7027,7039,7043,7057,7069,7079,7103
,7109,7121,7127,7129,7151,7159,7177,7187,7193,7207
,7211,7213,7219,7229,7237,7243,7247,7253,7283,7297
,7307,7309,7321,7331,7333,7349,7351,7369,7393,7411
,7417,7433,7451,7457,7459,7477,7481,7487,7489,7499
,7507,7517,7523,7529,7537,7541,7547,7549,7559,7561
,7573,7577,7583,7589,7591,7603,7607,7621,7639,7643
,7649,7669,7673,7681,7687,7691,7699,7703,7717,7723
,7727,7741,7753,7757,7759,7789,7793,7817,7823,7829
,7841,7853,7867,7873,7877,7879,7883,7901,7907,7919
,7927,7933,7937,7949,7951,7963,7993,8009,8011,8017
,8039,8053,8059,8069,8081,8087,8089,8093,8101,8111
,8117,8123,8147,8161,8167,8171,8179,8191,8209,8219
,8221,8231,8233,8237,8243,8263,8269,8273,8287,8291
,8293,8297,8311,8317,8329,8353,8363,8369,8377,8387
,8389,8419,8423,8429,8431,8443,8447,8461,8467,8501
,8513,8521,8527,8537,8539,8543,8563,8573,8581,8597
,8599,8609,8623,8627,8629,8641,8647,8663,8669,8677
,8681,8689,8693,8699,8707,8713,8719,8731,8737,8741
,8747,8753,8761,8779,8783,8803,8807,8819,8821,8831
,8837,8839,8849,8861,8863,8867,8887,8893,8923,8929
,8933,8941,8951,8963,8969,8971,8999,9001,9007,9011
,9013,9029,9041,9043,9049,9059,9067,9091,9103,9109
,9127,9133,9137,9151,9157,9161,9173,9181,9187,9199
,9203,9209,9221,9227,9239,9241,9257,9277,9281,9283
,9293,9311,9319,9323,9337,9341,9343,9349,9371,9377
,9391,9397,9403,9413,9419,9421,9431,9433,9437,9439
,9461,9463,9467,9473,9479,9491,9497,9511,9521,9533
,9539,9547,9551,9587,9601,9613,9619,9623,9629,9631
,9643,9649,9661,9677,9679,9689,9697,9719,9721,9733
,9739,9743,9749,9767,9769,9781,9787,9791,9803,9811
,9817,9829,9833,9839,9851,9857,9859,9871,9883,9887
,9901,9907,9923,9929,9931,9941,9949,9967,9973,10007
,10009,10037,10039,10061,10067,10069,10079,10091,10093,10099
,10103,10111,10133,10139,10141,10151,10159,10163,10169,10177
,10181,10193,10211,10223,10243,10247,10253,10259,10267,10271
,10273,10289,10301,10303,10313,10321,10331,10333,10337,10343
,10357,10369,10391,10399,10427,10429,10433,10453,10457,10459
,10463,10477,10487,10499,10501,10513,10529,10531,10559,10567
,10589,10597,10601,10607,10613,10627,10631,10639,10651,10657
,10663,10667,10687,10691,10709,10711,10723,10729,10733,10739
,10753,10771,10781,10789,10799,10831,10837,10847,10853,10859
,10861,10867,10883,10889,10891,10903,10909,10937,10939,10949
,10957,10973,10979,10987,10993,11003,11027,11047,11057,11059
,11069,11071,11083,11087,11093,11113,11117,11119,11131,11149
,11159,11161,11171,11173,11177,11197,11213,11239,11243,11251
,11257,11261,11273,11279,11287,11299,11311,11317,11321,11329
,11351,11353,11369,11383,11393,11399,11411,11423,11437,11443
,11447,11467,11471,11483,11489,11491,11497,11503,11519,11527
,11549,11551,11579,11587,11593,11597,11617,11621,11633,11657
,11677,11681,11689,11699,11701,11717,11719,11731,11743,11777
,11779,11783,11789,11801,11807,11813,11821,11827,11831,11833
,11839,11863,11867,11887,11897,11903,11909,11923,11927,11933
,11939,11941,11953,11959,11969,11971,11981,11987,12007,12011
,12037,12041,12043,12049,12071,12073,12097,12101,12107,12109
,12113,12119,12143,12149,12157,12161,12163,12197,12203,12211
,12227,12239,12241,12251,12253,12263,12269,12277,12281,12289
,12301,12323,12329,12343,12347,12373,12377,12379,12391,12401
,12409,12413,12421,12433,12437,12451,12457,12473,12479,12487
,12491,12497,12503,12511,12517,12527,12539,12541,12547,12553
,12569,12577,12583,12589,12601,12611,12613,12619,12637,12641
,12647,12653,12659,12671,12689,12697,12703,12713,12721,12739
,12743,12757,12763,12781,12791,12799,12809,12821,12823,12829
,12841,12853,12889,12893,12899,12907,12911,12917,12919,12923
,12941,12953,12959,12967,12973,12979,12983,13001,13003,13007
,13009,13033,13037,13043,13049,13063,13093,13099,13103,13109
,13121,13127,13147,13151,13159,13163,13171,13177,13183,13187
,13217,13219,13229,13241,13249,13259,13267,13291,13297,13309
,13313,13327,13331,13337,13339,13367,13381,13397,13399,13411
,13417,13421,13441,13451,13457,13463,13469,13477,13487,13499
,13513,13523,13537,13553,13567,13577,13591,13597,13613,13619
,13627,13633,13649,13669,13679,13681,13687,13691,13693,13697
,13709,13711,13721,13723,13729,13751,13757,13759,13763,13781
,13789,13799,13807,13829,13831,13841,13859,13873,13877,13879
,13883,13901,13903,13907,13913,13921,13931,13933,13963,13967
,13997,13999,14009,14011,14029,14033,14051,14057,14071,14081
,14083,14087,14107,14143,14149,14153,14159,14173,14177,14197
,14207,14221,14243,14249,14251,14281,14293,14303,14321,14323
,14327,14341,14347,14369,14387,14389,14401,14407,14411,14419
,14423,14431,14437,14447,14449,14461,14479,14489,14503,14519
,14533,14537,14543,14549,14551,14557,14561,14563,14591,14593
,14621,14627,14629,14633,14639,14653,14657,14669,14683,14699
,14713,14717,14723,14731,14737,14741,14747,14753,14759,14767
,14771,14779,14783,14797,14813,14821,14827,14831,14843,14851
,14867,14869,14879,14887,14891,14897,14923,14929,14939,14947
,14951,14957,14969,14983,15013,15017,15031,15053,15061,15073
,15077,15083,15091,15101,15107,15121,15131,15137,15139,15149
,15161,15173,15187,15193,15199,15217,15227,15233,15241,15259
,15263,15269,15271,15277,15287,15289,15299,15307,15313,15319
,15329,15331,15349,15359,15361,15373,15377,15383,15391,15401
,15413,15427,15439,15443,15451,15461,15467,15473,15493,15497
,15511,15527,15541,15551,15559,15569,15581,15583,15601,15607
,15619,15629,15641,15643,15647,15649,15661,15667,15671,15679
,15683,15727,15731,15733,15737,15739,15749,15761,15767,15773
,15787,15791,15797,15803,15809,15817,15823,15859,15877,15881
,15887,15889,15901,15907,15913,15919,15923,15937,15959,15971
,15973,15991,16001,16007,16033,16057,16061,16063,16067,16069
,16073,16087,16091,16097,16103,16111,16127,16139,16141,16183
,16187,16189,16193,16217,16223,16229,16231,16249,16253,16267
,16273,16301,16319,16333,16339,16349,16361,16363,16369,16381
,16411,16417,16421,16427,16433,16447,16451,16453,16477,16481
,16487,16493,16519,16529,16547,16553,16561,16567,16573,16603
,16607,16619,16631,16633,16649,16651,16657,16661,16673,16691
,16693,16699,16703,16729,16741,16747,16759,16763,16787,16811
,16823,16829,16831,16843,16871,16879,16883,16889,16901,16903
,16921,16927,16931,16937,16943,16963,16979,16981,16987,16993
,17011,17021,17027,17029,17033,17041,17047,17053,17077,17093
,17099,17107,17117,17123,17137,17159,17167,17183,17189,17191
,17203,17207,17209,17231,17239,17257,17291,17293,17299,17317
,17321,17327,17333,17341,17351,17359,17377,17383,17387,17389
,17393,17401,17417,17419,17431,17443,17449,17467,17471,17477
,17483,17489,17491,17497,17509,17519,17539,17551,17569,17573
,17579,17581,17597,17599,17609,17623,17627,17657,17659,17669
,17681,17683,17707,17713,17729,17737,17747,17749,17761,17783
,17789,17791,17807,17827,17837,17839,17851,17863,17881,17891
,17903,17909,17911,17921,17923,17929,17939,17957,17959,17971
,17977,17981,17987,17989,18013,18041,18043,18047,18049,18059
,18061,18077,18089,18097,18119,18121,18127,18131,18133,18143
,18149,18169,18181,18191,18199,18211,18217,18223,18229,18233
,18251,18253,18257,18269,18287,18289,18301,18307,18311,18313
,18329,18341,18353,18367,18371,18379,18397,18401,18413,18427
,18433,18439,18443,18451,18457,18461,18481,18493,18503,18517
,18521,18523,18539,18541,18553,18583,18587,18593,18617,18637
,18661,18671,18679,18691,18701,18713,18719,18731,18743,18749
,18757,18773,18787,18793,18797,18803,18839,18859,18869,18899
,18911,18913,18917,18919,18947,18959,18973,18979,19001,19009
,19013,19031,19037,19051,19069,19073,19079,19081,19087,19121
,19139,19141,19157,19163,19181,19183,19207,19211,19213,19219
,19231,19237,19249,19259,19267,19273,19289,19301,19309,19319
,19333,19373,19379,19381,19387,19391,19403,19417,19421,19423
,19427,19429,19433,19441,19447,19457,19463,19469,19471,19477
,19483,19489,19501,19507,19531,19541,19543,19553,19559,19571
,19577,19583,19597,19603,19609,19661,19681,19687,19697,19699
,19709,19717,19727,19739,19751,19753,19759,19763,19777,19793
,19801,19813,19819,19841,19843,19853,19861,19867,19889,19891
,19913,19919,19927,19937,19949,19961,19963,19973,19979,19991
,19993,19997,20011,20021,20023,20029,20047,20051,20063,20071
,20089,20101,20107,20113,20117,20123,20129,20143,20147,20149
,20161,20173,20177,20183,20201,20219,20231,20233,20249,20261
,20269,20287,20297,20323,20327,20333,20341,20347,20353,20357
,20359,20369,20389,20393,20399,20407,20411,20431,20441,20443
,20477,20479,20483,20507,20509,20521,20533,20543,20549,20551
,20563,20593,20599,20611,20627,20639,20641,20663,20681,20693
,20707,20717,20719,20731,20743,20747,20749,20753,20759,20771
,20773,20789,20807,20809,20849,20857,20873,20879,20887,20897
,20899,20903,20921,20929,20939,20947,20959,20963,20981,20983
,21001,21011,21013,21017,21019,21023,21031,21059,21061,21067
,21089,21101,21107,21121,21139,21143,21149,21157,21163,21169
,21179,21187,21191,21193,21211,21221,21227,21247,21269,21277
,21283,21313,21317,21319,21323,21341,21347,21377,21379,21383
,21391,21397,21401,21407,21419,21433,21467,21481,21487,21491
,21493,21499,21503,21517,21521,21523,21529,21557,21559,21563
,21569,21577,21587,21589,21599,21601,21611,21613,21617,21647
,21649,21661,21673,21683,21701,21713,21727,21737,21739,21751
,21757,21767,21773,21787,21799,21803,21817,21821,21839,21841
,21851,21859,21863,21871,21881,21893,21911,21929,21937,21943
,21961,21977,21991,21997,22003,22013,22027,22031,22037,22039
,22051,22063,22067,22073,22079,22091,22093,22109,22111,22123
,22129,22133,22147,22153,22157,22159,22171,22189,22193,22229
,22247,22259,22271,22273,22277,22279,22283,22291,22303,22307
,22343,22349,22367,22369,22381,22391,22397,22409,22433,22441
,22447,22453,22469,22481,22483,22501,22511,22531,22541,22543
,22549,22567,22571,22573,22613,22619,22621,22637,22639,22643
,22651,22669,22679,22691,22697,22699,22709,22717,22721,22727
,22739,22741,22751,22769,22777,22783,22787,22807,22811,22817
,22853,22859,22861,22871,22877,22901,22907,22921,22937,22943
,22961,22963,22973,22993,23003,23011,23017,23021,23027,23029
,23039,23041,23053,23057,23059,23063,23071,23081,23087,23099
,23117,23131,23143,23159,23167,23173,23189,23197,23201,23203
,23209,23227,23251,23269,23279,23291,23293,23297,23311,23321
,23327,23333,23339,23357,23369,23371,23399,23417,23431,23447
,23459,23473,23497,23509,23531,23537,23539,23549,23557,23561
,23563,23567,23581,23593,23599,23603,23609,23623,23627,23629
,23633,23663,23669,23671,23677,23687,23689,23719,23741,23743
,23747,23753,23761,23767,23773,23789,23801,23813,23819,23827
,23831,23833,23857,23869,23873,23879,23887,23893,23899,23909
,23911,23917,23929,23957,23971,23977,23981,23993,24001,24007
,24019,24023,24029,24043,24049,24061,24071,24077,24083,24091
,24097,24103,24107,24109,24113,24121,24133,24137,24151,24169
,24179,24181,24197,24203,24223,24229,24239,24247,24251,24281
,24317,24329,24337,24359,24371,24373,24379,24391,24407,24413
,24419,24421,24439,24443,24469,24473,24481,24499,24509,24517
,24527,24533,24547,24551,24571,24593,24611,24623,24631,24659
,24671,24677,24683,24691,24697,24709,24733,24749,24763,24767
,24781,24793,24799,24809,24821,24841,24847,24851,24859,24877
,24889,24907,24917,24919,24923,24943,24953,24967,24971,24977
,24979,24989,25013,25031,25033,25037,25057,25073,25087,25097
,25111,25117,25121,25127,25147,25153,25163,25169,25171,25183
,25189,25219,25229,25237,25243,25247,25253,25261,25301,25303
,25307,25309,25321,25339,25343,25349,25357,25367,25373,25391
,25409,25411,25423,25439,25447,25453,25457,25463,25469,25471
,25523,25537,25541,25561,25577,25579,25583,25589,25601,25603
,25609,25621,25633,25639,25643,25657,25667,25673,25679,25693
,25703,25717,25733,25741,25747,25759,25763,25771,25793,25799
,25801,25819,25841,25847,25849,25867,25873,25889,25903,25913
,25919,25931,25933,25939,25943,25951,25969,25981,25997,25999
,26003,26017,26021,26029,26041,26053,26083,26099,26107,26111
,26113,26119,26141,26153,26161,26171,26177,26183,26189,26203
,26209,26227,26237,26249,26251,26261,26263,26267,26293,26297
,26309,26317,26321,26339,26347,26357,26371,26387,26393,26399
,26407,26417,26423,26431,26437,26449,26459,26479,26489,26497
,26501,26513,26539,26557,26561,26573,26591,26597,26627,26633
,26641,26647,26669,26681,26683,26687,26693,26699,26701,26711
,26713,26717,26723,26729,26731,26737,26759,26777,26783,26801
,26813,26821,26833,26839,26849,26861,26863,26879,26881,26891
,26893,26903,26921,26927,26947,26951,26953,26959,26981,26987
,26993,27011,27017,27031,27043,27059,27061,27067,27073,27077
,27091,27103,27107,27109,27127,27143,27179,27191,27197,27211
,27239,27241,27253,27259,27271,27277,27281,27283,27299,27329
,27337,27361,27367,27397,27407,27409,27427,27431,27437,27449
,27457,27479,27481,27487,27509,27527,27529,27539,27541,27551
,27581,27583,27611,27617,27631,27647,27653,27673,27689,27691
,27697,27701,27733,27737,27739,27743,27749,27751,27763,27767
,27773,27779,27791,27793,27799,27803,27809,27817,27823,27827
,27847,27851,27883,27893,27901,27917,27919,27941,27943,27947
,27953,27961,27967,27983,27997,28001,28019,28027,28031,28051
,28057,28069,28081,28087,28097,28099,28109,28111,28123,28151
,28163,28181,28183,28201,28211,28219,28229,28277,28279,28283
,28289,28297,28307,28309,28319,28349,28351,28387,28393,28403
,28409,28411,28429,28433,28439,28447,28463,28477,28493,28499
,28513,28517,28537,28541,28547,28549,28559,28571,28573,28579
,28591,28597,28603,28607,28619,28621,28627,28631,28643,28649
,28657,28661,28663,28669,28687,28697,28703,28711,28723,28729
,28751,28753,28759,28771,28789,28793,28807,28813,28817,28837
,28843,28859,28867,28871,28879,28901,28909,28921,28927,28933
,28949,28961,28979,29009,29017,29021,29023,29027,29033,29059
,29063,29077,29101,29123,29129,29131,29137,29147,29153,29167
,29173,29179,29191,29201,29207,29209,29221,29231,29243,29251
,29269,29287,29297,29303,29311,29327,29333,29339,29347,29363
,29383,29387,29389,29399,29401,29411,29423,29429,29437,29443
,29453,29473,29483,29501,29527,29531,29537,29567,29569,29573
,29581,29587,29599,29611,29629,29633,29641,29663,29669,29671
,29683,29717,29723,29741,29753,29759,29761,29789,29803,29819
,29833,29837,29851,29863,29867,29873,29879,29881,29917,29921
,29927,29947,29959,29983,29989,30011,30013,30029,30047,30059
,30071,30089,30091,30097,30103,30109,30113,30119,30133,30137
,30139,30161,30169,30181,30187,30197,30203,30211,30223,30241
,30253,30259,30269,30271,30293,30307,30313,30319,30323,30341
,30347,30367,30389,30391,30403,30427,30431,30449,30467,30469
,30491,30493,30497,30509,30517,30529,30539,30553,30557,30559
,30577,30593,30631,30637,30643,30649,30661,30671,30677,30689
,30697,30703,30707,30713,30727,30757,30763,30773,30781,30803
,30809,30817,30829,30839,30841,30851,30853,30859,30869,30871
,30881,30893,30911,30931,30937,30941,30949,30971,30977,30983
,31013,31019,31033,31039,31051,31063,31069,31079,31081,31091
,31121,31123,31139,31147,31151,31153,31159,31177,31181,31183
,31189,31193,31219,31223,31231,31237,31247,31249,31253,31259
,31267,31271,31277,31307,31319,31321,31327,31333,31337,31357
,31379,31387,31391,31393,31397,31469,31477,31481,31489,31511
,31513,31517,31531,31541,31543,31547,31567,31573,31583,31601
,31607};
long int m,n,i,diff,c,x;
scanf("%d",&t);
while(t)
{
char bool2[100000]={0};   
scanf("%ld%ld",&m,&n);
diff=n-m;
c=sqrt(n);  			
j=0;					
if(m==1)
{
bool2[0]=1;				
}
while(1)		
{
  x=m%p[j];
  if(x==0)
  {
	if(m==p[j])
	i=p[j];
	else
	i=0;
  }
  else
   if(m+(p[j]-x)==p[j])
  {
  i=2*p[j]-x;
  }
  else
  i=p[j]-x;
		for(;i<=diff;i+=p[j])
		{
		bool2[i]=1;
		}
	j++;		
	if((p[j]>c)||(j>3400))
	break;
}
for(i=0;i<=diff;i++)
{
	if(!bool2[i])
   writeint(m+i);		
}
buf[bp++]='\n';
flushbuf();
t--;
}
 
return 0;
}
Esempio n. 16
0
void
main(int argc, char **argv)
{
	int omode;
	volatile int quiet;
	char *s;
	char *name;

	quiet = 0;
	name = 0;
	outputinit();
	maxoff = MAXOFF;
	omode = OREAD;
	ARGBEGIN{
	default:
		usage();
	case 'A':
		abort();
	case 'k':
		kflag = 1;
		break;
	case 'w':
		omode = ORDWR;
		break;
	case 'I':
		s = ARGF();
		if(s == 0)
			dprint("missing -I argument\n");
		else
			Ipath = s;
		break;
	case 'm':
		name = ARGF();
		if(name == 0)
			dprint("missing -m argument\n");
		break;
	case 'q':
		quiet = 1;
		break;
	}ARGEND

	attachargs(argc, argv, omode, !quiet);

	dotmap = dumbmap(-1);

	/*
	 * show initial state and drop into the execution loop.
	 */
	notify(fault);
	setsym();
	if(setjmp(env) == 0){
		if (pid || corhdr)
			setcor();	/* could get error */
		if (correg && !quiet) {
			dprint("%s\n", mach->exc(cormap, correg));
			printpc();
		}
	}

	setjmp(env);
	if (executing)
		delbp();
	executing = FALSE;
	for (;;) {
		flushbuf();
		if (errmsg) {
			dprint(errmsg);
			printc('\n');
			errmsg = 0;
			exitflg = 0;
		}
		if (mkfault) {
			mkfault=0;
			printc('\n');
			prints(DBNAME);
		}
		clrinp();
		rdc();
		reread();
		if (eof) {
			if (infile == STDIN)
				done();
			iclose(-1, 0);
			eof = 0;
			longjmp(env, 1);
		}
		exitflg = 0;
		command(0, 0);
		reread();
		if (rdc() != '\n')
			error("newline expected");
	}
}
Esempio n. 17
0
scrinterp::~scrinterp()
{
  flushbuf();
  delete[] chrbuf;
}
Esempio n. 18
0
static void dopop(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
{
  int opcode;
  int arg16;
  int arg16a;
  int arg16b;

  /* We have found PUSHS.  No search for the next occurrence
   * of either and instruction that increments the string
   * stack or for the matching POPS
   */

  /* Skip over the PUSHS for now */

  inch = poffGetProgByte(poffHandle);

  while (inch != EOF)
    {
      /* Did we encounter another PUSHS? */

      if (inch == oPUSHS)
        {
          /* Yes... recurse to handle it */

          current_level++;
          dopop(poffHandle, poffProgHandle);
          current_level--;
        }

      else if (inch == oPOPS)
        {
          /* Flush the buffered data without the PUSHS */

          flushbuf(poffProgHandle);

          /* And discard the matching POPS */

          inch = poffGetProgByte(poffHandle);
          break;
        }
      else if (inch == oLIB)
        {
          /* Get the 16-bit argument */

          putbuf(inch, poffProgHandle);
          arg16a = poffGetProgByte(poffHandle);
          putbuf(arg16a, poffProgHandle);
          arg16b = poffGetProgByte(poffHandle);
          putbuf(arg16b, poffProgHandle);
          arg16  = (arg16a << 8) | arg16b;
          inch   = poffGetProgByte(poffHandle);

          /* Is it LIB MKSTK? MKSTKSTR? or MKSTKC? */

          if ((arg16 == lbMKSTK) ||
              (arg16 == lbMKSTKSTR) ||
              (arg16 == lbMKSTKC))
            {
              /* Flush the buffered data with the PUSHS */

              flushc(oPUSHS, poffProgHandle);
              flushbuf(poffProgHandle);

              /* And break out of the loop to search for
               * the next PUSHS
               */

              break;
            }
        }
      else
        {
          /* Something else.  Put it in the buffer */

          putbuf(inch, poffProgHandle);

          /* Get the next byte from the input stream */

          opcode = inch;
          inch = poffGetProgByte(poffHandle);

          /* Check for an 8-bit argument */

          if ((opcode & o8) != 0)
            {
              /* Buffer the 8-bit argument */

              putbuf(inch, poffProgHandle);
              inch = poffGetProgByte(poffHandle);
            }

          /* Check for a 16-bit argument */

          if ((opcode & o16) != 0)
            {
              /* Buffer the 16-bit argument */

              putbuf(inch, poffProgHandle);
              inch = poffGetProgByte(poffHandle);
              putbuf(inch, poffProgHandle);
              inch = poffGetProgByte(poffHandle);
            }
        }
    }
}
Esempio n. 19
0
int main(int argc, char *argv[])
#endif
{
    u8 sta = 0, cmd;
    int i;

#ifndef __AVR__
    if (argc > 3 || argc < 2) {
        printf("Usage: (sudo) testfat rawdevice  e.g. fat32 /dev/sdb \r\n");
        return 1;
    }
    //    fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
    if (initsec(argv[1]))
        return -1;
#endif

    hwinit();

    printf("\nFAT32 Test\n");
    i = sdhcinit();
    printf("init %d\n", i);
    if (!i) {
        printf( "%lu sects\n", sdnumsectors );
        i = mount(0);
        printf("Mount: %d\n", i);
        if (!i)
            seekfile(0, 0);
#if 1                           // show what is read
        else
            for (i = 0; i < 1; i++) {
                readsec(i);
                dumpsect();
            }
#endif
    }
    if (i)
        printf("Not Ready\n");

    for (;;) {
        cmd = tzgetchar();
        if (cmd >= 'a')
            cmd -= 32;
        switch (cmd) {
#ifdef __AVR__
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            //            while (!tzkbhit()) {
                ADMUX = 0xe0 + cmd - '0';
                ADCSRA = 0xc7;
                while (ADCSRA & 0x40);
                printf("%c %04x\n", cmd, ADC);
                //            }
            break;
#endif
        case 3:
        case 26:
        case 'Q':
            exit(0);
        case 'Y':
            {
                u16 u;
                u = getdirent((u8 *) "");
                printf("%u entries in dir\n", u);
            }
            break;
        case 'I':
            sta = sdhcinit();
            printf("init %d\n", sta);
            if (sta)
                continue;
            printf( "%lu sects\n", sdnumsectors );
            sta = cardinfo(0);
            printf("inf %d\n", sta);
            if (sta)
                continue;
            for (sta = 0; sta < 18; sta++)
                printf("%02X", filesectbuf[sta]);
            printf(" ");
            for (sta = 0; sta < 18; sta++)
                printf("%c", dochar(filesectbuf[sta]));
            printf("\n");
            sta = cardinfo(1);
            printf("inf %d\n", sta);
            if (sta)
                continue;
            for (sta = 0; sta < 18; sta++)
                printf("%02X", filesectbuf[sta]);
            printf(" ");
            for (sta = 0; sta < 18; sta++)
                printf("%c", dochar(filesectbuf[sta]));
            printf("\n");
            break;
        case 'M':
            i = mount(0);
            if (!i)
                printf("Mounted\n");
            else
                printf("Error\n");
            break;
        case 'O':
            printf("Open:\n");
            i = getfname();
            if (i < 0) {
                printf("bad fname\n");
                break;
            }
            i = getdirent(filename);
            if (i == 2)
                printf("Entered Dir\n");
            else if (!i)
                printf("Opened\n");
            else
                printf("Not Found\n");
            break;
        case 'C':
            printf("Create:\n");
            i = getfname();
            if (i < 0) {
                printf("bad fname\n");
                break;
            }
            if (i == 1) {
                printf("Directory:\n");
                i = getfname();
                if (i) {
                    printf("bad fname\n");
                    break;
                }
                i = 0x10;       // directory attribute
            }
            i = newdirent(filename, i);
            if (!i)
                printf("Created\n");
            else if (i == 2)
                printf("Exists\n");
            else
                printf("Error\n");
            break;
        case 'N':
            i = newdirent(NULL, 0);
            if (!i)
                printf("Created Ser Log\n");
            else
                printf("Error\n");
            break;
        case 'L':
            resettodir();
            seekfile(0, 0);
            for (i = 0; i < 16; i++) {
                if (!filesectbuf[i << 5])
                    break;
                if (0xe5 == filesectbuf[i << 5]) {
                    printf("(del)\n");
                    continue;
                }
                if (0xf == filesectbuf[(i << 5) + 11]) {
                    printf("(lfn)\n");
                    continue;
                }
                printf("%8.8s.%3.3s %c\n", &filesectbuf[i << 5], &filesectbuf[(i << 5) + 8],
                  filesectbuf[(i << 5) + 11] & 0x10 ? '/' : ' ');
                if (i == 15) {
                    i = readnextsect();
                    if (i != 512)
                        break;
                    i = -1;
                }
            }
            break;
        case 'W':
            printf("Write: ^c|^z to exit\n");
            for (;;) {
                char cx;
                cx = tzgetchar();
                if (cx == 3 || cx == 26)
                    break;
                writebyte(cx);
                printf("%c", cx);
            }
            printf("\nWritten ");
            flushbuf();
            printf("Flushed ");
            syncdirent(0);
            printf("DSynced\n");
            break;
        case 'F':
            flushbuf();
            printf("Flushed\n");
            break;
        case 'E':
            syncdirent(0);
            printf("dirsynced\n");
            break;
        case 'P':
            syncdirent(1);
            printf("size pushed\n");
            break;
        case 'Z':
            zaphint();
            printf("hint zapped\n");
            break;
        case 'T':
            truncatefile();
            printf("Trunc-ed\n");
            break;
        case 'D':
            i = deletefile();
            if (i == 1)
                printf("no rmdir\n");
            else if (!i)
                printf("Deleted\n");
            else
                printf("Error\n");
            break;
            // will go away when seek is filled in
        case 'A':
            seekfile(0, 2);
            printf("At EOF\n");
            break;
        case 'S':
            {
                u32 x = 0;
                u8 y = 1;
                seekfile(x, y);
                printf("Rewound\n");
            }
            break;
        case 'R':
        case 'V':
        case 'X':
            sta = 0;
            while (!tzkbhit()) {
                i = readbyte();
                if (i < 0) {
                    printf("\n=EOF=\n");
                    break;
                }
                switch (cmd) {
                case 'R':
                    printf("%c", i);
                    break;
                case 'V':
                    printf("%c", dochar(i));
                    break;
                case 'X':
                    if (!(sta++ & 15))
                        printf("\n");
                    printf("%02X", i);
                    break;
                }
            }
            break;
        case 'U':
            resetrootdir();
            seekfile(0, 0);     // for list
            printf("At rootdir\n");
            break;
        case 'G':
            resettodir();
            seekfile(0, 0);     // for list
            printf("At curdir\n");
            break;

        default:
            // help message
            {
                char *c = mainmenu;
                while (pgm_read_byte(c))
                    putchar(pgm_read_byte(c++));
            }
            break;
        }
    }
}
Esempio n. 20
0
int
main(int argc, char **argv)
{
    struct sockaddr_in6 sin6;
    int rc, fd, i, opt;
    time_t expiry_time, source_expiry_time, kernel_dump_time;
    const char **config_files = NULL;
    int num_config_files = 0;
    void *vrc;
    unsigned int seed;
    struct interface *ifp;

    gettime(&now);

    rc = read_random_bytes(&seed, sizeof(seed));
    if(rc < 0) {
        perror("read(random)");
        seed = 42;
    }

    seed ^= (now.tv_sec ^ now.tv_usec);
    srandom(seed);

    parse_address("ff02:0:0:0:0:0:1:6", protocol_group, NULL);
    protocol_port = 6696;
    change_smoothing_half_life(4);
    has_ipv6_subtrees = kernel_has_ipv6_subtrees();

    while(1) {
        opt = getopt(argc, argv,
                     "m:p:h:H:i:k:A:sruS:d:g:G:lwz:M:t:T:c:C:DL:I:V");
        if(opt < 0)
            break;

        switch(opt) {
        case 'm':
            rc = parse_address(optarg, protocol_group, NULL);
            if(rc < 0)
                goto usage;
            if(protocol_group[0] != 0xff) {
                fprintf(stderr,
                        "%s is not a multicast address\n", optarg);
                goto usage;
            }
            if(protocol_group[1] != 2) {
                fprintf(stderr,
                        "Warning: %s is not a link-local multicast address\n",
                        optarg);
            }
            break;
        case 'p':
            protocol_port = parse_nat(optarg);
            if(protocol_port <= 0 || protocol_port > 0xFFFF)
                goto usage;
            break;
        case 'h':
            default_wireless_hello_interval = parse_thousands(optarg);
            if(default_wireless_hello_interval <= 0 ||
               default_wireless_hello_interval > 0xFFFF * 10)
                goto usage;
            break;
        case 'H':
            default_wired_hello_interval = parse_thousands(optarg);
            if(default_wired_hello_interval <= 0 ||
               default_wired_hello_interval > 0xFFFF * 10)
                goto usage;
            break;
        case 'k':
            kernel_metric = parse_nat(optarg);
            if(kernel_metric < 0 || kernel_metric > 0xFFFF)
                goto usage;
            break;
        case 'A':
            allow_duplicates = parse_nat(optarg);
            if(allow_duplicates < 0 || allow_duplicates > 0xFFFF)
                goto usage;
            break;
        case 's':
            split_horizon = 0;
            break;
        case 'r':
            random_id = 1;
            break;
        case 'u':
            keep_unfeasible = 1;
            break;
        case 'S':
            state_file = optarg;
            break;
        case 'd':
            debug = parse_nat(optarg);
            if(debug < 0)
                goto usage;
            break;
        case 'g':
        case 'G':
            if(opt == 'g')
                local_server_write = 0;
            else
                local_server_write = 1;
            if(optarg[0] == '/') {
                local_server_port = -1;
                free(local_server_path);
                local_server_path = strdup(optarg);
            } else {
                local_server_port = parse_nat(optarg);
                free(local_server_path);
                local_server_path = NULL;
                if(local_server_port <= 0 || local_server_port > 0xFFFF)
                    goto usage;
            }
            break;
        case 'l':
            link_detect = 1;
            break;
        case 'w':
            all_wireless = 1;
            break;
        case 'z':
            {
                char *comma;
                diversity_kind = (int)strtol(optarg, &comma, 0);
                if(*comma == '\0')
                    diversity_factor = 128;
                else if(*comma == ',')
                    diversity_factor = parse_nat(comma + 1);
                else
                    goto usage;
                if(diversity_factor <= 0 || diversity_factor > 256)
                    goto usage;
            }
            break;
        case 'M': {
            int l = parse_nat(optarg);
            if(l < 0 || l > 3600)
                goto usage;
            change_smoothing_half_life(l);
            break;
        }
        case 't':
            export_table = parse_nat(optarg);
            if(export_table < 0 || export_table > 0xFFFF)
                goto usage;
            break;
        case 'T':
            if(add_import_table(parse_nat(optarg)))
                goto usage;
            break;
        case 'c':
            config_files = realloc(config_files,
                                   (num_config_files + 1) * sizeof(char*));
            if(config_files == NULL) {
                fprintf(stderr, "Couldn't allocate config file.\n");
                exit(1);
            }
            config_files[num_config_files++] = optarg;
            break;
        case 'C':
            rc = parse_config_from_string(optarg, strlen(optarg), NULL);
            if(rc != CONFIG_ACTION_DONE) {
                fprintf(stderr,
                        "Couldn't parse configuration from command line.\n");
                exit(1);
            }
            break;
        case 'D':
            do_daemonise = 1;
            break;
        case 'L':
            logfile = optarg;
            break;
        case 'I':
            pidfile = optarg;
            break;
        case 'V':
            fprintf(stderr, "%s\n", BABELD_VERSION);
            exit(0);
            break;
        default:
            goto usage;
        }
    }

    if(num_config_files == 0) {
        if(access("/etc/babeld.conf", F_OK) >= 0) {
            config_files = malloc(sizeof(char*));
            if(config_files == NULL) {
                fprintf(stderr, "Couldn't allocate config file.\n");
                exit(1);
            }
            config_files[num_config_files++] = "/etc/babeld.conf";
        }
    }

    for(i = 0; i < num_config_files; i++) {
        int line;
        rc = parse_config_from_file(config_files[i], &line);
        if(rc < 0) {
            fprintf(stderr,
                    "Couldn't parse configuration from file %s "
                    "(error at line %d).\n",
                    config_files[i], line);
            exit(1);
        }
    }

    free(config_files);

    if(default_wireless_hello_interval <= 0)
        default_wireless_hello_interval = 4000;
    default_wireless_hello_interval = MAX(default_wireless_hello_interval, 5);

    if(default_wired_hello_interval <= 0)
        default_wired_hello_interval = 4000;
    default_wired_hello_interval = MAX(default_wired_hello_interval, 5);

    resend_delay = 2000;
    resend_delay = MIN(resend_delay, default_wireless_hello_interval / 2);
    resend_delay = MIN(resend_delay, default_wired_hello_interval / 2);
    resend_delay = MAX(resend_delay, 20);

    if(do_daemonise) {
        if(logfile == NULL)
            logfile = "/var/log/babeld.log";
    }

    rc = reopen_logfile();
    if(rc < 0) {
        perror("reopen_logfile()");
        exit(1);
    }

    fd = open("/dev/null", O_RDONLY);
    if(fd < 0) {
        perror("open(null)");
        exit(1);
    }

    rc = dup2(fd, 0);
    if(rc < 0) {
        perror("dup2(null, 0)");
        exit(1);
    }

    close(fd);

    if(do_daemonise) {
        rc = daemonise();
        if(rc < 0) {
            perror("daemonise");
            exit(1);
        }
    }

    if(pidfile && pidfile[0] != '\0') {
        int pfd, len;
        char buf[100];

        len = snprintf(buf, 100, "%lu", (unsigned long)getpid());
        if(len < 0 || len >= 100) {
            perror("snprintf(getpid)");
            exit(1);
        }

        pfd = open(pidfile, O_WRONLY | O_CREAT | O_EXCL, 0644);
        if(pfd < 0) {
            char buf[40];
            snprintf(buf, 40, "creat(%s)", pidfile);
            buf[39] = '\0';
            perror(buf);
            exit(1);
        }

        rc = write(pfd, buf, len);
        if(rc < len) {
            perror("write(pidfile)");
            goto fail_pid;
        }

        close(pfd);
    }

    rc = kernel_setup(1);
    if(rc < 0) {
        fprintf(stderr, "kernel_setup failed.\n");
        goto fail_pid;
    }

    rc = kernel_setup_socket(1);
    if(rc < 0) {
        fprintf(stderr, "kernel_setup_socket failed.\n");
        kernel_setup(0);
        goto fail_pid;
    }

    rc = finalise_config();
    if(rc < 0) {
        fprintf(stderr, "Couldn't finalise configuration.\n");
        goto fail;
    }

    for(i = optind; i < argc; i++) {
        vrc = add_interface(argv[i], NULL);
        if(vrc == NULL)
            goto fail;
    }

    if(interfaces == NULL) {
        fprintf(stderr, "Eek... asked to run on no interfaces!\n");
        goto fail;
    }

    if(!have_id && !random_id) {
        /* We use all available interfaces here, since this increases the
           chances of getting a stable router-id in case the set of Babel
           interfaces changes. */

        for(i = 1; i < 256; i++) {
            char buf[IF_NAMESIZE], *ifname;
            unsigned char eui[8];
            ifname = if_indextoname(i, buf);
            if(ifname == NULL)
                continue;
            rc = if_eui64(ifname, i, eui);
            if(rc < 0)
                continue;
            memcpy(myid, eui, 8);
            have_id = 1;
            break;
        }
    }

    if(!have_id) {
        if(!random_id)
            fprintf(stderr,
                    "Warning: couldn't find router id -- "
                    "using random value.\n");
        rc = read_random_bytes(myid, 8);
        if(rc < 0) {
            perror("read(random)");
            goto fail;
        }
        /* Clear group and global bits */
        myid[0] &= ~3;
    }

    myseqno = (random() & 0xFFFF);

    fd = open(state_file, O_RDONLY);
    if(fd < 0 && errno != ENOENT)
        perror("open(babel-state)");
    rc = unlink(state_file);
    if(fd >= 0 && rc < 0) {
        perror("unlink(babel-state)");
        /* If we couldn't unlink it, it's probably stale. */
        close(fd);
        fd = -1;
    }
    if(fd >= 0) {
        char buf[100];
        int s;
        rc = read(fd, buf, 99);
        if(rc < 0) {
            perror("read(babel-state)");
        } else {
            buf[rc] = '\0';
            rc = sscanf(buf, "%d\n", &s);
            if(rc == 1 && s >= 0 && s <= 0xFFFF) {
                myseqno = seqno_plus(s, 1);
            } else {
                fprintf(stderr, "Couldn't parse babel-state.\n");
            }
        }
        close(fd);
        fd = -1;
    }

    protocol_socket = babel_socket(protocol_port);
    if(protocol_socket < 0) {
        perror("Couldn't create link local socket");
        goto fail;
    }

    if(local_server_port >= 0) {
        local_server_socket = tcp_server_socket(local_server_port, 1);
        if(local_server_socket < 0) {
            perror("local_server_socket");
            goto fail;
        }
    } else if(local_server_path) {
        local_server_socket = unix_server_socket(local_server_path);
        if(local_server_socket < 0) {
            perror("local_server_socket");
            goto fail;
        }
    }

    init_signals();
    rc = resize_receive_buffer(1500);
    if(rc < 0)
        goto fail;
    if(receive_buffer == NULL)
        goto fail;

    check_interfaces();

    rc = check_xroutes(0);
    if(rc < 0)
        fprintf(stderr, "Warning: couldn't check exported routes.\n");
    rc = check_rules();
    if(rc < 0)
        fprintf(stderr, "Warning: couldn't check rules.\n");

    kernel_routes_changed = 0;
    kernel_rules_changed = 0;
    kernel_link_changed = 0;
    kernel_addr_changed = 0;
    kernel_dump_time = now.tv_sec + roughly(30);
    schedule_neighbours_check(5000, 1);
    schedule_interfaces_check(30000, 1);
    expiry_time = now.tv_sec + roughly(30);
    source_expiry_time = now.tv_sec + roughly(300);

    /* Make some noise so that others notice us, and send retractions in
       case we were restarted recently */
    FOR_ALL_INTERFACES(ifp) {
        if(!if_up(ifp))
            continue;
        /* Apply jitter before we send the first message. */
        usleep(roughly(10000));
        gettime(&now);
        send_hello(ifp);
        send_wildcard_retraction(ifp);
    }

    FOR_ALL_INTERFACES(ifp) {
        if(!if_up(ifp))
            continue;
        usleep(roughly(10000));
        gettime(&now);
        send_hello(ifp);
        send_wildcard_retraction(ifp);
        send_self_update(ifp);
        send_request(ifp, NULL, 0, NULL, 0);
        flushupdates(ifp);
        flushbuf(ifp);
    }

    debugf("Entering main loop.\n");

    while(1) {
        struct timeval tv;
        fd_set readfds;

        gettime(&now);

        tv = check_neighbours_timeout;
        timeval_min(&tv, &check_interfaces_timeout);
        timeval_min_sec(&tv, expiry_time);
        timeval_min_sec(&tv, source_expiry_time);
        timeval_min_sec(&tv, kernel_dump_time);
        timeval_min(&tv, &resend_time);
        FOR_ALL_INTERFACES(ifp) {
            if(!if_up(ifp))
                continue;
            timeval_min(&tv, &ifp->flush_timeout);
            timeval_min(&tv, &ifp->hello_timeout);
            timeval_min(&tv, &ifp->update_timeout);
            timeval_min(&tv, &ifp->update_flush_timeout);
        }
        timeval_min(&tv, &unicast_flush_timeout);
        FD_ZERO(&readfds);
        if(timeval_compare(&tv, &now) > 0) {
            int maxfd = 0;
            timeval_minus(&tv, &tv, &now);
            FD_SET(protocol_socket, &readfds);
            maxfd = MAX(maxfd, protocol_socket);
            if(kernel_socket < 0) kernel_setup_socket(1);
            if(kernel_socket >= 0) {
                FD_SET(kernel_socket, &readfds);
                maxfd = MAX(maxfd, kernel_socket);
            }
            if(local_server_socket >= 0 &&
               num_local_sockets < MAX_LOCAL_SOCKETS) {
                FD_SET(local_server_socket, &readfds);
                maxfd = MAX(maxfd, local_server_socket);
            }
            for(i = 0; i < num_local_sockets; i++) {
                FD_SET(local_sockets[i].fd, &readfds);
                maxfd = MAX(maxfd, local_sockets[i].fd);
            }
            rc = select(maxfd + 1, &readfds, NULL, NULL, &tv);
            if(rc < 0) {
                if(errno != EINTR) {
                    perror("select");
                    sleep(1);
                }
                rc = 0;
                FD_ZERO(&readfds);
            }
        }

        gettime(&now);

        if(exiting)
            break;

        if(kernel_socket >= 0 && FD_ISSET(kernel_socket, &readfds)) {
            struct kernel_filter filter = {0};
            filter.route = kernel_route_notify;
            filter.addr = kernel_addr_notify;
            filter.link = kernel_link_notify;
            filter.rule = kernel_rule_notify;
            kernel_callback(&filter);
        }

        if(FD_ISSET(protocol_socket, &readfds)) {
            rc = babel_recv(protocol_socket,
                            receive_buffer, receive_buffer_size,
                            (struct sockaddr*)&sin6, sizeof(sin6));
            if(rc < 0) {
                if(errno != EAGAIN && errno != EINTR) {
                    perror("recv");
                    sleep(1);
                }
            } else {
                FOR_ALL_INTERFACES(ifp) {
                    if(!if_up(ifp))
                        continue;
                    if(ifp->ifindex == sin6.sin6_scope_id) {
                        parse_packet((unsigned char*)&sin6.sin6_addr, ifp,
                                     receive_buffer, rc);
                        VALGRIND_MAKE_MEM_UNDEFINED(receive_buffer,
                                                    receive_buffer_size);
                        break;
                    }
                }
            }
        }

        if(local_server_socket >= 0 && FD_ISSET(local_server_socket, &readfds))
           accept_local_connections();

        i = 0;
        while(i < num_local_sockets) {
            if(FD_ISSET(local_sockets[i].fd, &readfds)) {
                rc = local_read(&local_sockets[i]);
                if(rc <= 0) {
                    if(rc < 0) {
                        if(errno == EINTR || errno == EAGAIN)
                            continue;
                        perror("read(local_socket)");
                    }
                    local_socket_destroy(i);
                }
            }
            i++;
        }

        if(reopening) {
            kernel_dump_time = now.tv_sec;
            check_neighbours_timeout = now;
            expiry_time = now.tv_sec;
            rc = reopen_logfile();
            if(rc < 0) {
                perror("reopen_logfile");
                break;
            }
            reopening = 0;
        }

        if(kernel_link_changed || kernel_addr_changed) {
            check_interfaces();
            kernel_link_changed = 0;
        }

        if(kernel_routes_changed || kernel_addr_changed ||
           kernel_rules_changed || now.tv_sec >= kernel_dump_time) {
            rc = check_xroutes(1);
            if(rc < 0)
                fprintf(stderr, "Warning: couldn't check exported routes.\n");
            rc = check_rules();
            if(rc < 0)
                fprintf(stderr, "Warning: couldn't check rules.\n");
            kernel_routes_changed = kernel_rules_changed =
                kernel_addr_changed = 0;
            if(kernel_socket >= 0)
                kernel_dump_time = now.tv_sec + roughly(300);
            else
                kernel_dump_time = now.tv_sec + roughly(30);
        }

        if(timeval_compare(&check_neighbours_timeout, &now) < 0) {
            int msecs;
            msecs = check_neighbours();
            /* Multiply by 3/2 to allow neighbours to expire. */
            msecs = MAX(3 * msecs / 2, 10);
            schedule_neighbours_check(msecs, 1);
        }

        if(timeval_compare(&check_interfaces_timeout, &now) < 0) {
            check_interfaces();
            schedule_interfaces_check(30000, 1);
        }

        if(now.tv_sec >= expiry_time) {
            expire_routes();
            expire_resend();
            expiry_time = now.tv_sec + roughly(30);
        }

        if(now.tv_sec >= source_expiry_time) {
            expire_sources();
            source_expiry_time = now.tv_sec + roughly(300);
        }

        FOR_ALL_INTERFACES(ifp) {
            if(!if_up(ifp))
                continue;
            if(timeval_compare(&now, &ifp->hello_timeout) >= 0)
                send_hello(ifp);
            if(timeval_compare(&now, &ifp->update_timeout) >= 0)
                send_update(ifp, 0, NULL, 0, NULL, 0);
            if(timeval_compare(&now, &ifp->update_flush_timeout) >= 0)
                flushupdates(ifp);
        }

        if(resend_time.tv_sec != 0) {
            if(timeval_compare(&now, &resend_time) >= 0)
                do_resend();
        }

        if(unicast_flush_timeout.tv_sec != 0) {
            if(timeval_compare(&now, &unicast_flush_timeout) >= 0)
                flush_unicast(1);
        }

        FOR_ALL_INTERFACES(ifp) {
            if(!if_up(ifp))
                continue;
            if(ifp->flush_timeout.tv_sec != 0) {
                if(timeval_compare(&now, &ifp->flush_timeout) >= 0)
                    flushbuf(ifp);
            }
        }

        if(UNLIKELY(debug || dumping)) {
            dump_tables(stdout);
            dumping = 0;
        }
    }
Esempio n. 21
0
void oz_sys_recio_termchnex (OZ_Recio_chnex *recio_chnex, OZ_Recio_filex *recio_filex)

{
  flushbuf (recio_chnex, recio_filex);
  (*(recio_filex -> call -> free)) (recio_filex -> filex, recio_chnex -> chnex, recio_chnex);
}
Esempio n. 22
0
static uLong fillrec (OZ_Recio_chnex *recio_chnex, OZ_Recio_filex *recio_filex, uLong overwrite)

{
  uLong buf_len, rfact, sts;
  OZ_Recio_buf *buf;

  /* Normalize the starting vbn and offset to an recbuffsize boundary */

  recio_chnex -> cur_vbn += recio_chnex -> cur_ofs / recio_filex -> diskblksize;
  recio_chnex -> cur_ofs %= recio_filex -> diskblksize;
  rfact = (recio_chnex -> cur_vbn - 1) % recio_filex -> blockfact;
  recio_chnex -> cur_vbn -= rfact;
  recio_chnex -> cur_ofs += rfact * recio_filex -> diskblksize;

  /* If our current buffer is ok, use it as is (but do check to see if pointer is at the eof) */

  buf = recio_chnex -> cur_buf;
  if ((buf != NULL) && (recio_chnex -> cur_vbn == buf -> buf_vbn)) goto rtn;

  /* Need a different buffer, make sure any pending write has been done and release current buffer */

  sts = flushbuf (recio_chnex, recio_filex);
  if (sts != OZ_SUCCESS) return (sts);

  /* See if it already exists on file's list of block buffers.  If so, point to it and inc ref count. */

  for (buf = recio_filex -> bufs; buf != NULL; buf = buf -> next) {
    if (buf -> buf_vbn == recio_chnex -> cur_vbn) {
      recio_chnex -> cur_buf = buf;
      buf -> refcount ++;
      goto rtn;
    }
  }

  /* Not on files list, allocate a new block buffer */

  buf = (*(recio_filex -> call -> malloc)) (recio_chnex -> chnex, recio_filex -> filex, recio_filex -> recbuffsize + sizeof *buf, __FILE__, __LINE__);

  /* If past eof block, don't read anything */

  buf_len = 0;
  if (recio_chnex -> cur_vbn > recio_filex -> efblk) goto linkit;

  /* If entire record block buffer is before eof, read whole record block buffer */

  buf_len = recio_filex -> recbuffsize;
  if (recio_chnex -> cur_vbn + recio_filex -> blockfact <= recio_filex -> efblk) goto readit;

  /* Eof is somewhere in the block buffer, just read up to the eof point */

  buf_len = (recio_filex -> efblk - recio_chnex -> cur_vbn) * recio_filex -> diskblksize + recio_filex -> efbyt;
  if (buf_len == 0) goto linkit;

  /* Read - only if we won't be overwriting all of it */

readit:
  if ((recio_chnex -> cur_ofs != 0) || (recio_chnex -> cur_ofs + overwrite < buf_len)) {
    sts = (*(recio_filex -> call -> read)) (recio_chnex -> chnex, recio_filex -> filex, recio_chnex -> cur_vbn, buf_len, buf -> buf_data);
    if (sts != OZ_SUCCESS) {
      (*(recio_filex -> call -> free)) (recio_chnex -> chnex, recio_filex -> filex, buf);
      return (sts);
    }
  }

  /* Link buffer up */

linkit:
  buf -> next = recio_filex -> bufs;
  buf -> prev = &(recio_filex -> bufs);
  if (buf -> next != NULL) buf -> next -> prev = &(buf -> next);
  recio_filex -> bufs = buf;
  buf -> buf_vbn   = recio_chnex -> cur_vbn;
  buf -> buf_len   = buf_len;
  buf -> buf_dirty = 0;
  buf -> refcount  = 1;

  /* Make it our current buffer */

  recio_chnex -> cur_buf = buf;

rtn:
  return ((recio_chnex -> cur_ofs >= buf -> buf_len) ? OZ_ENDOFFILE : OZ_SUCCESS);
}
Esempio n. 23
0
	void
normal()
{
	register u_char	c;
	long 			n;
	int				flag = FALSE;
	int 			type = 0;		/* used in some operations to modify type */
	int 			dir = FORWARD;	/* search direction */
	u_char			nchar = NUL;
	int				finish_op;
	linenr_t		Prenum1;
	char			searchbuff[CMDBUFFSIZE];		/* buffer for search string */
	FPOS			*pos;
	register char	*ptr;
	int				command_busy = FALSE;

	static linenr_t	redo_Quote_nlines;
	static int		redo_Quote_type;
	static long		redo_Quote_col;

	Prenum = 0;
	/*
	 * If there is an operator pending, then the command we take this time
	 * will terminate it. Finish_op tells us to finish the operation before
	 * returning this time (unless the operation was cancelled).
	 */
	finish_op = (operator != NOP);

	if (!finish_op && !yankbuffer)
		opnum = 0;

	if (vpeekc() == NUL || KeyTyped == TRUE)
		premsg(NUL, NUL);
	State = NORMAL_BUSY;
	c = vgetc();

	/* Pick up any leading digits and compute 'Prenum' */
	while ((c >= '1' && c <= '9') || (Prenum > 0 && (c == DEL || c == '0')))
	{
		if (c == DEL)
				Prenum /= 10;
		else
				Prenum = Prenum * 10 + (c - '0');
		premsg(' ', NUL);
		c = vgetc();
	}

	/*
	 * If we're in the middle of an operator (including after entering a yank
	 * buffer with ") AND we had a count before the
	 * operator, then that count overrides the current value of Prenum. What
	 * this means effectively, is that commands like "3dw" get turned into
	 * "d3w" which makes things fall into place pretty neatly.
	 * If you give a count before AND after the operator, they are multiplied.
	 */
	if (opnum != 0)
	{
			if (Prenum)
				Prenum *= opnum;
			else
				Prenum = opnum;
			opnum = 0;
	}

	Prenum1 = (Prenum == 0 ? 1 : Prenum);		/* Prenum often defaults to 1 */
	premsg(c, NUL);

	/*
	 * get an additional character if we need one
	 */
	if (strchr("@zZtTfF[]rm'`\"", c) || (c == 'v' && Recording == FALSE))
	{
		State = NOMAPPING;
		nchar = vgetc();		/* no macro mapping for this char */
		premsg(c, nchar);
	}
	flushbuf();			/* flush the premsg() characters onto the screen so we can
							see them while the command is being executed */

	if (c != 'z')	/* the 'z' command gets another character */
	{
		State = NORMAL;
		script_winsize_pp();
	}
	if (nchar == ESC)
	{
		CLEAROP;
		goto normal_end;
	}
	switch (c)
	{

/*
 * 0: Macros
 */
	  case 'v': 		/* (stop) recording into a named buffer */
		CHECKCLEAROP;
		if (!dorecord(nchar))
				CLEAROPBEEP;
		break;

	 case '@':			/* execute a named buffer */
		CHECKCLEAROP;
		while (Prenum1--)
			if (!doexecbuf(nchar))
			{
				CLEAROPBEEP;
				break;
			}
		break;

/*
 * 1: Screen positioning commands
 */
	  case CTRL('D'):
		flag = TRUE;

	  case CTRL('U'):
		CHECKCLEAROP;
		if (Prenum)
			p_scroll = (Prenum > Rows - 1) ? Rows - 1 : Prenum;
		n = (p_scroll < Rows) ? p_scroll : Rows - 1;
		if (flag)
		{
				scrollup(n);
				onedown(n);
		}
		else
		{
				scrolldown(n);
				oneup(n);
		}
		updateScreen(VALID);
		break;

	  case CTRL('B'):
	  case K_SUARROW:
		dir = BACKWARD;

	  case CTRL('F'):
	  case K_SDARROW:
		CHECKCLEAROP;
		onepage(dir, Prenum1);
		break;

	  case CTRL('E'):
		CHECKCLEAROP;
		scrollup(Prenum1);
		updateScreen(VALID);
		break;

	  case CTRL('Y'):
		CHECKCLEAROP;
		scrolldown(Prenum1);
		updateScreen(VALID);
		break;

	  case 'z':
		CHECKCLEAROP;
		if (isdigit(nchar))
		{
			/*
			 * we misuse some variables to be able to call premsg()
			 */
			operator = c;
			opnum = Prenum;
			Prenum = nchar - '0';
			for (;;)
			{
				premsg(' ', NUL);
				nchar = vgetc();
				State = NORMAL;
				script_winsize_pp();
				if (nchar == DEL)
					Prenum /= 10;
				else if (isdigit(nchar))
					Prenum = Prenum * 10 + (nchar - '0');
				else if (nchar == CR)
				{
					set_winsize((int)Columns, (int)Prenum, TRUE);
					break;
				}
				else
				{
					CLEAROPBEEP;
					break;
				}
			}
			operator = NOP;
			break;
		}

		if (Prenum)		/* line number given */
		{
			if (Prenum > line_count)
				Curpos.lnum = line_count;
			else
				Curpos.lnum = Prenum;
		}
		State = NORMAL;
		script_winsize_pp();
		switch (nchar)
		{
		  case NL:				/* put Curpos at top of screen */
		  case CR:
			Topline = Prenum;
			updateScreen(VALID);
			break;

		  case '.': 			/* put Curspos in middle of screen */
			n = Rows / 2;
			goto dozcmd;

		  case '-': 			/* put Curpos at bottom of screen */
			n = Rows - 1;
			/* FALLTHROUGH */

	dozcmd:
			{
				register linenr_t	lp = Prenum;
				register long		l = 0;

				while ((l < n) && (lp != 0))
				{
					l += plines(lp);
					Topline = lp;
					--lp;
				}
			}
			updateScreen(VALID);
			break;

		  default:
			CLEAROPBEEP;
		}
		break;

/*
 *	  2: Control commands
 */
	  case ':':
	    if (Quote.lnum)
			goto dooperator;
		CHECKCLEAROP;
		docmdline(NULL);
		break;

	  case K_HELP:
		CHECKCLEAROP;
		help();
		break;

	  case CTRL('L'):
		CHECKCLEAROP;
		updateScreen(CLEAR);
		break;

	  case CTRL('G'):
		CHECKCLEAROP;
		fileinfo();
		break;

	  case K_CCIRCM:			/* shorthand command */
		CHECKCLEAROPQ;
		if (getaltfile((int)Prenum, (linenr_t)0, TRUE))
			emsg(e_noalt);
		break;

	  case 'Z': 		/* write, if changed, and exit */
		CHECKCLEAROPQ;
		if (nchar != 'Z')
		{
			CLEAROPBEEP;
			break;
		}
		stuffReadbuff(":x\n");
		break;

	  case CTRL(']'):			/* :ta to current identifier */
		CHECKCLEAROPQ;
	  case '*': 				/* / to current identifier */
	  case '#': 				/* ? to current identifier */
	  case 'K':					/* run program for current identifier */
		{
			register int 	col;

			ptr = nr2ptr(Curpos.lnum);
			col = Curpos.col;

			/*
			 * skip to start of identifier.
			 */
			while (ptr[col] != NUL && !isidchar(ptr[col]))
				++col;

			/*
			 * Back up to start of identifier. This doesn't match the
			 * real vi but I like it a little better and it shouldn't bother
			 * anyone.
			 */
			while (col > 0 && isidchar(ptr[col - 1]))
				--col;

			if (!isidchar(ptr[col]))
			{
				CLEAROPBEEP;
				break;
			}

			if (Prenum)
				stuffnumReadbuff(Prenum);
			switch (c)
			{
				case '*':
					stuffReadbuff("/");
					break;
				case '#':
					stuffReadbuff("?");
					break;
				case 'K':
					stuffReadbuff(":! ");
					stuffReadbuff(p_kp);
					stuffReadbuff(" ");
					break;
				default:
					stuffReadbuff(":ta ");
			}

			/*
			 * Now grab the chars in the identifier
			 */
			while (isidchar(ptr[col]))
			{
				stuffReadbuff(mkstr(ptr[col]));
				++col;
			}
			stuffReadbuff("\n");
		}
		break;

	  case CTRL('T'):		/* backwards in tag stack */
			CHECKCLEAROPQ;
	  		dotag("", 2, (int)Prenum1);
			break;

/*
 * Cursor motions
 */
	  case 'G':
		mtype = MLINE;
		setpcmark();
		if (Prenum == 0 || Prenum > line_count)
				Curpos.lnum = line_count;
		else
				Curpos.lnum = Prenum;
		beginline(TRUE);
		break;

	  case 'H':
	  case 'M':
		if (c == 'M')
				n = Rows / 2;
		else
				n = Prenum;
		mtype = MLINE;
		Curpos.lnum = Topline;
		while (n && onedown((long)1))
				--n;
		beginline(TRUE);
		break;

	  case 'L':
		mtype = MLINE;
		Curpos.lnum = Botline - 1;
		for (n = Prenum; n && oneup((long)1); n--)
				;
		beginline(TRUE);
		break;

	  case 'l':
	  case K_RARROW:
	  case ' ':
		mtype = MCHAR;
		mincl = FALSE;
		n = Prenum1;
		while (n--)
		{
			if (!oneright())
			{
				if (operator == NOP)
					beep();
				else
				{
					if (lineempty(Curpos.lnum))
						CLEAROPBEEP;
					else
					{
						mincl = TRUE;
						if (n)
							beep();
					}
				}
				break;
			}
		}
		set_want_col = TRUE;
		break;

	  case 'h':
	  case K_LARROW:
	  case CTRL('H'):
	  case DEL:
		mtype = MCHAR;
		mincl = FALSE;
		n = Prenum1;
		while (n--)
		{
			if (!oneleft())
			{
				if (operator != DELETE && operator != CHANGE)
					beep();
				else if (Prenum1 == 1)
					CLEAROPBEEP;
				break;
			}
		}
		set_want_col = TRUE;
		break;

	  case '-':
		flag = TRUE;
		/* FALLTHROUGH */

	  case 'k':
	  case K_UARROW:
	  case CTRL('P'):
		mtype = MLINE;
		if (!oneup(Prenum1))
			CLEAROPBEEP;
		else if (flag)
			beginline(TRUE);
		break;

	  case '+':
	  case CR:
		flag = TRUE;
		/* FALLTHROUGH */

	  case 'j':
	  case K_DARROW:
	  case CTRL('N'):
	  case NL:
		mtype = MLINE;
		if (!onedown(Prenum1))
			CLEAROPBEEP;
		else if (flag)
			beginline(TRUE);
		break;

		/*
		 * This is a strange motion command that helps make operators more
		 * logical. It is actually implemented, but not documented in the
		 * real 'vi'. This motion command actually refers to "the current
		 * line". Commands like "dd" and "yy" are really an alternate form of
		 * "d_" and "y_". It does accept a count, so "d3_" works to delete 3
		 * lines.
		 */
	  case '_':
lineop:
		mtype = MLINE;
		if (!onedown((long)(Prenum1 - 1)))
			CLEAROPBEEP;
		else if (operator != YANK)	/* 'Y' does not move cursor */
			beginline(TRUE);
		break;

	  case '|':
		mtype = MCHAR;
		mincl = TRUE;
		beginline(FALSE);
		if (Prenum > 0)
			coladvance((colnr_t)(Prenum - 1));
		Curswant = Prenum - 1;
		break;

		/*
		 * Word Motions
		 */

	  case 'B':
		type = 1;
		/* FALLTHROUGH */

	  case 'b':
	  case K_SLARROW:
		mtype = MCHAR;
		mincl = FALSE;
		set_want_col = TRUE;
		if (bck_word(Prenum1, type))
			CLEAROPBEEP;
		break;

	  case 'E':
		type = 1;
		/* FALLTHROUGH */

	  case 'e':
		mincl = TRUE;
		goto dowrdcmd;

	  case 'W':
		type = 1;
		/* FALLTHROUGH */

	  case 'w':
	  case K_SRARROW:
		mincl = FALSE;
		flag = TRUE;
		/*
		 * This is a little strange. To match what the real vi does, we
		 * effectively map 'cw' to 'ce', and 'cW' to 'cE', provided that we are
		 * not on a space or a TAB. This seems
		 * impolite at first, but it's really more what we mean when we say
		 * 'cw'.
		 */
		if (operator == CHANGE && (n = gcharCurpos()) != ' ' && n != TAB &&
																n != NUL)
		{
			mincl = TRUE;
			flag = FALSE;
		}

dowrdcmd:
		mtype = MCHAR;
		set_want_col = TRUE;
		if (flag)
			n = fwd_word(Prenum1, type);
		else
			n = end_word(Prenum1, type, operator == CHANGE);
		if (n)
		{
			CLEAROPBEEP;
			break;
		}
		/*
		 * if we do a 'dw' for the last word in a line, we only delete the rest
		 * of the line, not joining the two lines.
		 */
		if (operator == DELETE && Prenum1 == 1 && startop.lnum != Curpos.lnum)
		{
				Curpos = startop;
				while (oneright())
					;
				mincl = TRUE;
		}
		break;

	  case '$':
		mtype = MCHAR;
		mincl = TRUE;
		Curswant = 29999;				/* so we stay at the end */
		if (!onedown((long)(Prenum1 - 1)))
		{
				CLEAROPBEEP;
				break;
		}
		if (Quote_block)
			updateScreen(NOT_VALID);
		break;

	  case '^':
		flag = TRUE;
		/* FALLTHROUGH */

	  case '0':
		mtype = MCHAR;
		mincl = TRUE;
		beginline(flag);
		break;

/*
 * 4: Searches
 */
	  case '?':
	  case '/':
		if (!getcmdline(c, (u_char *)searchbuff))
		{
				CLEAROP;
				break;
		}
		mtype = MCHAR;
		mincl = FALSE;
		set_want_col = TRUE;

		n = dosearch(c == '/' ? FORWARD : BACKWARD, searchbuff, FALSE, Prenum1);
		if (n == 0)
				CLEAROPBEEP;
		else if (n == 2)
				mtype = MLINE;
		break;

	  case 'N':
		flag = 1;

	  case 'n':
		mtype = MCHAR;
		mincl = FALSE;
		set_want_col = TRUE;
		if (!dosearch(0, NULL, flag, Prenum1))
			CLEAROPBEEP;
		break;

		/*
		 * Character searches
		 */
	  case 'T':
		dir = BACKWARD;
		/* FALLTHROUGH */

	  case 't':
		type = 1;
		goto docsearch;

	  case 'F':
		dir = BACKWARD;
		/* FALLTHROUGH */

	  case 'f':
docsearch:
		mtype = MCHAR;
		mincl = TRUE;
		set_want_col = TRUE;
		if (!searchc(nchar, dir, type, Prenum1))
		{
			CLEAROPBEEP;
		}
		break;

	  case ',':
		flag = 1;
		/* FALLTHROUGH */

	  case ';':
	    dir = flag;
	    goto docsearch;		/* nchar == NUL, thus repeat previous search */

		/*
		 * section or C function searches
		 */

	  case '[':
		dir = BACKWARD;
		/* FALLTHROUGH */

	  case ']':
		mtype = MLINE;
		set_want_col = TRUE;
		flag = '{';
		if (nchar != c)
		{
			if (nchar == '[' || nchar == ']')
				flag = '}';
			else
			{
				CLEAROPBEEP;
				break;
			}
		}
		if (dir == FORWARD && operator != NOP)	/* e.g. y]] searches for '}' */
			flag = '}';
		if (!findpar(dir, Prenum1, flag))
		{
			CLEAROPBEEP;
		}
		break;

	  case '%':
		mincl = TRUE;
	    if (Prenum)		/* {cnt}% : goto {cnt} percentage in file */
		{
			if (Prenum > 100)
				CLEAROPBEEP;
			else
			{
				mtype = MLINE;
				setpcmark();
				Curpos.lnum = line_count * Prenum / 100;
				Curpos.col = 0;
			}
		}
		else			/* % : go to matching paren */
		{
			mtype = MCHAR;
			if ((pos = showmatch()) == NULL)
				CLEAROPBEEP;
			else
			{
				setpcmark();
				Curpos = *pos;
				set_want_col = TRUE;
			}
		}
		break;

	  case '(':
		dir = BACKWARD;
		/* FALLTHROUGH */

	  case ')':
		mtype = MCHAR;
		if (c == ')')
			mincl = FALSE;
		else
			mincl = TRUE;
		set_want_col = TRUE;

		if (!findsent(dir, Prenum1))
			CLEAROPBEEP;
		break;

	  case '{':
		dir = BACKWARD;
		/* FALLTHROUGH */

	  case '}':
		mtype = MCHAR;
		mincl = FALSE;
		set_want_col = TRUE;

		if (!findpar(dir, Prenum1, NUL))
			CLEAROPBEEP;
		break;

/*
 * 5: Edits
 */
	  case '.':
		CHECKCLEAROPQ;
		if (!start_redo(Prenum))
			CLEAROPBEEP;
		break;

	  case 'u':
	    if (Quote.lnum)
			goto dooperator;
	  case K_UNDO:
		CHECKCLEAROPQ;
		u_undo((int)Prenum1);
		set_want_col = TRUE;
		break;

	  case CTRL('R'):
		CHECKCLEAROPQ;
	  	u_redo((int)Prenum1);
		set_want_col = TRUE;
		break;

	  case 'U':
	    if (Quote.lnum)
			goto dooperator;
		CHECKCLEAROPQ;
		u_undoline();
		set_want_col = TRUE;
		break;

	  case 'r':
	    if (Quote.lnum)
		{
			c = 'c';
			goto dooperator;
		}
		CHECKCLEAROPQ;
		n = strlen(nr2ptr(Curpos.lnum)) - Curpos.col;
		if (n < Prenum1)			/* not enough characters to replace */
		{
			CLEAROPBEEP;
			break;
		}

		prep_redo(Prenum1, 'r', NUL, nchar);
		stuffnumReadbuff(Prenum1);
		stuffReadbuff("R");
		stuffReadbuff(mkstr(nchar));
		stuffReadbuff("\033");
		break;

	  case 'J':
	    if (Quote.lnum)		/* join the quoted lines */
		{
			if (Curpos.lnum > Quote.lnum)
			{
				Prenum = Curpos.lnum - Quote.lnum + 1;
				Curpos.lnum = Quote.lnum;
			}
			else
				Prenum = Quote.lnum - Curpos.lnum + 1;
			Quote.lnum = 0;
		}
		CHECKCLEAROP;
		if (Prenum <= 1)
				Prenum = 2; 	/* default for join is two lines! */
		if (Curpos.lnum + Prenum - 1 > line_count)	/* beyond last line */
		{
			CLEAROPBEEP;
			break;
		}

		prep_redo(Prenum, 'J', NUL, NUL);
		dodojoin(Prenum, TRUE, TRUE);
		break;

	  case 'P':
		dir = BACKWARD;
		/* FALLTHROUGH */

	  case 'p':
		CHECKCLEAROPQ;
		prep_redo(Prenum, c, NUL, NUL);
		doput(dir, Prenum1);
		break;

	  case CTRL('A'):			/* add to number */
	  case CTRL('S'):			/* subtract from number */
		CHECKCLEAROPQ;
		{
			register int 	col;
			char			buf[30];
			int				hex;		/* 'x' or 'X': hexadecimal; '0': octal */
			static int		hexupper = FALSE;	/* 0xABC */

			ptr = nr2ptr(Curpos.lnum);
			col = Curpos.col;

				/* first check if we are on a hexadecimal number */
			while (col > 0 && isxdigit(ptr[col]))
				--col;
			if (col > 0 && toupper(ptr[col]) == 'X' && ptr[col - 1] == '0' && isxdigit(ptr[col + 1]))
				--col;		/* found hexadecimal number */
			else
			{
				/* first search forward and then backward for start of number */
				col = Curpos.col;

				while (ptr[col] != NUL && !isdigit(ptr[col]))
					++col;

				while (col > 0 && isdigit(ptr[col - 1]))
					--col;
			}

			if (isdigit(ptr[col]) && u_saveCurpos())
			{
				set_want_col = TRUE;
				prep_redo(Prenum1, c, NUL, NUL);

				if (ptr[col] != '0')
					hex = 0;				/* decimal */
				else
				{
					hex = toupper(ptr[col + 1]);		/* assume hexadecimal */
					if (hex != 'X' || !isxdigit(ptr[col + 2]))
					{
						if (isdigit(hex))
							hex = '0';		/* octal */
						else
							hex = 0;		/* 0 by itself is decimal */
					}
				}

				if (!hex && col > 0 && ptr[col - 1] == '-')
					--col;

				ptr += col;
				if (hex == '0')
					sscanf(ptr, "%lo", &n);
				else if (hex)
					sscanf(ptr, "%lx", &n);	/* "%X" doesn't work! */
				else
					n = atol(ptr);

				if (c == CTRL('A'))
					n += Prenum1;
				else
					n -= Prenum1;

				if (hex == 'X')					/* skip the '0x' */
					col += 2;
				Curpos.col = col;
				do								/* delete the old number */
				{
					if (isalpha(c))
					{
						if (isupper(c))
							hexupper = TRUE;
						else
							hexupper = FALSE;
					}
					delchar(FALSE);
					c = gcharCurpos();
				}
				while (hex ? (hex == '0' ? c >= '0' && c <= '7' : isxdigit(c)) : isdigit(c));

				if (hex == '0')
					sprintf(buf, "0%lo", n);
				else if (hexupper)
					sprintf(buf, "%lX", n);
				else if (hex)
					sprintf(buf, "%lx", n);
				else
					sprintf(buf, "%ld", n);
				insstr(buf);					/* insert the new number */
				--Curpos.col;
				updateline();
			}
			else
				beep();
		}
		break;

/*
 * 6: Inserts
 */
	  case 'A':
		set_want_col = TRUE;
		while (oneright())
				;
		/* FALLTHROUGH */

	  case 'a':
		CHECKCLEAROPQ;
		/* Works just like an 'i'nsert on the next character. */
		if (u_saveCurpos())
		{
			if (!lineempty(Curpos.lnum))
				incCurpos();
			startinsert(c, FALSE, Prenum1);
			command_busy = TRUE;
		}
		break;

	  case 'I':
		beginline(TRUE);
		/* FALLTHROUGH */

	  case 'i':
		CHECKCLEAROPQ;
		if (u_saveCurpos())
		{
			startinsert(c, FALSE, Prenum1);
			command_busy = TRUE;
		}
		break;

	  case 'o':
	  	if (Quote.lnum)	/* switch start and end of quote */
		{
			Prenum = Quote.lnum;
			Quote.lnum = Curpos.lnum;
			Curpos.lnum = Prenum;
			n = Quote.col;
			Quote.col = Curpos.col;
			Curpos.col = n;
			break;
		}
		CHECKCLEAROP;
		if (u_save(Curpos.lnum, (linenr_t)(Curpos.lnum + 1)) && Opencmd(FORWARD, TRUE))
		{
			startinsert('o', TRUE, Prenum1);
			command_busy = TRUE;
		}
		break;

	  case 'O':
		CHECKCLEAROPQ;
		if (u_save((linenr_t)(Curpos.lnum - 1), Curpos.lnum) && Opencmd(BACKWARD, TRUE))
		{
			startinsert('O', TRUE, Prenum1);
			command_busy = TRUE;
		}
		break;

	  case 'R':
	    if (Quote.lnum)
		{
			c = 'c';
			Quote.col = QUOTELINE;
			goto dooperator;
		}
		CHECKCLEAROPQ;
		if (u_saveCurpos())
		{
			startinsert('R', FALSE, Prenum1);
			command_busy = TRUE;
		}
		break;

/*
 * 7: Operators
 */
	  case '~': 		/* swap case */
	  /*
	   * if tilde is not an operator and Quoting is off: swap case
	   * of a single character
	   */
		if (!p_to && !Quote.lnum)
		{
			CHECKCLEAROPQ;
			if (lineempty(Curpos.lnum))
			{
				CLEAROPBEEP;
				break;
			}
			prep_redo(Prenum, '~', NUL, NUL);

			if (!u_saveCurpos())
				break;

			for (; Prenum1 > 0; --Prenum1)
			{
				if (gcharCurpos() == NUL)
					break;
				swapchar(&Curpos);
				incCurpos();
			}

			set_want_col = TRUE;
			CHANGED;
			updateline();
			break;
		}
		/*FALLTHROUGH*/

	  case 'd':
	  case 'c':
	  case 'y':
	  case '>':
	  case '<':
	  case '!':
	  case '=':
	  case 'V':
dooperator:
		n = strchr(opchars, c) - opchars + 1;
		if (n == operator)		/* double operator works on lines */
			goto lineop;
		CHECKCLEAROP;
		if (Prenum != 0)
			opnum = Prenum;
		startop = Curpos;
		operator = n;
		break;

/*
 * 8: Abbreviations
 */

	 /* when quoting the next commands are operators */
	  case 'S':
	  case 'Y':
	  case 'D':
	  case 'C':
	  case 'x':
	  case 'X':
	  case 's':
	  	if (Quote.lnum)
		{
			static char trans[] = "ScYyDdCcxdXdsc";

			if (isupper(c))			/* uppercase means linewise */
				Quote.col = QUOTELINE;
			c = *(strchr(trans, c) + 1);
			goto dooperator;
		}

	  case '&':
		CHECKCLEAROPQ;
		if (Prenum)
			stuffnumReadbuff(Prenum);

		if (c == 'S')
		{
			beginline((int)p_ai);
			substituting = TRUE;
		}
		else if (c == 'Y' && p_ye)
			c = 'Z';
		{
				static char *(ar[9]) = {"dl", "dh", "d$", "c$", "cl", "c$", "yy", "y$", ":s\r"};
				static char *str = "xXDCsSYZ&";

				stuffReadbuff(ar[strchr(str, c) - str]);
		}
		break;

/*
 * 9: Marks
 */

	  case 'm':
		CHECKCLEAROP;
		if (!setmark(nchar))
			CLEAROPBEEP;
		break;

	  case '\'':
		flag = TRUE;
		/* FALLTHROUGH */

	  case '`':
		pos = getmark(nchar, (operator == NOP));
		if (pos == (FPOS *)-1)	/* jumped to other file */
		{
			if (flag)
				beginline(TRUE);
			break;
		}

		if (pos != NULL)
			setpcmark();

cursormark:
		if (pos == NULL)
			CLEAROPBEEP;
		else
		{
			Curpos = *pos;
			if (flag)
				beginline(TRUE);
		}
		mtype = flag ? MLINE : MCHAR;
		mincl = FALSE;		/* ignored if not MCHAR */
		set_want_col = TRUE;
		break;

	case CTRL('O'):			/* goto older pcmark */
		Prenum1 = -Prenum1;
		/* FALLTHROUGH */

	case CTRL('I'):			/* goto newer pcmark */
		CHECKCLEAROPQ;
		pos = movemark((int)Prenum1);
		if (pos == (FPOS *)-1)	/* jump to other file */
		{
			set_want_col = TRUE;
			break;
		}
		goto cursormark;

/*
 * 10. Buffer setting
 */
	  case '"':
		CHECKCLEAROP;
		if (isalnum(nchar) || nchar == '.')
		{
			yankbuffer = nchar;
			opnum = Prenum;		/* remember count before '"' */
		}
		else
			CLEAROPBEEP;
		break;

/*
 * 11. Quoting
 */
 	  case 'q':
	  case 'Q':
	  case CTRL('Q'):
		CHECKCLEAROP;
		Quote_block = FALSE;
		if (Quote.lnum)					/* stop quoting */
		{
			Quote.lnum = 0;
			updateScreen(NOT_VALID);	/* delete the inversion */
		}
		else							/* start quoting */
		{
			Quote = Curpos;
			if (c == 'Q')				/* linewise */
				Quote.col = QUOTELINE;
			else if (c == CTRL('Q'))	/* blockwise */
				Quote_block = TRUE;
			updateline();				/* start the inversion */
		}
		break;

/*
 * 12. Suspend
 */

 	case CTRL('Z'):
		CLEAROP;
		Quote.lnum = 0;					/* stop quoting */
		stuffReadbuff(":st!\r");		/* no autowrite */
		break;

/*
 * The end
 */
	  case ESC:
	    if (Quote.lnum)
		{
			Quote.lnum = 0;			/* stop quoting */
			updateScreen(NOT_VALID);
		}

	  default:					/* not a known command */
		CLEAROPBEEP;
		break;

	}	/* end of switch on command character */

/*
 * if we didn't start or finish an operator, reset yankbuffer, unless we
 * need it later.
 */
	if (!finish_op && !operator && strchr("\"DCYSsXx", c) == NULL)
		yankbuffer = 0;

	/*
	 * If an operation is pending, handle it...
	 */
	if ((Quote.lnum || finish_op) && operator != NOP)
	{
		if (operator != YANK && !Quote.lnum)		/* can't redo yank */
		{
				prep_redo(Prenum, opchars[operator - 1], c, nchar);
				if (c == '/' || c == '?')		/* was a search */
				{
						AppendToRedobuff(searchbuff);
						AppendToRedobuff(NL_STR);
				}
		}

		if (redo_Quote_busy)
		{
			startop = Curpos;
			Curpos.lnum += redo_Quote_nlines - 1;
			switch (redo_Quote_type)
			{
			case 'Q':	Quote.col = QUOTELINE;
						break;

			case CTRL('Q'):
						Quote_block = TRUE;
						break;

			case 'q':		
						if (redo_Quote_nlines <= 1)
							Curpos.col += redo_Quote_col;
						else
							Curpos.col = redo_Quote_col;
						break;
			}
			if (redo_Quote_col == 29999)
			{
				Curswant = 29999;
				coladvance(29999);
			}
		}
		else if (Quote.lnum)
			startop = Quote;


		if (lt(startop, Curpos))
		{
			endop = Curpos;
			Curpos = startop;
		}
		else
		{
			endop = startop;
			startop = Curpos;
		}
		nlines = endop.lnum - startop.lnum + 1;

		if (Quote.lnum || redo_Quote_busy)
		{
			if (Quote_block)				/* block mode */
			{
				startvcol = getvcol(&startop, 2);
				n = getvcol(&endop, 2);
				if (n < startvcol)
					startvcol = n;

			/* if '$' was used, get endvcol from longest line */
				if (Curswant == 29999)
				{
					Curpos.col = 29999;
					endvcol = 0;
					for (Curpos.lnum = startop.lnum; Curpos.lnum <= endop.lnum; ++Curpos.lnum)
						if ((n = getvcol(&Curpos, 3)) > endvcol)
							endvcol = n;
					Curpos = startop;
				}
				else if (redo_Quote_busy)
					endvcol = startvcol + redo_Quote_col;
				else
				{
					endvcol = getvcol(&startop, 3);
					n = getvcol(&endop, 3);
					if (n > endvcol)
						endvcol = n;
				}
				coladvance(startvcol);
			}

	/*
	 * prepare to redo quoting: this is based on the size
	 * of the quoted text
	 */
			if (operator != YANK)		/* can't redo yank */
			{
				prep_redo(0L, 'q', opchars[operator - 1], NUL);
				if (Quote_block)
					redo_Quote_type = CTRL('Q');
				else if (Quote.col == QUOTELINE)
					redo_Quote_type = 'Q';
				else
					redo_Quote_type = 'q';
				if (Curswant == 29999)
					redo_Quote_col = 29999;
				else if (Quote_block)
					redo_Quote_col = endvcol - startvcol;
				else if (nlines > 1)
					redo_Quote_col = endop.col;
				else
					redo_Quote_col = endop.col - startop.col;
				redo_Quote_nlines = nlines;
			}

			mincl = TRUE;
			if (Quote.col == QUOTELINE)
				mtype = MLINE;
			else
				mtype = MCHAR;

			redo_Quote_busy = FALSE;
			/*
			 * Switch quoting off now, so screen updating does
			 * not show inverted text when the screen is redrawn.
			 * With YANK and sometimes with COLON there is no screen redraw, so
			 * it is done here to remove the inverted part.
			 */
			Quote.lnum = 0;
			if (operator == YANK || operator == COLON)
				updateScreen(NOT_VALID);
		}

		set_want_col = 1;
		if (!mincl && !equal(startop, endop))
			oneless = 1;
		else
			oneless = 0;

		switch (operator)
		{
		  case LSHIFT:
		  case RSHIFT:
			adjust_lnum();
			doshift(operator);
			break;

		  case DELETE:
			dodelete();
			break;

		  case YANK:
			doyank(FALSE);
			break;

		  case CHANGE:
			dochange();
			break;

		  case FILTER:
			AppendToRedobuff("!\n");	/* strange but necessary */

		  case INDENT:
		  case COLON:
			adjust_lnum();
			sprintf(IObuff, ":%ld,%ld", (long)startop.lnum, (long)endop.lnum);
			stuffReadbuff(IObuff);
			if (operator != COLON)
				stuffReadbuff("!");
			if (operator == INDENT)
			{
				stuffReadbuff(p_ep);
				stuffReadbuff("\n");
			}
				/*	docmdline() does the rest */
			break;

		  case TILDE:
		  case UPPER:
		  case LOWER:
			dotilde();
			break;

		  case FORMAT:
			adjust_lnum();
			doformat();
			break;

		  default:
			CLEAROPBEEP;
		}
		operator = NOP;
		Quote_block = FALSE;
		yankbuffer = 0;
	}

normal_end:
	premsg(-1, NUL);
	if (restart_edit && operator == NOP && Quote.lnum == 0 && !command_busy && stuff_empty() && yankbuffer == 0)
		startinsert(NUL, FALSE, 1L);
}