Ejemplo n.º 1
0
Archivo: tags.c Proyecto: hackalog/mg
/*
 * Extract the word at dot without changing dot position.
 */
int
curtoken(int f, int n, char *token)
{
	struct line *odotp;
	int odoto, tdoto, odotline, size, r;
	char c;
	
	/* Underscore character is to be treated as "inword" while
	 * processing tokens unlike mg's default word traversal. Save
	 * and restore it's cinfo value so that tag matching works for
	 * identifier with underscore.
	 */
	c = cinfo['_'];
	cinfo['_'] = _MG_W;
	
	odotp = curwp->w_dotp;
	odoto = curwp->w_doto;
	odotline = curwp->w_dotline;
	
	/* Move backword unless we are at the beginning of a word or at
	 * beginning of line.
	 */
	if (!atbow())
		if ((r = backword(f, n)) == FALSE)
			goto cleanup;
		
	tdoto = curwp->w_doto;

	if ((r = forwword(f, n)) == FALSE)
		goto cleanup;
	
	/* strip away leading whitespace if any like emacs. */
	while (ltext(curwp->w_dotp) && 
	    isspace(lgetc(curwp->w_dotp, tdoto)))
		tdoto++;

	size = curwp->w_doto - tdoto;
	if (size <= 0 || size >= MAX_TOKEN || 
	    ltext(curwp->w_dotp) == NULL) {
		r = FALSE;
		goto cleanup;
	}    
	strncpy(token, ltext(curwp->w_dotp) + tdoto, size);
	token[size] = '\0';
	r = TRUE;
	
cleanup:
	cinfo['_'] = c;
	curwp->w_dotp = odotp;
	curwp->w_doto = odoto;
	curwp->w_dotline = odotline;
	return (r);
}
Ejemplo n.º 2
0
/*
 * This function does the work of counting matching lines.
 */
int
countmatches(int cond)
{
	int	 error;
	int	 count = 0;
	struct line	*clp;

	clp = curwp->w_dotp;
	if (curwp->w_doto == llength(clp))
		/* Consider dot on next line */
		clp = lforw(clp);

	while (clp != (curbp->b_headp)) {
		/* see if line matches */
		regex_match[0].rm_so = 0;
		regex_match[0].rm_eo = llength(clp);
		error = regexec_new(&re_buff, ltext(clp), RE_NMATCH, regex_match,
		    REG_STARTEND);

		/* Count line when appropriate */
		if ((cond == FALSE && error) || (cond == TRUE && !error))
			count++;
		clp = lforw(clp);
	}

	if (cond)
		ewprintf("Number of lines matching: %d", count);
	else
		ewprintf("Number of lines not matching: %d", count);

	return (TRUE);
}
Ejemplo n.º 3
0
Archivo: fileio.c Proyecto: hackalog/mg
/*
 * Write a buffer to the already opened file. bp points to the
 * buffer. Return the status.
 */
int
ffputbuf(FILE *ffp, struct buffer *bp)
{
	struct line   *lp, *lpend;

	lpend = bp->b_headp;
	for (lp = lforw(lpend); lp != lpend; lp = lforw(lp)) {
		if (fwrite(ltext(lp), 1, llength(lp), ffp) != llength(lp)) {
			dobeep();
			ewprintf("Write I/O error");
			return (FIOERR);
		}
		if (lforw(lp) != lpend)		/* no implied \n on last line */
			putc('\n', ffp);
	}
	/*
	 * XXX should be variable controlled (once we have variables)
	 */
	if (llength(lback(lpend)) != 0) {
		if (eyorn("No newline at end of file, add one") == TRUE) {
			lnewline_at(lback(lpend), llength(lback(lpend)));
			putc('\n', ffp);
		}
	}
	return (FIOSUC);
}
Ejemplo n.º 4
0
/*
 * This routine does the real work of a backward search.  The pattern is sitting
 * in the external variable "re_pat".  If found, dot is updated, the window
 * system is notified of the change, and TRUE is returned.  If the string isn't
 * found, FALSE is returned.
 */
