예제 #1
0
RC_DEPTREE *
_rc_deptree_load(int force, int *regen) {
	int fd;
	int retval;
	int serrno = errno;
	int merrno;
	time_t t;
	char file[PATH_MAX];
	struct stat st;
	struct utimbuf ut;
	FILE *fp;

	t = 0;
	if (rc_deptree_update_needed(&t, file) || force != 0) {
		/* Test if we have permission to update the deptree */
		fd = open(RC_DEPTREE_CACHE, O_WRONLY);
		merrno = errno;
		errno = serrno;
		if (fd == -1 && merrno == EACCES)
			return rc_deptree_load();
		close(fd);

		if (regen)
			*regen = 1;
		ebegin("Caching service dependencies");
		retval = rc_deptree_update() ? 0 : -1;
		eend (retval, "Failed to update the dependency tree");

		if (retval == 0) {
			stat(RC_DEPTREE_CACHE, &st);
			if (st.st_mtime < t) {
				eerror("Clock skew detected with `%s'", file);
				eerrorn("Adjusting mtime of `" RC_DEPTREE_CACHE
				    "' to %s", ctime(&t));
				fp = fopen(RC_DEPTREE_SKEWED, "w");
				if (fp != NULL) {
					fprintf(fp, "%s\n", file);
					fclose(fp);
				}
				ut.actime = t;
				ut.modtime = t;
				utime(RC_DEPTREE_CACHE, &ut);
			} else {
				if (exists(RC_DEPTREE_SKEWED))
					unlink(RC_DEPTREE_SKEWED);
			}
		}
		if (force == -1 && regen != NULL)
			*regen = retval;
	}
	return rc_deptree_load();
}
예제 #2
0
/* return number of processed killed, -1 on error */
static int
do_stop(const char *exec, const char *const *argv,
    pid_t pid, uid_t uid,int sig,
    bool quiet, bool verbose, bool test)
{
	RC_PIDLIST *pids;
	RC_PID *pi;
	RC_PID *np;
	bool killed;
	int nkilled = 0;

	if (pid)
		pids = rc_find_pids(NULL, NULL, 0, pid);
	else
		pids = rc_find_pids(exec, argv, uid, pid);

	if (!pids)
		return 0;

	LIST_FOREACH_SAFE(pi, pids, entries, np) {
		if (test) {
			if (!quiet)
				einfo("Would send signal %d to PID %d",
				    sig, pi->pid);
			nkilled++;
		} else {
			if (verbose)
				ebegin("Sending signal %d to PID %d",
				    sig, pi->pid);
			errno = 0;
			killed = (kill(pi->pid, sig) == 0 ||
			    errno == ESRCH ? true : false);
			if (verbose)
				eend(killed ? 0 : 1,
				    "%s: failed to send signal %d to PID %d: %s",
				    applet, sig, pi->pid, strerror(errno));
			if (!killed) {
				nkilled = -1;
			} else {
				if (nkilled != -1)
					nkilled++;
			}
		}
		free(pi);
	}

	free(pids);
	return nkilled;
}
예제 #3
0
void CPrint::OnPaint() 
{
	if(m_bRepaintPreview){
		CWnd* item = GetDlgItem(IDC_PREVIEW_FRAME);
		CRect prerect;
		item->GetWindowRect(prerect);
		ScreenToClient(prerect);
		
		int obase = m_Calculator->m_base;
		m_Calculator->m_base = 10;
		
		UpdateData();
		CDC print_dc;
		print_dc.Attach(m_PrintDlg.GetPrinterDC());         // Attach a printer DC
		
		CPaintDC dc(this); // device context for painting
		CPoint ul(prerect.left + 10, prerect.top + 19);
		CRect print_rect(0,0, print_dc.GetDeviceCaps(HORZRES), print_dc.GetDeviceCaps(VERTRES));
		CRect window_rect(0,0,prerect.Width() - 20, prerect.Height() - 25);
		double scale_factor;
		
		TRACE("print_rect.Width=%d print_rect.Height=%d\n", print_rect.Width(), print_rect.Height());
		
		if((double(print_rect.Width())/double(print_rect.Height())) >
			(double(window_rect.Width())/double(window_rect.Height())))
			scale_factor = double(window_rect.Width()) / double(print_rect.Width());
		else
			scale_factor = double(window_rect.Height()) / double(print_rect.Height());
		
		CPoint start;
		start.x = ul.x + (double(window_rect.Width() - (print_rect.Width() * scale_factor)) / 2.0);
		start.y = ul.y + (double(window_rect.Height() - (print_rect.Height() * scale_factor)) / 2.0);
		
		//////////// DRAW PAPER
		CBrush brush(RGB(255,255,255)), *pOldBrush;
		pOldBrush = dc.SelectObject(&brush);
		CPen penBlack;
		penBlack.CreatePen(PS_SOLID, 0, RGB(0,0,0));
		CPen* pOldPen = dc.SelectObject(&penBlack);
		
		dc.Rectangle(start.x - 3, start.y - 3, 
			start.x + (print_rect.Width() * scale_factor) + 3, 
			start.y + (print_rect.Height() * scale_factor) + 3);
		dc.SelectObject(pOldPen);
		//////////// END DRAW PAPER
		
		//////////// Calculate width and height
		long double w, h;
		
		if(m_iPageSize == 1){
			double scale;
			if((double(print_rect.Width()) / double(m_graph_width)) > 
				(double(print_rect.Height()) / double(m_graph_height)))
				scale = (double(print_rect.Height()) / 2.0) / double(m_graph_height);
			else
				scale = (double(print_rect.Width()) / 2.0) / double(m_graph_width);
			
			h = (double(m_graph_height)/double(print_dc.GetDeviceCaps(LOGPIXELSY))) * scale;
			w = (double(m_graph_width)/double(print_dc.GetDeviceCaps(LOGPIXELSX))) * scale;
		}
		else if(m_iPageSize == 0){
			w = double(print_rect.Width()) / double(print_dc.GetDeviceCaps(LOGPIXELSX));
			h = double(print_rect.Height()) / double(print_dc.GetDeviceCaps(LOGPIXELSY));
		}
		else{
			m_Calculator->StringToDecimal(m_sWidth, 10, w);
			m_Calculator->StringToDecimal(m_sHeight, 10, h);
			w = m_Calculator->abs(w);
			h = m_Calculator->abs(h);
			// convert width
			if(m_sWUnits == "cm")
				w *= 0.39370078740157;
			// convert height
			if(m_sHUnits == "cm")
				h *= 0.39370078740157;
		}
		
		// I now have desired width and height in inches
		CPoint gstart(start.x, start.y);
		
		double max_h((double(print_rect.Height()) / double(print_dc.GetDeviceCaps(LOGPIXELSY))));
		double max_w((double(print_rect.Width()) / double(print_dc.GetDeviceCaps(LOGPIXELSX))));
		
		// resize max height based on printing options
		if(m_bTitleOn){
			max_h -= (0.25 + 0.125);
			gstart.y += ((0.25 + 0.125) * print_dc.GetDeviceCaps(LOGPIXELSY) * scale_factor);
		}
		if(m_bEquations)
			max_h -= (1.5 + 0.125);
		
		// error check for desired size too large too large
		if(w > (max_w + 0.0001)){
			w = max_w;
			m_Calculator->DecimalToString(m_sWidth, w);
			if(m_iPageSize == 2)
				SetDimensionsW(w);
		}
		if(h > (max_h + 0.0001)){
			h = max_h;
			m_Calculator->DecimalToString(m_sHeight, h);
			if(m_iPageSize == 2)
				SetDimensionsH(h);
		}
		
		// now convert inches into device units (ie device pixels)
		w *= print_dc.GetDeviceCaps(LOGPIXELSX) * scale_factor;			// scale w for window
		h *= print_dc.GetDeviceCaps(LOGPIXELSY) * scale_factor;			// scale h for window
		//////////// END Calculate width and height
		
		//////////// Draw Graph Rectangle
		CBrush gray(RGB(128,128,128));
		dc.SelectObject(&gray);
		
		if(m_bCenter){
			gstart.x += ((print_rect.Width() * scale_factor) / 2.0) - (w / 2.0);
			
			double th(h);
			if(m_bTitleOn)
				th += ((0.25 + 0.125) * print_dc.GetDeviceCaps(LOGPIXELSY) * scale_factor);
			if(m_bEquations)
				th += ((1.5 + 0.125) * print_dc.GetDeviceCaps(LOGPIXELSY) * scale_factor);
			
			gstart.y += (double(print_rect.Height() * scale_factor) / 2.0) - (double(th) / 2.0);
		}
		dc.Rectangle(gstart.x, 
			gstart.y, 
			gstart.x + w, 
			gstart.y + h);
		//////////// END Draw Graph Rectangle
		
		if(m_bEquations){
			//////////// Draw Equations List
			CPoint estart(gstart.x, gstart.y + h +(0.125 * print_dc.GetDeviceCaps(LOGPIXELSY) * scale_factor));
			CPoint eend(gstart.x + w, gstart.y + h + (1.625 * print_dc.GetDeviceCaps(LOGPIXELSY) * scale_factor));
			
			int ew(w);
			
			if(ew < (5 * print_dc.GetDeviceCaps(LOGPIXELSX) * scale_factor)) // check for min eqs list size
				ew = (5 * print_dc.GetDeviceCaps(LOGPIXELSX) * scale_factor);
			
			if(ew > (max_w * print_dc.GetDeviceCaps(LOGPIXELSX) * scale_factor))
				ew = max_w;
			if((eend.y - estart.y) > (max_h * print_dc.GetDeviceCaps(LOGPIXELSY) * scale_factor))
				eend.y = estart.y + max_h;
			
			estart.x = (gstart.x + (double(w) / 2.0)) - (double(ew) / 2.0);
			if(estart.x < start.x)
				estart.x = start.x;
			
			eend.x = estart.x + ew;
			
			dc.SelectObject(&brush);
			dc.Rectangle(estart.x, estart.y, eend.x, eend.y);
			//////////// END Draw Equations List
		}
		
		if(m_bTitleOn){
			//////////// Draw Title Rectangle
			dc.SelectObject(&brush);
			dc.Rectangle(start.x, 
				start.y, 
				start.x + (print_rect.Width() * scale_factor), 
				start.y + (0.25 * print_dc.GetDeviceCaps(LOGPIXELSY) * scale_factor));
			//////////// END Draw Title Rectangle
		}
		
		dc.SelectObject(pOldBrush);
		print_dc.Detach();
		UpdateData(true);
		
		m_Calculator->m_base = obase;
	}
	
}
예제 #4
0
void
operate(int c, int cnt)
{
	register int i;
	void (*moveop)(), (*deleteop)();
	void (*opf)();
	bool subop = 0;
	char *oglobp, *ocurs;
	register line *addr;
	static char lastFKND, lastFCHR;
	char d;

	moveop = vmove, deleteop = vdelete;
	wcursor = cursor;
	wdot = NOLINE;
	notecnt = 0;
	dir = 1;
	switch (c) {

	/*
	 * d		delete operator.
	 */
	case 'd':
		moveop = vdelete;
		deleteop = beep;
		break;

	/*
	 * s		substitute characters, like c\040, i.e. change space.
	 */
	case 's':
		ungetkey(' ');
		subop++;
		/* fall into ... */

	/*
	 * c		Change operator.
	 */
	case 'c':
		if ((c == 'c' && workcmd[0] == 'C') || workcmd[0] == 'S')
			subop++;
		moveop = vchange;
		deleteop = beep;
		break;

	/*
	 * !		Filter through a UNIX command.
	 */
	case '!':
		moveop = vfilter;
		deleteop = beep;
		break;

	/*
	 * y		Yank operator.  Place specified text so that it
	 *		can be put back with p/P.  Also yanks to named buffers.
	 */
	case 'y':
		moveop = vyankit;
		deleteop = beep;
		break;

	/*
	 * =		Reformat operator (for LISP).
	 */
#ifdef LISP
	case '=':
		forbid(!value(LISP));
		/* fall into ... */
#endif

	/*
	 * >		Right shift operator.
	 * <		Left shift operator.
	 */
	case '<':
	case '>':
		moveop = vshftop;
		deleteop = beep;
		break;

	/*
	 * r		Replace character under cursor with single following
	 *		character.
	 */
	case 'r':
		vrep(cnt);
		return;

	default:
		goto nocount;
	}
	/*
	 * Had an operator, so accept another count.
	 * Multiply counts together.
	 */
	if (isdigit(peekkey()) && peekkey() != '0') {
		cnt *= vgetcnt();
		Xcnt = cnt;
		forbid (cnt <= 0);
	}

	/*
	 * Get next character, mapping it and saving as
	 * part of command for repeat.
	 */
	c = map(getesc());
	if (c == 0)
		return;
	if (!subop)
		*lastcp++ = c;
nocount:
	opf = moveop;
	switch (c) {

	/*
	 * b		Back up a word.
	 * B		Back up a word, liberal definition.
	 */
	case 'b':
	case 'B':
		dir = -1;
		/* fall into ... */

	/*
	 * w		Forward a word.
	 * W		Forward a word, liberal definition.
	 */
	case 'W':
	case 'w':
		wdkind = c & ' ';
		if (edge()) {
			forbid (opf == vmove);
			wcursor = dir == -1 ? linebuf : strend(linebuf);
		} else
			while (cnt > 0 && !edge())
				word(opf, cnt), cnt--;
		vmoving = 0;
		break;

	/*
	 * E to end of following blank/nonblank word
	 */
	case 'E':
		wdkind = 0;
		goto ein;

	/*
	 * e		To end of following word.
	 */
	case 'e':
		wdkind = 1;
ein:
		if (edge()) {
			forbid(opf == vmove);
			wcursor = dir == -1 ? linebuf : strend(linebuf);
		} else {
			while (cnt > 1 && !edge()) {
				word(opf, cnt);
				cnt--;
			}
			eend(opf, cnt);
		}
		vmoving = 0;
		break;

	/*
	 * (		Back an s-expression.
	 */
	case '(':
		dir = -1;
		/* fall into... */

	/*
	 * )		Forward an s-expression.
	 */
	case ')':
		forbid(lfind(0, cnt, opf, (line *) 0) < 0);
		if (wdot)
			markpr(wdot);
		break;

	/*
	 * {		Back an s-expression, but don't stop on atoms.
	 *		In text mode, a paragraph.  For C, a balanced set
	 *		of {}'s.
	 */
	case '{':
		dir = -1;
		/* fall into... */

	/*
	 * }		Forward an s-expression, but don't stop on atoms.
	 *		In text mode, back paragraph.  For C, back a balanced
	 *		set of {}'s.
	 */
	case '}':
		forbid(lfind(1, cnt, opf, (line *) 0) < 0);
		if (wdot)
			markpr(wdot);
		break;

	/*
	 * %		To matching () or {}.  If not at ( or { scan for
	 *		first such after cursor on this line.
	 */
	case '%':
		vsave();
		i = lmatchp((line *) 0);
		getDOT();
		forbid(!i);
		if (opf != vmove)
			if (dir > 0)
				wcursor++;
			else
				cursor++;
		else
			if (wdot)
				markpr(wdot);
		break;

	/*
	 * [		Back to beginning of defun, i.e. an ( in column 1.
	 *		For text, back to a section macro.
	 *		For C, back to a { in column 1 (~~ beg of function.)
	 */
	case '[':
		dir = -1;
		/* fall into ... */

	/*
	 * ]		Forward to next defun, i.e. a ( in column 1.
	 *		For text, forward section.
	 *		For C, forward to a } in column 1 (if delete or such)
	 *		or if a move to a { in column 1.
	 */
	case ']':
		if (!vglobp)
			forbid(getkey() != c);
		if (Xhadcnt)
			vsetsiz(Xcnt);
		vsave();
		i = lbrack(c, opf);
		getDOT();
		forbid(!i);
		if (wdot)
			markpr(wdot);
		if (ex_ospeed > B300)
			hold |= HOLDWIG;
		break;

	/*
	 * ,		Invert last find with f F t or T, like inverse
	 *		of ;.
	 */
	case ',':
		forbid (lastFKND == 0);
		c = isupper((int)lastFKND) ? tolower((int)lastFKND) : toupper((int)lastFKND);
		ungetkey(lastFCHR);
		if (vglobp == 0)
			vglobp = "";
		subop++;
		goto nocount;

	/*
	 * 0		To beginning of real line.
	 */
	case '0':
		wcursor = linebuf;
		vmoving = 0;
		break;

	/*
	 * ;		Repeat last find with f F t or T.
	 */
	case ';':
		forbid (lastFKND == 0);
		c = lastFKND;
		ungetkey(lastFCHR);
		subop++;
		goto nocount;

	/*
	 * F		Find single character before cursor in current line.
	 * T		Like F, but stops before character.
	 */
	case 'F':	/* inverted find */
	case 'T':
		dir = -1;
		/* fall into ... */

	/*
	 * f		Find single character following cursor in current line.
	 * t		Like f, but stope before character.
	 */
	case 'f':	/* find */
	case 't':
		i = getesc();
		if (i == 0)
			return;
		if (!subop)
			*lastcp++ = i;
		if (vglobp == 0)
			lastFKND = c, lastFCHR = i;
		for (; cnt > 0; cnt--)
			forbid (find(i) == 0);
		switch (c) {

		case 'T':
			wcursor++;
			break;

		case 't':
			wcursor--;
		case 'f':
fixup:
			if (moveop != vmove)
				wcursor++;
			break;
		}
		vmoving = 0;
		break;

	/*
	 * |		Find specified print column in current line.
	 */
	case '|':
		if (Pline == numbline)
			cnt += 8;
		vmovcol = cnt;
		vmoving = 1;
		wcursor = vfindcol(cnt);
		break;

	/*
	 * ^		To beginning of non-white space on line.
	 */
	case '^':
		wcursor = vskipwh(linebuf);
		vmoving = 0;
		break;

	/*
	 * $		To end of line.
	 */
	case '$':
		if (cnt > 1) {
			if (opf == vmove) {
				wcursor = 0;
				vmoving = 1;
				vmovcol = 20000;
				cnt--;
			} else
				wcursor = linebuf;
			wdot = dot + cnt;
			break;
		}
		if (linebuf[0]) {
			wcursor = strend(linebuf) - 1;
			goto fixup;
		}
		wcursor = linebuf;
		vmoving = 0;
		break;

	/*
	 * h		Back a character.
	 * ^H		Back a character.
	 */
	case 'h':
	case CTRL('h'):
		dir = -1;
		/* fall into ... */

	/*
	 * space	Forward a character.
	 */
	case ' ':
		forbid (margin() || (opf == vmove && edge()));
		while (cnt > 0 && !margin())
			wcursor += dir, cnt--;
		if ((margin() && opf == vmove) || wcursor < linebuf)
			wcursor -= dir;
		vmoving = 0;
		break;

	/*
	 * D		Delete to end of line, short for d$.
	 */
	case 'D':
		cnt = INF;
		goto deleteit;

	/*
	 * X		Delete character before cursor.
	 */
	case 'X':
		dir = -1;
		/* fall into ... */
deleteit:
	/*
	 * x		Delete character at cursor, leaving cursor where it is.
	 */
	case 'x':
		if (margin())
			goto errlab;
		while (cnt > 0 && !margin())
			wcursor += dir, cnt--;
		opf = deleteop;
		vmoving = 0;
		break;

	default:
		/*
		 * Stuttered operators are equivalent to the operator on
		 * a line, thus turn dd into d_.
		 */
		if (opf == vmove || c != workcmd[0]) {
errlab:
			beep();
			return;
		}
		/* fall into ... */

	/*
	 * _		Target for a line or group of lines.
	 *		Stuttering is more convenient; this is mostly
	 *		for aesthetics.
	 */
	case '_':
		wdot = dot + cnt - 1;
		vmoving = 0;
		wcursor = 0;
		break;

	/*
	 * H		To first, home line on screen.
	 *		Count is for count'th line rather than first.
	 */
	case 'H':
		wdot = (dot - vcline) + cnt - 1;
		if (opf == vmove)
			markit(wdot);
		vmoving = 0;
		wcursor = 0;
		break;

	/*
	 * -		Backwards lines, to first non-white character.
	 */
	case '-':
		wdot = dot - cnt;
		vmoving = 0;
		wcursor = 0;
		break;

	/*
	 * ^P		To previous line same column.  Ridiculous on the
	 *		console of the VAX since it puts console in LSI mode.
	 */
	case CTRL('p'):
		wdot = dot - cnt;
		if (vmoving == 0)
			vmoving = 1, vmovcol = column(cursor);
		wcursor = 0;
		break;

	/*
	 * L		To last line on screen, or count'th line from the
	 *		bottom.
	 */
	case 'L':
		wdot = dot + vcnt - vcline - cnt;
		if (opf == vmove)
			markit(wdot);
		vmoving = 0;
		wcursor = 0;
		break;

	/*
	 * M		To the middle of the screen.
	 */
	case 'M':
		wdot = dot + ((vcnt + 1) / 2) - vcline - 1;
		if (opf == vmove)
			markit(wdot);
		vmoving = 0;
		wcursor = 0;
		break;

	/*
	 * +		Forward line, to first non-white.
	 *
	 * CR		Convenient synonym for +.
	 */
	case '+':
	case CR:
		wdot = dot + cnt;
		vmoving = 0;
		wcursor = 0;
		break;

	/*
	 * ^N		To next line, same column if possible.
	 *
	 * LF		Linefeed is a convenient synonym for ^N.
	 */
	case CTRL('n'):
	case NL:
		wdot = dot + cnt;
		if (vmoving == 0)
			vmoving = 1, vmovcol = column(cursor);
		wcursor = 0;
		break;

	/*
	 * n		Search to next match of current pattern.
	 */
	case 'n':
		vglobp = vscandir;
		c = *vglobp++;
		goto nocount;

	/*
	 * N		Like n but in reverse direction.
	 */
	case 'N':
		vglobp = vscandir[0] == '/' ? "?" : "/";
		c = *vglobp++;
		goto nocount;

	/*
	 * '		Return to line specified by following mark,
	 *		first white position on line.
	 *
	 * `		Return to marked line at remembered column.
	 */
	case '\'':
	case '`':
		d = c;
		c = getesc();
		if (c == 0)
			return;
		c = markreg(c);
		forbid (c == 0);
		wdot = getmark(c);
		forbid (wdot == NOLINE);
		if (Xhadcnt)
			vsetsiz(Xcnt);
		if (opf == vmove)
			markit(wdot);
		vmoving = 0;
		wcursor = d == '`' ? ncols[c - 'a'] : 0;
		if (wcursor) {
			vsave();
			ex_getline(*wdot);
			if (wcursor > strend(linebuf))
				wcursor = 0;
			getDOT();
		}
		if (ex_ospeed > B300)
			hold |= HOLDWIG;
		break;

	/*
	 * G		Goto count'th line, or last line if no count
	 *		given.
	 */
	case 'G':
		if (!Xhadcnt)
			cnt = lineDOL();
		wdot = zero + cnt;
		forbid (wdot < one || wdot > dol);
		if (opf == vmove)
			markit(wdot);
		vmoving = 0;
		wcursor = 0;
		break;

	/*
	 * /		Scan forward for following re.
	 * ?		Scan backward for following re.
	 */
	case '/':
	case '?':
		if (Xhadcnt)
			vsetsiz(Xcnt);
		vsave();
		ocurs = cursor;
		wcursor = 0;
		if (readecho(c))
			return;
		if (!vglobp)
			vscandir[0] = genbuf[0];
		oglobp = globp; CP(vutmp, genbuf); globp = vutmp;
		d = peekc; ungetchar(0); fixech();
		CATCH
#ifdef V6
			/*
			 * Lose typeahead (ick).
			 */
			vcook();
#endif
			addr = address();
#ifdef V6
			vraw();
#endif
		ONERR
#ifdef V6
			vraw();
#endif
			globp = oglobp;
			ungetchar(d);
			splitw = 0;
			vclean();
			vjumpto(dot, ocurs, 0);
			return;
		ENDCATCH
		if (globp == 0)
			globp = "";
		else if (peekc)
			--globp;
		ungetchar(d);
		c = 0;
		if (*globp == 'z')
			globp++, c = '\n';
		if (any(*globp, "^+-."))
			c = *globp++;
		i = 0;
		while (isdigit((int)*globp))
			i = i * 10 + *globp++ - '0';
		if (*globp)
			c = *globp++;
		globp = oglobp;
		splitw = 0;
		vmoving = 0;
		if (i != 0)
			vsetsiz(i);
		if (opf == vmove) {
			if (state == ONEOPEN || state == HARDOPEN)
				outline = destline = WBOT;
			markit(addr);
			if (loc1 > linebuf && *loc1 == 0)
				loc1--;
			if (c)
				vjumpto(addr, loc1, c);
			else {
				vmoving = 0;
				if (loc1) {
					vmoving++;
					vmovcol = column(loc1);
				}
				getDOT();
				if (state == CRTOPEN && addr != dot)
					vup1();
				vupdown(addr - dot, NOSTR);
			}
			return;
		}
		lastcp[-1] = 'n';
		getDOT();
		wdot = addr;
		break;
	}
	/*
	 * Apply.
	 */
	if (vreg && wdot == 0)
		wdot = dot;
	(*opf)(c);
	wdot = NOLINE;
}
예제 #5
0
/*
 * Find over structure, repeated count times.
 * Don't go past line limit.  F is the operation to
 * be performed eventually.  If pastatom then the user said {}
 * rather than (), implying past atoms in a list (or a paragraph
 * rather than a sentence.
 */
