Edit

IABSD.fr/src/usr.bin/mg/grep.c

Branch :

  • Show log

    Commit

  • Author : guenther
    Date : 2023-03-08 04:43:04
    Hash : 5b133f3f
    Message : Delete obsolete /* ARGSUSED */ lint comments. ok miod@ millert@

  • usr.bin/mg/grep.c
  • /*	$OpenBSD: grep.c,v 1.50 2023/03/08 04:43:11 guenther Exp $	*/
    
    /* This file is in the public domain */
    
    #include <sys/queue.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    
    #include <ctype.h>
    #include <limits.h>
    #include <signal.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    #include <unistd.h>
    
    #include "def.h"
    #include "kbd.h"
    #include "funmap.h"
    
    int	 globalwd = FALSE;
    static int	 compile_goto_error(int, int);
    int		 next_error(int, int);
    static int	 grep(int, int);
    static int	 gid(int, int);
    static struct buffer	*compile_mode(const char *, const char *);
    void grep_init(void);
    
    static char compile_last_command[NFILEN] = "make ";
    
    /*
     * Hints for next-error
     *
     * XXX - need some kind of callback to find out when those get killed.
     */
    struct mgwin	*compile_win;
    struct buffer	*compile_buffer;
    
    static PF compile_pf[] = {
    	compile_goto_error
    };
    
    static struct KEYMAPE (1) compilemap = {
    	1,
    	1,
    	rescan,
    	{
    		{ CCHR('M'), CCHR('M'), compile_pf, NULL }
    	}
    };
    
    void
    grep_init(void)
    {
    	funmap_add(compile_goto_error, "compile-goto-error", 0);
    	funmap_add(next_error, "next-error", 0);
    	funmap_add(grep, "grep", 1);
    	funmap_add(compile, "compile", 0);
    	funmap_add(gid, "gid", 1);
    	maps_add((KEYMAP *)&compilemap, "compile");
    }
    
    static int
    grep(int f, int n)
    {
    	char	 cprompt[NFILEN], *bufp;
    	struct buffer	*bp;
    	struct mgwin	*wp;
    
    	(void)strlcpy(cprompt, "grep -n ", sizeof(cprompt));
    	if ((bufp = eread("Run grep: ", cprompt, NFILEN,
    	    EFDEF | EFNEW | EFCR)) == NULL)
    		return (ABORT);
    	else if (bufp[0] == '\0')
    		return (FALSE);
    	if (strlcat(cprompt, " /dev/null", sizeof(cprompt)) >= sizeof(cprompt))
    		return (FALSE);
    
    	if ((bp = compile_mode("*grep*", cprompt)) == NULL)
    		return (FALSE);
    	if ((wp = popbuf(bp, WNONE)) == NULL)
    		return (FALSE);
    	curbp = bp;
    	compile_win = curwp = wp;
    	return (TRUE);
    }
    
    int
    compile(int f, int n)
    {
    	char	 cprompt[NFILEN], *bufp;
    	struct buffer	*bp;
    	struct mgwin	*wp;
    
    	(void)strlcpy(cprompt, compile_last_command, sizeof(cprompt));
    	if ((bufp = eread("Compile command: ", cprompt, NFILEN,
    	    EFDEF | EFNEW | EFCR)) == NULL)
    		return (ABORT);
    	else if (bufp[0] == '\0')
    		return (FALSE);
    	if (savebuffers(f, n) == ABORT)
    		return (ABORT);
    	(void)strlcpy(compile_last_command, bufp, sizeof(compile_last_command));
    
    	if ((bp = compile_mode("*compile*", cprompt)) == NULL)
    		return (FALSE);
    	if ((wp = popbuf(bp, WNONE)) == NULL)
    		return (FALSE);
    	curbp = bp;
    	compile_win = curwp = wp;
    	gotoline(FFARG, 0);
    	return (TRUE);
    }
    
    /* id-utils foo. */
    static int
    gid(int f, int n)
    {
    	char	 command[NFILEN];
    	char	 cprompt[NFILEN], *bufp;
    	int	c;
    	struct buffer	*bp;
    	struct mgwin	*wp;
    	int	 i, j, len;
    
    	/* catch ([^\s(){}]+)[\s(){}]* */
    
    	i = curwp->w_doto;
    	/* Skip backwards over delimiters we are currently on */
    	while (i > 0) {
    		c = lgetc(curwp->w_dotp, i);
    		if (isalnum(c) || c == '_')
    			break;
    
    		i--;
    	}
    
    	/* Skip the symbol itself */
    	for (; i > 0; i--) {
    		c = lgetc(curwp->w_dotp, i - 1);
    		if (!isalnum(c) && c != '_')
    			break;
    	}
    	/* Fill the symbol in cprompt[] */
    	for (j = 0; j < sizeof(cprompt) - 1 && i < llength(curwp->w_dotp);
    	    j++, i++) {
    		c = lgetc(curwp->w_dotp, i);
    		if (!isalnum(c) && c != '_')
    			break;
    		cprompt[j] = c;
    	}
    	cprompt[j] = '\0';
    
    	if ((bufp = eread("Run gid (with args): ", cprompt, NFILEN,
    	    (j ? EFDEF : 0) | EFNEW | EFCR)) == NULL)
    		return (ABORT);
    	else if (bufp[0] == '\0')
    		return (FALSE);
    	len = snprintf(command, sizeof(command), "gid %s", cprompt);
    	if (len < 0 || len >= sizeof(command))
    		return (FALSE);
    
    	if ((bp = compile_mode("*gid*", command)) == NULL)
    		return (FALSE);
    	if ((wp = popbuf(bp, WNONE)) == NULL)
    		return (FALSE);
    	curbp = bp;
    	compile_win = curwp = wp;
    	return (TRUE);
    }
    
    struct buffer *
    compile_mode(const char *name, const char *command)
    {
    	struct buffer	*bp;
    	FILE	*fpipe;
    	char	*buf;
    	size_t	 sz;
    	ssize_t	 len;
    	int	 ret, n, status;
    	char	 cwd[NFILEN], qcmd[NFILEN];
    	char	 timestr[NTIME];
    	time_t	 t;
    
    	buf = NULL;
    	sz = 0;
    
    	n = snprintf(qcmd, sizeof(qcmd), "%s 2>&1", command);
    	if (n < 0 || n >= sizeof(qcmd))
    		return (NULL);
    
    	bp = bfind(name, TRUE);
    	if (bclear(bp) != TRUE)
    		return (NULL);
    
    	if (getbufcwd(bp->b_cwd, sizeof(bp->b_cwd)) != TRUE)
    		return (NULL);
    	addlinef(bp, "cd %s", bp->b_cwd);
    	addline(bp, qcmd);
    	addline(bp, "");
    
    	if (getcwd(cwd, sizeof(cwd)) == NULL)
    		panic("Can't get current directory!");
    	if (chdir(bp->b_cwd) == -1) {
    		dobeep();
    		ewprintf("Can't change dir to %s", bp->b_cwd);
    		return (NULL);
    	}
    	if ((fpipe = popen(qcmd, "r")) == NULL) {
    		dobeep();
    		ewprintf("Problem opening pipe");
    		return (NULL);
    	}
    	while ((len = getline(&buf, &sz, fpipe)) != -1) {
    		if (buf[len - 1] == *bp->b_nlchr)
    			buf[len - 1] = '\0';
    		addline(bp, buf);
    	}
    	free(buf);
    	if (ferror(fpipe))
    		ewprintf("Problem reading pipe");
    	ret = pclose(fpipe);
    	t = time(NULL);
    	strftime(timestr, sizeof(timestr), "%a %b %e %T %Y", localtime(&t));
    	addline(bp, "");
    	if (WIFEXITED(ret)) {
    		status = WEXITSTATUS(ret);
    		if (status == 0)
    			addlinef(bp, "Command finished at %s", timestr);
    		else
    			addlinef(bp, "Command exited abnormally with code %d "
    			    "at %s", status, timestr);
    	} else
    		addlinef(bp, "Subshell killed by signal %d at %s",
    		    WTERMSIG(ret), timestr);
    
    	bp->b_dotp = bfirstlp(bp);
    	bp->b_modes[0] = name_mode("fundamental");
    	bp->b_modes[1] = name_mode("compile");
    	bp->b_nmodes = 1;
    
    	compile_buffer = bp;
    
    	if (chdir(cwd) == -1) {
    		dobeep();
    		ewprintf("Can't change dir back to %s", cwd);
    		return (NULL);
    	}
    	return (bp);
    }
    
    static int
    compile_goto_error(int f, int n)
    {
    	struct buffer	*bp;
    	struct mgwin	*wp;
    	char	*fname, *line, *lp, *ln;
    	int	 lineno;
    	char	*adjf, path[NFILEN];
    	const char *errstr;
    	struct line	*last;
    
    	compile_win = curwp;
    	compile_buffer = curbp;
    	last = blastlp(compile_buffer);
    
     retry:
    	/* last line is compilation result */
    	if (curwp->w_dotp == last)
    		return (FALSE);
    
    	if ((line = linetostr(curwp->w_dotp)) == NULL)
    		return (FALSE);
    	lp = line;
    	if ((fname = strsep(&lp, ":")) == NULL || *fname == '\0')
    		goto fail;
    	if ((ln = strsep(&lp, ":")) == NULL || *ln == '\0')
    		goto fail;
    	lineno = (int)strtonum(ln, INT_MIN, INT_MAX, &errstr);
    	if (errstr)
    		goto fail;
    
    	if (fname && fname[0] != '/') {
    		if (getbufcwd(path, sizeof(path)) == FALSE)
    			goto fail;
    		if (strlcat(path, fname, sizeof(path)) >= sizeof(path))
    			goto fail;
    		adjf = path;
    	} else {
    		adjf = adjustname(fname, TRUE);
    	}
    	free(line);
    
    	if (adjf == NULL)
    		return (FALSE);
    
    	if ((bp = findbuffer(adjf)) == NULL)
    		return (FALSE);
    	if ((wp = popbuf(bp, WNONE)) == NULL)
    		return (FALSE);
    	curbp = bp;
    	curwp = wp;
    	if (bp->b_fname[0] == '\0')
    		readin(adjf);
    	gotoline(FFARG, lineno);
    	return (TRUE);
    fail:
    	free(line);
    	if (curwp->w_dotp != blastlp(curbp)) {
    		curwp->w_dotp = lforw(curwp->w_dotp);
    		curwp->w_rflag |= WFMOVE;
    		goto retry;
    	}
    	dobeep();
    	ewprintf("No more hits");
    	return (FALSE);
    }
    
    int
    next_error(int f, int n)
    {
    	if (compile_win == NULL || compile_buffer == NULL) {
    		dobeep();
    		ewprintf("No compilation active");
    		return (FALSE);
    	}
    	curwp = compile_win;
    	curbp = compile_buffer;
    	if (curwp->w_dotp == blastlp(curbp)) {
    		dobeep();
    		ewprintf("No more hits");
    		return (FALSE);
    	}
    	curwp->w_dotp = lforw(curwp->w_dotp);
    	curwp->w_rflag |= WFMOVE;
    
    	return (compile_goto_error(f, n));
    }
    
    /*
     * Since we don't have variables (we probably should) these are command
     * processors for changing the values of mode flags.
     */
    int
    globalwdtoggle(int f, int n)
    {
    	if (f & FFARG)
    		globalwd = n > 0;
    	else
    		globalwd = !globalwd;
    
    	sgarbf = TRUE;
    
    	return (TRUE);
    }