static int
re_backsrch(void)
{
	struct line     *clp;
	int		 tbo;
	regmatch_t	 lastmatch;

	lastmatch.rm_eo = 0;
	clp = curwp->w_dotp;
	tbo = curwp->w_doto;

	/* Start search one position to the left of dot */
	tbo = tbo - 1;
	if (tbo < 0) {
		/* must move up one line */
		clp = lback(clp);
		tbo = llength(clp);
	}

	/*
	 * Note this loop does not process the last line, but this editor
	 * always makes the last line empty so this is good.
	 */
	while (clp != (curbp->b_headp)) {
		regex_match[0].rm_so = 0;
		regex_match[0].rm_eo = llength(clp);
		lastmatch.rm_so = -1;
		/*
		 * Keep searching until we don't match any longer.  Assumes a
		 * non-match does not modify the regex_match array.  We have to
		 * do this character-by-character after the first match since
		 * POSIX regexps don't give you a way to do reverse matches.
		 */
		while (!regexec_new(&re_buff, ltext(clp), RE_NMATCH, regex_match,
		    REG_STARTEND) && regex_match[0].rm_so < tbo) {
			memcpy(&lastmatch, &regex_match[0], sizeof(regmatch_t));
			regex_match[0].rm_so++;
			regex_match[0].rm_eo = llength(clp);
		}
		if (lastmatch.rm_so == -1) {
			clp = lback(clp);
			tbo = llength(clp);
		} else {
			memcpy(&regex_match[0], &lastmatch, sizeof(regmatch_t));
			curwp->w_doto = regex_match[0].rm_so;
			curwp->w_dotp = clp;
			curwp->w_rflag |= WFMOVE;
			return (TRUE);
		}
	}
	return (FALSE);
}
Ejemplo n.º 5
0
Archivo: tags.c Proyecto: hackalog/mg
/*
 * Search through each line of buffer for pattern.
 */
int
searchpat(char *pat)
{
	struct line *lp;
	int dotline;
	size_t plen;

	plen = strlen(pat);
	dotline = 1;
	lp = lforw(curbp->b_headp);
	while (lp != curbp->b_headp) {
		if (ltext(lp) != NULL && plen <= llength(lp) &&
		    (strncmp(pat, ltext(lp), plen) == 0)) {
			curwp->w_doto = 0;
			curwp->w_dotp = lp;
			curwp->w_dotline = dotline;
			return (TRUE);
		} else {
			lp = lforw(lp);
			dotline++;
		}
	}
	return (FALSE);
}
Ejemplo n.º 6
0
Archivo: extend.c Proyecto: mbkulik/mg
/* ARGSUSED */
int
evalbuffer(int f, int n)
{
	struct line		*lp;
	struct buffer		*bp = curbp;
	int		 s;
	static char	 excbuf[128];

	for (lp = bfirstlp(bp); lp != bp->b_headp; lp = lforw(lp)) {
		if (llength(lp) >= 128)
			return (FALSE);
		(void)strncpy(excbuf, ltext(lp), llength(lp));

		/* make sure it's terminated */
		excbuf[llength(lp)] = '\0';
		if ((s = excline(excbuf)) != TRUE)
			return (s);
	}
	return (TRUE);
}
Ejemplo n.º 7
0
/*
 * This function does the work of deleting matching lines.
 */
static int
killmatches(int cond)
{
	int	 s, error;
	int	 count = 0;
	struct line	*clp;

	clp = curwp->w_dotp;
	if (curwp->w_doto == llength(clp))
		/* Consider dot on next line */
		clp = lforw(clp);

	while (clp != (curbp->b_headp)) {
		/* see if line matches */
		regex_match[0].rm_so = 0;
		regex_match[0].rm_eo = llength(clp);
		error = regexec_new(&re_buff, ltext(clp), RE_NMATCH, regex_match,
		    REG_STARTEND);

		/* Delete line when appropriate */
		if ((cond == FALSE && error) || (cond == TRUE && !error)) {
			curwp->w_doto = 0;
			curwp->w_dotp = clp;
			count++;
			s = ldelete(llength(clp) + 1, KNONE);
			clp = curwp->w_dotp;
			curwp->w_rflag |= WFMOVE;
			if (s == FALSE)
				return (FALSE);
		} else
			clp = lforw(clp);
	}

	ewprintf("%d line(s) deleted", count);
	if (count > 0)
		curwp->w_rflag |= WFMOVE;

	return (TRUE);
}
Ejemplo n.º 8
0
/*
 * This routine does the real work of a forward search.  The pattern is
 * sitting in the external variable "pat".  If found, dot is updated, the
 * window system is notified of the change, and TRUE is returned.  If the
 * string isn't found, FALSE is returned.
 */