int
llfind(bool pastatom, int cnt, void (*f)(int), line *limit)
{
#ifdef	LISPCODE
	register int c;
#endif
	register int rc = 0;
	char *save = smalloc(LBSIZE);

	/*
	 * Initialize, saving the current line buffer state
	 * and computing the limit; a 0 argument means
	 * directional end of file.
	 */
	wasend = 0;
	lf = f;
	lcpy(save, linebuf, LBSIZE);
	if (limit == 0)
		limit = dir < 0 ? one : dol;
	llimit = limit;
	wdot = dot;
	wcursor = cursor;

	if (pastatom >= 2) {
		while (cnt > 0 && word(f, cnt))
			cnt--;
		if (pastatom == 3)
			eend(f);
		if (dot == wdot) {
			wdot = 0;
			if (cursor == wcursor)
				rc = -1;
		}
	}
#ifdef LISPCODE
	else if (!value(LISP)) {
#else
	else {
#endif
		char *icurs;
		line *idot;

		if (linebuf[0] == 0) {
			do
				if (!lnext())
					goto ret;
			while (linebuf[0] == 0);
			if (dir > 0) {
				wdot--;
				linebuf[0] = 0;
				wcursor = linebuf;
				/*
				 * If looking for sentence, next line
				 * starts one.
				 */
				if (!pastatom) {
					icurs = wcursor;
					idot = wdot;
					goto begin;
				}
			}
		}
		icurs = wcursor;
		idot = wdot;

		/*
		 * Advance so as to not find same thing again.
		 */
		if (dir > 0) {
			if (!lnext()) {
				rc = -1;
				goto ret;
			}
		} else
			ignore(lskipa1(""));

		/*
		 * Count times find end of sentence/paragraph.
		 */
begin:
		for (;;) {
			while (!endsent(pastatom))
				if (!lnext())
					goto ret;
			if (!pastatom || (wcursor == linebuf && endPS()))
				if (--cnt <= 0)
					break;
			if (linebuf[0] == 0) {
				do
					if (!lnext())
						goto ret;
				while (linebuf[0] == 0);
			} else
				if (!lnext())
					goto ret;
		}

		/*
		 * If going backwards, and didn't hit the end of the buffer,
		 * then reverse direction.
		 */
		if (dir < 0 && (wdot != llimit || wcursor != linebuf)) {
			dir = 1;
			llimit = dot;
			/*
			 * Empty line needs special treatement.
			 * If moved to it from other than begining of next line,
			 * then a sentence starts on next line.
			 */
			if (linebuf[0] == 0 && !pastatom && 
			   (wdot != dot - 1 || cursor != linebuf)) {
				lnext();
				goto ret;
			}
		}

		/*
		 * If we are not at a section/paragraph division,
		 * advance to next.
		 */
		if ((wcursor == icurs && wdot == idot) || wcursor != linebuf || !endPS())
			ignore(lskipa1(""));
	}
#ifdef LISPCODE
	else {
		c = *wcursor;
		/*
		 * Startup by skipping if at a ( going left or a ) going
		 * right to keep from getting stuck immediately.
		 */
		if ((dir < 0 && c == '(') || (dir > 0 && c == ')')) {
			if (!lnext()) {
				rc = -1;
				goto ret;
			}
		}
		/*
		 * Now chew up repitition count.  Each time around
		 * if at the beginning of an s-exp (going forwards)
		 * or the end of an s-exp (going backwards)
		 * skip the s-exp.  If not at beg/end resp, then stop
		 * if we hit a higher level paren, else skip an atom,
		 * counting it unless pastatom.
		 */
		while (cnt > 0) {
			c = *wcursor;
			if ((dir < 0 && c == ')') || (dir > 0 && c == '(')) {
				if (!lskipbal("()"))
					goto ret;
				/*
 				 * Unless this is the last time going
				 * backwards, skip past the matching paren
				 * so we don't think it is a higher level paren.
				 */
				if (dir < 0 && cnt == 1)
					goto ret;
				if (!lnext() || !ltosolid())
					goto ret;
				--cnt;
			} else if ((dir < 0 && c == '(') || (dir > 0 && c == ')'))
				/* Found a higher level paren */
				goto ret;
			else {
				if (!lskipatom())
					goto ret;
				if (!pastatom)
					--cnt;
			}
		}
	}
#endif
ret:
	strcLIN(save);
	free(save);
	return (rc);
}