static int
re_forwsrch(void)
{
	int	 tbo, error;
	struct line	*clp;

	clp = curwp->w_dotp;
	tbo = curwp->w_doto;

	if (tbo == clp->l_used)
		/*
		 * Don't start matching past end of line -- must move to
		 * beginning of next line, unless at end of file.
		 */
		if (clp != curbp->b_headp) {
			clp = lforw(clp);
			tbo = 0;
		}
	/*
	 * Note this loop does not process the last line, but this editor
	 * always makes the last line empty so this is good.
	 */
	while (clp != (curbp->b_headp)) {
		regex_match[0].rm_so = tbo;
		regex_match[0].rm_eo = llength(clp);
		error = regexec_new(&re_buff, ltext(clp), RE_NMATCH, regex_match,
		    REG_STARTEND);
		if (error != 0) {
			clp = lforw(clp);
			tbo = 0;
		} else {
			curwp->w_doto = regex_match[0].rm_eo;
			curwp->w_dotp = clp;
			curwp->w_rflag |= WFMOVE;
			return (TRUE);
		}
	}
	return (FALSE);
}
Ejemplo n.º 9
0
Archivo: extend.c Proyecto: mbkulik/mg
/*
 * excline - run a line from a load file or eval-expression.  If FKEYS is
 * defined, duplicate functionality of dobind so function key values don't
 * have to fit in type char.
 */
int
excline(char *line)
{
	PF	 fp;
	struct line	*lp, *np;
	int	 status, c, f, n;
	char	*funcp, *tmp;
	char	*argp = NULL;
	long	 nl;
#ifdef	FKEYS
	int	 bind;
	KEYMAP	*curmap;
#define BINDARG		0  /* this arg is key to bind (local/global set key) */
#define	BINDNO		1  /* not binding or non-quoted BINDARG */
#define BINDNEXT	2  /* next arg " (define-key) */
#define BINDDO		3  /* already found key to bind */
#define BINDEXT		1  /* space for trailing \0 */
#else /* FKEYS */
#define BINDEXT		0
#endif /* FKEYS */

	lp = NULL;

	if (macrodef || inmacro) {
		ewprintf("Not now!");
		return (FALSE);
	}
	f = 0;
	n = 1;
	funcp = skipwhite(line);
	if (*funcp == '\0')
		return (TRUE);	/* No error on blank lines */
	line = parsetoken(funcp);
	if (*line != '\0') {
		*line++ = '\0';
		line = skipwhite(line);
		if (ISDIGIT(*line) || *line == '-') {
			argp = line;
			line = parsetoken(line);
		}
	}
	if (argp != NULL) {
		f = FFARG;
		nl = strtol(argp, &tmp, 10);
		if (*tmp != '\0')
			return (FALSE);
		if (nl >= INT_MAX || nl <= INT_MIN)
			return (FALSE);
		n = (int)nl;
	}
	if ((fp = name_function(funcp)) == NULL) {
		ewprintf("Unknown function: %s", funcp);
		return (FALSE);
	}
#ifdef	FKEYS
	if (fp == bindtokey || fp == unbindtokey) {
		bind = BINDARG;
		curmap = fundamental_map;
	} else if (fp == localbind || fp == localunbind) {
		bind = BINDARG;
		curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
	} else if (fp == redefine_key)
		bind = BINDNEXT;
	else
		bind = BINDNO;
#endif /* FKEYS */
	/* Pack away all the args now... */
	if ((np = lalloc(0)) == FALSE)
		return (FALSE);
	np->l_fp = np->l_bp = maclcur = np;
	while (*line != '\0') {
		argp = skipwhite(line);
		if (*argp == '\0')
			break;
		line = parsetoken(argp);
		if (*argp != '"') {
			if (*argp == '\'')
				++argp;
			if ((lp = lalloc((int) (line - argp) + BINDEXT)) ==
			    NULL) {
				status = FALSE;
				goto cleanup;
			}
			bcopy(argp, ltext(lp), (int)(line - argp));
#ifdef	FKEYS
			/* don't count BINDEXT */
			lp->l_used--;
			if (bind == BINDARG)
				bind = BINDNO;
#endif /* FKEYS */
		} else {
			/* quoted strings are special */
			++argp;
#ifdef	FKEYS
			if (bind != BINDARG) {
#endif /* FKEYS */
				lp = lalloc((int)(line - argp) + BINDEXT);
				if (lp == NULL) {
					status = FALSE;
					goto cleanup;
				}
				lp->l_used = 0;
#ifdef	FKEYS
			} else
				key.k_count = 0;
#endif /* FKEYS */
			while (*argp != '"' && *argp != '\0') {
				if (*argp != '\\')
					c = *argp++;
				else {
					switch (*++argp) {
					case 't':
					case 'T':
						c = CCHR('I');
						break;
					case 'n':
					case 'N':
						c = CCHR('J');
						break;
					case 'r':
					case 'R':
						c = CCHR('M');
						break;
					case 'e':
					case 'E':
						c = CCHR('[');
						break;
					case '^':
						/*
						 * split into two statements
						 * due to bug in OSK cpp
						 */
						c = CHARMASK(*++argp);
						c = ISLOWER(c) ?
						    CCHR(TOUPPER(c)) : CCHR(c);
						break;
					case '0':
					case '1':
					case '2':
					case '3':
					case '4':
					case '5':
					case '6':
					case '7':
						c = *argp - '0';
						if (argp[1] <= '7' &&
						    argp[1] >= '0') {
							c <<= 3;
							c += *++argp - '0';
							if (argp[1] <= '7' &&
							    argp[1] >= '0') {
								c <<= 3;
								c += *++argp
								    - '0';
							}
						}
						break;
#ifdef	FKEYS
					case 'f':
					case 'F':
						c = *++argp - '0';
						if (ISDIGIT(argp[1])) {
							c *= 10;
							c += *++argp - '0';
						}
						c += KFIRST;
						break;
#endif /* FKEYS */
					default:
						c = CHARMASK(*argp);
						break;
					}
					argp++;
				}
#ifdef	FKEYS
				if (bind == BINDARG)
					key.k_chars[key.k_count++] = c;
				else
#endif /* FKEYS */
					lp->l_text[lp->l_used++] = c;
			}
			if (*line)
				line++;
		}
#ifdef	FKEYS
		switch (bind) {
		case BINDARG:
			bind = BINDDO;
			break;
		case BINDNEXT:
			lp->l_text[lp->l_used] = '\0';
			if ((curmap = name_map(lp->l_text)) == NULL) {
				ewprintf("No such mode: %s", lp->l_text);
				status = FALSE;
				free(lp);
				goto cleanup;
			}
			free(lp);
			bind = BINDARG;
			break;
		default:
#endif /* FKEYS */
			lp->l_fp = np->l_fp;
			lp->l_bp = np;
			np->l_fp = lp;
			np = lp;
#ifdef	FKEYS
		}
#endif /* FKEYS */
	}
#ifdef	FKEYS
	switch (bind) {
	default:
		ewprintf("Bad args to set key");
		status = FALSE;
		break;
	case BINDDO:
		if (fp != unbindtokey && fp != localunbind) {
			lp->l_text[lp->l_used] = '\0';
			status = bindkey(&curmap, lp->l_text, key.k_chars,
			    key.k_count);
		} else
			status = bindkey(&curmap, NULL, key.k_chars,
			    key.k_count);
		break;
	case BINDNO:
#endif /* FKEYS */
		inmacro = TRUE;
		maclcur = maclcur->l_fp;
		status = (*fp)(f, n);
		inmacro = FALSE;
#ifdef	FKEYS
	}
#endif /* FKEYS */
cleanup:
	lp = maclcur->l_fp;
	while (lp != maclcur) {
		np = lp->l_fp;
		free(lp);
		lp = np;
	}
	free(lp);
	return (status);
}
Ejemplo n.º 10
0
int
insertfile(char *fname, char *newname, int replacebuf)
{
	struct buffer	*bp;
	struct line	*lp1, *lp2;
	struct line	*olp;			/* line we started at */
	struct mgwin	*wp;
	int	 nbytes, s, nline = 0, siz, x, x2;
	int	 opos;			/* offset we started at */
	int	 oline;			/* original line number */
	char *dp;

	if (replacebuf == TRUE)
		x = undo_enable(FFRAND, 0);
	else
		x = undo_enabled();

	lp1 = NULL;
	if (line == NULL) {
		line = malloc(NLINE);
		if (line == NULL)
			panic("out of memory");
		linesize = NLINE;
	}

	/* cheap */
	bp = curbp;
	if (newname != NULL) {
		(void)strlcpy(bp->b_fname, newname, sizeof(bp->b_fname));
		dp = xdirname(newname);
		(void)strlcpy(bp->b_cwd, dp, sizeof(bp->b_cwd));
		(void)strlcat(bp->b_cwd, "/", sizeof(bp->b_cwd));
		free(dp);
	}

	/* hard file open */
	if ((s = ffropen(fname, (replacebuf == TRUE) ? bp : NULL)) == FIOERR)
		goto out;
	if (s == FIOFNF) {
		/* file not found */
		if (newname != NULL)
			ewprintf("(New file)");
		else
			ewprintf("(File not found)");
		goto out;
	} else if (s == FIODIR) {
		/* file was a directory */
		if (replacebuf == FALSE) {
			ewprintf("Cannot insert: file is a directory, %s",
			    fname);
			goto cleanup;
		}
		killbuffer(bp);
		if ((bp = dired_(fname)) == NULL)
			return (FALSE);
		undo_enable(FFRAND, x);
		curbp = bp;
		return (showbuffer(bp, curwp, WFFULL | WFMODE));
	} else {
		dp = xdirname(fname);
		(void)strlcpy(bp->b_cwd, dp, sizeof(bp->b_cwd));
		(void)strlcat(bp->b_cwd, "/", sizeof(bp->b_cwd));
		free(dp);
	}
	opos = curwp->w_doto;
	oline = curwp->w_dotline;
	/*
	 * Open a new line at dot and start inserting after it.
	 * We will delete this newline after insertion.
	 * Disable undo, as we create the undo record manually.
	 */
	x2 = undo_enable(FFRAND, 0);
	(void)lnewline();
	olp = lback(curwp->w_dotp);
	undo_enable(FFRAND, x2);

	nline = 0;
	siz = 0;
	while ((s = ffgetline(line, linesize, &nbytes)) != FIOERR) {
retry:
		siz += nbytes + 1;
		switch (s) {
		case FIOSUC:
			/* FALLTHRU */
		case FIOEOF:
			++nline;
			if ((lp1 = lalloc(nbytes)) == NULL) {
				/* keep message on the display */
				s = FIOERR;
				undo_add_insert(olp, opos,
				    siz - nbytes - 1 - 1);
				goto endoffile;
			}
			bcopy(line, &ltext(lp1)[0], nbytes);
			lp2 = lback(curwp->w_dotp);
			lp2->l_fp = lp1;
			lp1->l_fp = curwp->w_dotp;
			lp1->l_bp = lp2;
			curwp->w_dotp->l_bp = lp1;
			if (s == FIOEOF) {
				undo_add_insert(olp, opos, siz - 1);
				goto endoffile;
			}
			break;
		case FIOLONG: {
				/* a line too long to fit in our buffer */
				char	*cp;
				int	newsize;

				newsize = linesize * 2;
				if (newsize < 0 ||
				    (cp = malloc(newsize)) == NULL) {
					ewprintf("Could not allocate %d bytes",
					    newsize);
						s = FIOERR;
						goto endoffile;
				}
				bcopy(line, cp, linesize);
				free(line);
				line = cp;
				s = ffgetline(line + linesize, linesize,
				    &nbytes);
				nbytes += linesize;
				linesize = newsize;
				if (s == FIOERR)
					goto endoffile;
				goto retry;
			}
		default:
			ewprintf("Unknown code %d reading file", s);
			s = FIOERR;
			break;
		}
	}
endoffile:
	/* ignore errors */
	ffclose(NULL);
	/* don't zap an error */
	if (s == FIOEOF) {
		if (nline == 1)
			ewprintf("(Read 1 line)");
		else
			ewprintf("(Read %d lines)", nline);
	}
	/* set mark at the end of the text */
	curwp->w_dotp = curwp->w_markp = lback(curwp->w_dotp);
	curwp->w_marko = llength(curwp->w_markp);
	curwp->w_markline = oline + nline + 1;
	/*
	 * if we are at the end of the file, ldelnewline is a no-op,
	 * but we still need to decrement the line and markline counts
	 * as we've accounted for this fencepost in our arithmetic
	 */
	if (lforw(curwp->w_dotp) == curwp->w_bufp->b_headp) {
		curwp->w_bufp->b_lines--;
		curwp->w_markline--;
	} else
		(void)ldelnewline();
	curwp->w_dotp = olp;
	curwp->w_doto = opos;
	curwp->w_dotline = oline;
	if (olp == curbp->b_headp)
		curwp->w_dotp = lforw(olp);
	if (newname != NULL)
		bp->b_flag |= BFCHG | BFBAK;	/* Need a backup.	 */
	else
		bp->b_flag |= BFCHG;
	/*
	 * If the insert was at the end of buffer, set lp1 to the end of
	 * buffer line, and lp2 to the beginning of the newly inserted text.
	 * (Otherwise lp2 is set to NULL.)  This is used below to set
	 * pointers in other windows correctly if they are also at the end of
	 * buffer.
	 */
	lp1 = bp->b_headp;
	if (curwp->w_markp == lp1) {
		lp2 = curwp->w_dotp;
	} else {
		/* delete extraneous newline */
		(void)ldelnewline();
out:		lp2 = NULL;
	}
	for (wp = wheadp; wp != NULL; wp = wp->w_wndp) {
		if (wp->w_bufp == curbp) {
			wp->w_flag |= WFMODE | WFEDIT;
			if (wp != curwp && lp2 != NULL) {
				if (wp->w_dotp == lp1)
					wp->w_dotp = lp2;
				if (wp->w_markp == lp1)
					wp->w_markp = lp2;
				if (wp->w_linep == lp1)
					wp->w_linep = lp2;
			}
		}
	}
	bp->b_lines += nline;
cleanup:
	undo_enable(FFRAND, x);

	/* return FALSE if error */
	return (s != FIOERR);
}
Ejemplo n.º 11
0
/*ARGSUSED */
int
diffbuffer(int f, int n)
{
	struct buffer	*bp;
	struct line	*lp, *lpend;
	size_t		 len;
	int		 ret;
	char		*text, *ttext;
	char		* const argv[] =
	    {DIFFTOOL, "-u", "-p", curbp->b_fname, "-", (char *)NULL};

	len = 0;

	/* C-u is not supported */
	if (n > 1)
		return (ABORT);

	if (access(DIFFTOOL, X_OK) != 0) {
		dobeep();
		ewprintf("%s not found or not executable.", DIFFTOOL);
		return (FALSE);
	}

	if (curbp->b_fname[0] == 0) {
		dobeep();
		ewprintf("Cannot diff buffer not associated with any files.");
		return (FALSE);
	}

	lpend = curbp->b_headp;
	for (lp = lforw(lpend); lp != lpend; lp = lforw(lp)) {
		len+=llength(lp);
		if (lforw(lp) != lpend)		/* no implied \n on last line */
			len++;
	}
	if ((text = calloc(len + 1, sizeof(char))) == NULL) {
		dobeep();
		ewprintf("Cannot allocate memory.");
		return (FALSE);
	}
	ttext = text;

	for (lp = lforw(lpend); lp != lpend; lp = lforw(lp)) {
		if (llength(lp) != 0) {
			memcpy(ttext, ltext(lp), llength(lp));
			ttext += llength(lp);
		}
		if (lforw(lp) != lpend)		/* no implied \n on last line */
			*ttext++ = '\n';
	}

	bp = bfind("*Diff*", TRUE);
	bp->b_flag |= BFREADONLY;
	if (bclear(bp) != TRUE) {
		free(text);
		return (FALSE);
	}

	ret = pipeio(DIFFTOOL, argv, text, len, bp);

	if (ret == TRUE) {
		eerase();
		if (lforw(bp->b_headp) == bp->b_headp)
			addline(bp, "Diff finished (no differences).");
	}

	free(text);
	return (ret);
}
Ejemplo n.º 12
0
static void _std getlog(log_header *log, void *extptr) {
   getloginfo *pli = (getloginfo*)extptr;
   int    puretext = (pli->flags&(LOGTF_DATE|LOGTF_TIME|LOGTF_LEVEL))==0;

   if (puretext) {
      spstr ltext;
      while (log->offset) {
         if ((log->flags&LOGIF_USED)!=0 && ((pli->flags&LOGTF_LEVEL)==0 ||
           (pli->flags&LOGTF_LEVELMASK)>=(log->flags&LOGIF_LEVELMASK)))
         {
            ltext+=(char*)(log+1);
         }
         log+=log->offset;
      }
      if (pli->flags&LOGTF_DOSTEXT) ltext.replace("\n","\r\n");
      // make copy a bit faster
      pli->rc = (char*)malloc(ltext.length()+1);
      memcpy(pli->rc, ltext(), ltext.length());
      pli->rc[ltext.length()] = 0;
   } else {
      TStrings    lst;
      struct tm    dt;
      u32t      pdtme = 0;
      time_t     ptme;

      while (log->offset) {
         if ((log->flags&LOGIF_USED)!=0 && ((pli->flags&LOGTF_LEVEL)==0 ||
           (pli->flags&LOGTF_LEVELMASK)>=(log->flags&LOGIF_LEVELMASK)))
         {
            if (pdtme!=log->dostime) {
               dostimetotm(pdtme=log->dostime,&dt);
               ptme = mktime(&dt);
            }
            spstr estr, astr;

            if (pli->flags&LOGTF_DATE)
               estr.sprintf("%02d.%02d.%02d ",dt.tm_mday,dt.tm_mon+1,dt.tm_year-100);
            if (pli->flags&LOGTF_TIME) {
               int sec = dt.tm_sec;
               if (log->flags&LOGIF_SECOND) sec++;
               astr.sprintf("%02d:%02d:%02d ",dt.tm_hour, dt.tm_min, sec);
               estr+=astr;
            }
            if (pli->flags&LOGTF_LEVEL) {
               if (pli->flags&LOGTF_FLAGS)
                  astr.sprintf("[%c%d%c] ",log->flags&LOGIF_REALMODE?'r':' ',
                     log->flags&LOGIF_LEVELMASK,log->flags&LOGIF_DELAY?'d':' ');
               else
                  astr.sprintf("[%d] ",log->flags&LOGIF_LEVELMASK);
               estr+=astr;
            }
            estr+=(char*)(log+1);
            if (estr.lastchar()=='\n') estr.dellast();
            lst.AddObject(estr,ptme);
         }
         log+=log->offset;
      }
      int ii,jj;
      const char *eol = pli->flags&LOGTF_DOSTEXT?"\r\n":"\n";

      log_it(2, "%d lines of log queried\n", lst.Count());

      for (ii=1;ii<lst.Count();ii++)
         // we`re can`t fill entire log for 3 seconds
         if (lst.Objects(ii-1)-lst.Objects(ii)>3) break;
      // re-order cyclic added lines
      if (ii<lst.Count()) {
         spstr t1 = lst.GetTextToStr(eol,ii),
               t2 = lst.GetTextToStr(eol,0,ii);
         pli->rc = (char*)malloc(t1.length()+t2.length()+1);
         memcpy(pli->rc, t1(), t1.length());
         memcpy(pli->rc+t1.length(), t2(), t2.length()+1);
      } else
         pli->rc = lst.GetText(eol);
   }
}
Ejemplo n.º 13
0
// Display a pop-up window and page it for the user.  If altmodeline is true, display buffer name and filename (only) on bottom
// mode line.  If endprompt is true, wait for user to press a key before returning (regardless of page size).  Current bindings
// (if any) for backPage, forwPage, backLine, and forwLine commands are recognized as well as 'b' (backward page), 'f' or space
// (forward page), 'u' (backward half page), 'd' (forward half page), 'g' (goto first page), 'G' (goto last page), ESC or 'q'
// (exit), and '?' (help).  Any non-navigation key gets pushed back into the input stream to be interpeted later as a command. 
// Return status.
int bpop(Buffer *bufp,bool altmodeline,bool endprompt) {
	Line *lnp1,*lnp,*lpmax;
	int crow;		// Current screen row number.
	int disprows;		// Total number of display rows.
	int halfpage;		// Rows in a half page.
	int n;			// Rows to move.
	ushort ek;		// Input extended key.
	char *strp,*strpz;	// Line text pointers.
	char *hprompt = NULL;	// Help prompt;
	bool firstpass = true;

	// Display special mode line if requested.
	if(altmodeline) {

		// Find last window on screen and rewrite its mode line.
		wupd_modeline(wnextis(NULL),bufp);
		}

	// Set up and display a pop-up "window".
	disprows = term.t_nrow - 2;

	// Check if buffer will fit on one page and if not, set lpmax to first line of last page.
	lpmax = NULL;
	n = 0;
	for(lnp = lforw(bufp->b_hdrlnp); lnp != bufp->b_hdrlnp; lnp = lforw(lnp)) {
		if(++n > disprows) {

			// Find beginning of last page.
			lpmax = bufp->b_hdrlnp;
			n = disprows;
			do {
				lpmax = lback(lpmax);
				} while(--n > 0);
			break;
			}
		}

	// Begin at the beginning.
	lnp1 = lforw(bufp->b_hdrlnp);
	halfpage = disprows / 2;
	n = 0;

	// Display a page (beginning at line lnp1 + n) and prompt for a naviagtion command.  Loop until exit key entered or
	// endprompt is false and buffer fits on one page (lpmax is NULL).
	for(;;) {
		lnp = lnp1;

		// Moving backward?
		if(n < 0) {
			do {
				// At beginning of buffer?
				if(lpmax == NULL || lnp1 == lforw(bufp->b_hdrlnp))
					break;

				// No, back up one line.
				lnp1 = lback(lnp1);
				} while(++n < 0);
			}

		// Moving forward?
		else if(n > 0) {
			do {
				// At end of buffer or max line?
				if(lpmax == NULL || lnp1 == bufp->b_hdrlnp || lnp1 == lpmax)
					break;

				// No, move forward one line.
				lnp1 = lforw(lnp1);
				} while(--n > 0);
			}

		// Illegal command?
		if(n != 0 && lnp1 == lnp)

			// Yes, ignore it.
			n = 0;
		else {
			// Found first row ... display page.
			lnp = lnp1;
			crow = 0;
			do {
				// At end of buffer?
				if(lnp == bufp->b_hdrlnp) {

					// Yes, erase remaining lines on physical screen.
					while(crow < disprows) {
						vtmove(crow,0);
						vteeol();
#if COLOR
						vscreen[crow]->v_rfcolor = gfcolor;
						vscreen[crow]->v_rbcolor = gbcolor;
#endif
						vscreen[crow]->v_left = FARRIGHT;
						vscreen[crow]->v_right = 0;
#if COLOR
						vscreen[crow++]->v_flags |= VFCHGD | VFCOLOR;
#else
						vscreen[crow++]->v_flags |= VFCHGD;
#endif
						}
					break;
					}

				// Update the virtual screen image for this line.  Characters past right edge of screen won't be
				// displayed, so ignore those.
				vtmove(crow,0);
				strpz = (strp = ltext(lnp)) + (lused(lnp) <= (int) term.t_ncol ? lused(lnp) : term.t_ncol);
				while(strp < strpz)
					vtputc(*strp++);
				vteeol();
#if COLOR
				vscreen[crow]->v_rfcolor = gfcolor;
				vscreen[crow]->v_rbcolor = gbcolor;
#endif
				vscreen[crow]->v_left = FARRIGHT;
				vscreen[crow]->v_right = 0;
#if COLOR
				vscreen[crow++]->v_flags |= VFCHGD | VFCOLOR;
#else
				vscreen[crow++]->v_flags |= VFCHGD;
#endif
				// On to the next line.
				lnp = lforw(lnp);
				} while(crow < disprows);

			// Screen is full.  Copy the virtual screen to the physical screen.
			if(pupd_all(false) != SUCCESS)
				return rc.status;

			// Bail out if called from terminp() and one-page buffer.
			if(firstpass && !endprompt && lpmax == NULL)
				goto uexit;
			firstpass = false;
			}

		// Display prompt.
		mlputs(MLHOME | MLFORCE,hprompt != NULL ? hprompt : lpmax == NULL || lnp1 == lpmax ? text201 : ": ");
													// "End: "
		if(TTflush() != SUCCESS)
			return rc.status;

		// Get response.
		for(;;) {
			// Get a keystroke and decode it.
			if(getkey(&ek) != SUCCESS)
				return rc.status;

			// Exit?
			if(ek == (CTRL | '[') || ek == 'q')
				goto uexit;

			// Forward whole page?
			if(ek == ' ' || ek == 'f' || iscmd(ek,forwPage)) {
				n = disprows - overlap;
				break;
				}

			// Forward half page?
			if(ek == 'd') {
				n = halfpage;
				break;
				}

			// Backward whole page?
			if(ek == 'b' || iscmd(ek,backPage)) {
				n = overlap - disprows;
				break;
				}

			// Backward half page?
			if(ek == 'u') {
				n = -halfpage;
				break;
				}

			// Forward a line?
			if(iscmd(ek,forwLine)) {
				n = 1;
				break;
				}

			// Backward a line?
			if(iscmd(ek,backLine)) {
				n = -1;
				break;
				}

			// First page?
			if(ek == 'g') {
				if(lpmax == NULL || lnp1 == lforw(bufp->b_hdrlnp))
					n = -1;			// Force beep.
				else {
					lnp1 = lforw(bufp->b_hdrlnp);
					n = 0;
					}
				break;
				}

			// Last page?
			if(ek == 'G') {
				if(lpmax == NULL || lnp1 == lpmax)
					n = 1;			// Force beep.
				else {
					lnp1 = lpmax;
					n = 0;
					}
				break;
				}

			// Help?
			if(ek == '?') {
				StrList msg;

				// Get string list...
				if(vopen(&msg,NULL,false) != 0)
					return vrcset();

				// build prompt...
				if(vputs(text202,&msg) != 0)
						// "(<SPC>,f"
					return vrcset();
				if(hkey(&msg,forwPage,0) != SUCCESS)
					return rc.status;
				if(vputs(text203,&msg) != 0)
						// ") +page (b"
					return vrcset();
				if(hkey(&msg,backPage,0) != SUCCESS)
					return rc.status;
				if(vputs(text204,&msg) != 0)
						// ") -page (d) +half (u) -half"
					return vrcset();
				if(hkey(&msg,forwLine,'+') != SUCCESS || hkey(&msg,backLine,'-') != SUCCESS)
					return rc.status;
				if(vputs(text206,&msg) != 0)
						// " (g) first (G) last (ESC,q) quit (?) help: "
					return vrcset();

				// and display it.
				if(vclose(&msg) != 0)
					return vrcset();
				mlputs(MLHOME | MLFORCE,msg.sl_vp->v_strp);
				}
			else {
				// Other key.  "Unget" the key for reprocessing and return.
				tungetc(ek);
				goto uexit;
				}
			}
		}
uexit:
	uphard();
	if(endprompt)
		mlerase(MLFORCE);

	return rc.status;
	}