Example #1
0
/* Update the display and wait for an input event.
 */
int curses_runio(int *control)
{
    int ch, i;

    for (;;) {
	render();
	ch = tolower(getch());
	switch (ch) {
	  case '\r':
	  case '\n':
	  case KEY_ENTER:
	    *control = ctl_button;
	    return 1;
	  case KEY_MOUSE:
	    if (getmouseevent(control))
		return 1;
	    break;
	  case '?':
	  case KEY_F(1):
	    if (!runhelp())
		return 0;
	    break;
	  case '\022':
	    if (!runruleshelp())
		return 0;
	    break;
	  case '\026':
	    if (!runlicensedisplay())
		return 0;
	    break;
	  case '\001':
	    changediechars(+1);
	    break;
	  case '\f':
	    clearok(stdscr, TRUE);
	    break;
	  case KEY_RESIZE:
	    initlayout();
	    break;
	  case '\003':
	  case '\030':
	    return 0;
	  case 'q':
	  case '\033':
	    if (controls[ctl_button].value == bval_newgame)
		return 0;
	    break;
	  case ERR:
	    exit(1);
	  default:
	    for (i = 0 ; i < ctl_count ; ++i) {
		if (controls[i].key == ch) {
		    *control = i;
		    return 1;
		}
	    }
	}
    }
}
Example #2
0
int
getline(char s[], size_t size, int firstchar, BOOL iscaseless)
{
	int	c, i = 0;
	int	j;

	/* if a character already has been typed */
	if (firstchar != '\0') {
		if (iscaseless == YES) {
			firstchar = tolower(firstchar);
		}
		(void) addch((unsigned)firstchar);	/* display it */
		s[i++] = firstchar;	/* save it */
	}
	/* until the end of the line is reached */
	while ((c = mygetch()) != '\r' && c != '\n' && c != KEY_ENTER &&
	    c != '\003' && c != KEY_BREAK) {
		if (c == erasechar() || c == '\b' ||		/* erase */
		    c == KEY_BACKSPACE) {
			if (i > 0) {
				(void) addstr("\b \b");
				--i;
			}
		} else if (c == killchar()) {			/* kill */
			for (j = 0; j < i; ++j) {
				(void) addch('\b');
			}
			for (j = 0; j < i; ++j) {
				(void) addch(' ');
			}
			for (j = 0; j < i; ++j) {
				(void) addch('\b');
			}
			i = 0;
		} else if (isprint(c) || c == '\t') {		/* printable */
			if (iscaseless == YES) {
				c = tolower(c);
			}
			/* if it will fit on the line */
			if (i < size) {
				(void) addch((unsigned)c);	/* display it */
				s[i++] = c;		/* save it */
			}
		} else if (c == ctrl('X')) {
			/* mouse */
			(void) getmouseevent(); 	/* ignore it */
		} else if (c == EOF) {			/* end-of-file */
			break;
		}
		/* return on an empty line to allow a command to be entered */
		if (firstchar != '\0' && i == 0) {
			break;
		}
	}
	s[i] = '\0';
	return (i);
}
Example #3
0
BOOL
command(int commandc)
{
	char	filename[PATHLEN + 1];	/* file path name */
	MOUSEEVENT *p;			/* mouse data */
	int	c, i;
	FILE	*file;
	HISTORY *curritem, *item;	/* command history */
	char	*s;

	switch (commandc) {

	case ctrl('C'):	/* toggle caseless mode */
		if (caseless == NO) {
			caseless = YES;
			putmsg2("Caseless mode is now ON");
		} else {
			caseless = NO;
			putmsg2("Caseless mode is now OFF");
		}
		egrepcaseless(caseless);	/* turn on/off -i flag */
		return (NO);

	case ctrl('R'):	/* rebuild the cross reference */
		if (isuptodate == YES) {
			putmsg("The -d option prevents rebuilding the "
			    "symbol database");
			return (NO);
		}
		exitcurses();
		freefilelist();		/* remake the source file list */
		makefilelist();
		rebuild();
		if (errorsfound == YES) {
			errorsfound = NO;
			askforreturn();
		}
		entercurses();
		putmsg("");		/* clear any previous message */
		totallines = 0;
		topline = nextline = 1;
		break;

	case ctrl('X'):	/* mouse selection */
		if ((p = getmouseevent()) == NULL) {
			return (NO);	/* unknown control sequence */
		}
		/* if the button number is a scrollbar tag */
		if (p->button == '0') {
			scrollbar(p);
			break;
		}
		/* ignore a sweep */
		if (p->x2 >= 0) {
			return (NO);
		}
		/* if this is a line selection */
		if (p->y1 < FLDLINE) {

			/* find the selected line */
			/* note: the selection is forced into range */
			for (i = disprefs - 1; i > 0; --i) {
				if (p->y1 >= displine[i]) {
					break;
				}
			}
			/* display it in the file with the editor */
			editref(i);
		} else {	/* this is an input field selection */
			field = mouseselection(p, FLDLINE, FIELDS);
			setfield();
			resetcmd();
			return (NO);
		}
		break;

	case '\t':	/* go to next input field */
	case '\n':
	case '\r':
	case ctrl('N'):
	case KEY_DOWN:
	case KEY_ENTER:
	case KEY_RIGHT:
		field = (field + 1) % FIELDS;
		setfield();
		resetcmd();
		return (NO);

	case ctrl('P'):	/* go to previous input field */
	case KEY_UP:
	case KEY_LEFT:
		field = (field + (FIELDS - 1)) % FIELDS;
		setfield();
		resetcmd();
		return (NO);
	case KEY_HOME:	/* go to first input field */
		field = 0;
		setfield();
		resetcmd();
		return (NO);

	case KEY_LL:	/* go to last input field */
		field = FIELDS - 1;
		setfield();
		resetcmd();
		return (NO);
	case ' ':	/* display next page */
	case '+':
	case ctrl('V'):
	case KEY_NPAGE:
		/* don't redisplay if there are no lines */
		if (totallines == 0) {
			return (NO);
		}
		/*
		 * note: seekline() is not used to move to the next
		 * page because display() leaves the file pointer at
		 * the next page to optimize paging forward
		 */
		break;

	case '-':	/* display previous page */
	case KEY_PPAGE:
		/* don't redisplay if there are no lines */
		if (totallines == 0) {
			return (NO);
		}
		i = topline;		/* save the current top line */
		nextline = topline;	/* go back to this page */

		/* if on first page but not at beginning, go to beginning */
		if (nextline > 1 && nextline <= mdisprefs) {
			nextline = 1;
		} else {	/* go back the maximum displayable lines */
			nextline -= mdisprefs;

			/* if this was the first page, go to the last page */
			if (nextline < 1) {
				nextline = totallines - mdisprefs + 1;
				if (nextline < 1) {
					nextline = 1;
				}
				/* old top is past last line */
				i = totallines + 1;
			}
		}
		/*
		 * move down til the bottom line is just before the
		 * previous top line
		 */
		c = nextline;
		for (;;) {
			seekline(nextline);
			display();
			if (i - bottomline <= 0) {
				break;
			}
			nextline = ++c;
		}
		return (NO);	/* display already up to date */

	case '>':	/* write or append the lines to a file */
		if (totallines == 0) {
			putmsg("There are no lines to write to a file");
		} else {	/* get the file name */
			(void) move(PRLINE, 0);
			(void) addstr("Write to file: ");
			s = "w";
			if ((c = mygetch()) == '>') {
				(void) move(PRLINE, 0);
				(void) addstr(appendprompt);
				c = '\0';
				s = "a";
			}
			if (c != '\r' && c != '\n' && c != KEY_ENTER &&
			    c != KEY_BREAK &&
			    getaline(newpat, COLS - sizeof (appendprompt), c,
			    NO) > 0) {
				shellpath(filename, sizeof (filename), newpat);
				if ((file = fopen(filename, s)) == NULL) {
					cannotopen(filename);
				} else {
					seekline(1);
					while ((c = getc(refsfound)) != EOF) {
						(void) putc(c, file);
					}
					seekline(topline);
					(void) fclose(file);
				}
			}
			clearprompt();
		}
		return (NO);	/* return to the previous field */

	case '<':	/* read lines from a file */
		(void) move(PRLINE, 0);
		(void) addstr(readprompt);
		if (getaline(newpat, COLS - sizeof (readprompt), '\0',
		    NO) > 0) {
			clearprompt();
			shellpath(filename, sizeof (filename), newpat);
			if (readrefs(filename) == NO) {
				putmsg2("Ignoring an empty file");
				return (NO);
			}
			return (YES);
		}
		clearprompt();
		return (NO);

	case '^':	/* pipe the lines through a shell command */
	case '|':	/* pipe the lines to a shell command */
		if (totallines == 0) {
			putmsg("There are no lines to pipe to a shell command");
			return (NO);
		}
		/* get the shell command */
		(void) move(PRLINE, 0);
		(void) addstr(pipeprompt);
		if (getaline(newpat,
		    COLS - sizeof (pipeprompt), '\0', NO) == 0) {
			clearprompt();
			return (NO);
		}
		/* if the ^ command, redirect output to a temp file */
		if (commandc == '^') {
			(void) strcat(strcat(newpat, " >"), temp2);
		}
		exitcurses();
		if ((file = mypopen(newpat, "w")) == NULL) {
			(void) fprintf(stderr,
			    "cscope: cannot open pipe to shell command: %s\n",
			    newpat);
		} else {
			seekline(1);
			while ((c = getc(refsfound)) != EOF) {
				(void) putc(c, file);
			}
			seekline(topline);
			(void) mypclose(file);
		}
		if (commandc == '^') {
			if (readrefs(temp2) == NO) {
				putmsg("Ignoring empty output of ^ command");
			}
		}
		askforreturn();
		entercurses();
		break;

	case ctrl('L'):	/* redraw screen */
	case KEY_CLEAR:
		(void) clearok(curscr, TRUE);
		(void) wrefresh(curscr);
		drawscrollbar(topline, bottomline, totallines);
		return (NO);

	case '!':	/* shell escape */
		(void) execute(shell, shell, (char *)NULL);
		seekline(topline);
		break;

	case '?':	/* help */
		(void) clear();
		help();
		(void) clear();
		seekline(topline);
		break;

	case ctrl('E'):	/* edit all lines */
		editall();
		break;

	case ctrl('A'):	/* repeat last pattern */
	case ctrl('Y'):	/* (old command) */
		if (*pattern != '\0') {
			(void) addstr(pattern);
			goto repeat;
		}
		break;

	case ctrl('B'):		/* cmd history back */
	case ctrl('F'):		/* cmd history fwd */
		curritem = currentcmd();
		item = (commandc == ctrl('F')) ? nextcmd() : prevcmd();
		clearmsg2();
		if (curritem == item) {
			/* inform user that we're at history end */
			putmsg2(
			    "End of input field and search pattern history");
		}
		if (item) {
			field = item->field;
			setfield();
			atfield();
			(void) addstr(item->text);
			(void) strcpy(pattern, item->text);
			switch (c = mygetch()) {
			case '\r':
			case '\n':
			case KEY_ENTER:
				goto repeat;
			default:
				ungetch(c);
				atfield();
				(void) clrtoeol(); /* clear current field */
				break;
			}
		}
		return (NO);

	case '\\':	/* next character is not a command */
		(void) addch('\\');	/* display the quote character */

		/* get a character from the terminal */
		if ((commandc = mygetch()) == EOF) {
			return (NO);	/* quit */
		}
		(void) addstr("\b \b");	/* erase the quote character */
		goto ispat;

	case '.':
		atfield();	/* move back to the input field */
		/* FALLTHROUGH */
	default:
		/* edit a selected line */
		if (isdigit(commandc) && commandc != '0' && !mouse) {
			if (returnrequired == NO) {
				editref(commandc - '1');
			} else {
				(void) move(PRLINE, 0);
				(void) addstr(selectionprompt);
				if (getaline(newpat,
				    COLS - sizeof (selectionprompt), commandc,
				    NO) > 0 &&
				    (i = atoi(newpat)) > 0) {
					editref(i - 1);
				}
				clearprompt();
			}
		} else if (isprint(commandc)) {
			/* this is the start of a pattern */
ispat:
			if (getaline(newpat, COLS - fldcolumn - 1, commandc,
			    caseless) > 0) {
					(void) strcpy(pattern, newpat);
					resetcmd();	/* reset history */
repeat:
				addcmd(field, pattern);	/* add to history */
				if (field == CHANGE) {
					/* prompt for the new text */
					(void) move(PRLINE, 0);
					(void) addstr(toprompt);
					(void) getaline(newpat,
					    COLS - sizeof (toprompt), '\0', NO);
				}
				/* search for the pattern */
				if (search() == YES) {
					switch (field) {
					case DEFINITION:
					case FILENAME:
						if (totallines > 1) {
							break;
						}
						topline = 1;
						editref(0);
						break;
					case CHANGE:
						return (changestring());
					}
				} else if (field == FILENAME &&
				    access(newpat, READ) == 0) {
					/* try to edit the file anyway */
					edit(newpat, "1");
				}
			} else {	/* no pattern--the input was erased */
				return (NO);
			}
		} else {	/* control character */
			return (NO);
		}
	}
	return (YES);
}
Example #4
0
BOOL
changestring(void)
{
	char	buf[PATLEN + 1];	/* input buffer */
	char	newfile[PATHLEN + 1];	/* new file name */
	char	oldfile[PATHLEN + 1];	/* old file name */
	char	linenum[NUMLEN + 1];	/* file line number */
	char	msg[MSGLEN + 1];	/* message */
	FILE	*script;		/* shell script file */
	BOOL	anymarked = NO;		/* any line marked */
	MOUSEEVENT *p;			/* mouse data */
	int	c, i;
	char	*s;

	/* open the temporary file */
	if ((script = fopen(temp2, "w")) == NULL) {
		cannotopen(temp2);
		return (NO);
	}
	/* create the line change indicators */
	change = (BOOL *)mycalloc((unsigned)totallines, sizeof (BOOL));
	changing = YES;
	initmenu();

	/* until the quit command is entered */
	for (;;) {
		/* display the current page of lines */
		display();
	same:
		/* get a character from the terminal */
		(void) move(PRLINE, 0);
		(void) addstr(
		    "Select lines to change (press the ? key for help): ");
		if ((c = mygetch()) == EOF || c == ctrl('D') ||
		    c == ctrl('Z')) {
			break;	/* change lines */
		}
		/* see if the input character is a command */
		switch (c) {
		case ' ':	/* display next page */
		case '+':
		case ctrl('V'):
		case KEY_NPAGE:
		case '-':	/* display previous page */
		case KEY_PPAGE:
		case '!':	/* shell escape */
		case '?':	/* help */
			(void) command(c);
			break;

		case ctrl('L'):	/* redraw screen */
		case KEY_CLEAR:
			(void) command(c);
			goto same;

		case ESC:	/* kept for backwards compatibility */
			/* FALLTHROUGH */

		case '\r':	/* don't change lines */
		case '\n':
		case KEY_ENTER:
		case KEY_BREAK:
		case ctrl('G'):
			clearprompt();
			goto nochange;

		case '*':	/* mark/unmark all displayed lines */
			for (i = 0; topline + i < nextline; ++i) {
				mark(i);
			}
			goto same;

		case 'a':	/* mark/unmark all lines */
			for (i = 0; i < totallines; ++i) {
				if (change[i] == NO) {
					change[i] = YES;
				} else {
					change[i] = NO;
				}
			}
			/* show that all have been marked */
			seekline(totallines);
			break;
		case ctrl('X'):	/* mouse selection */
			if ((p = getmouseevent()) == NULL) {
				goto same;	/* unknown control sequence */
			}
			/* if the button number is a scrollbar tag */
			if (p->button == '0') {
				scrollbar(p);
				break;
			}
			/* find the selected line */
			/* note: the selection is forced into range */
			for (i = disprefs - 1; i > 0; --i) {
				if (p->y1 >= displine[i]) {
					break;
				}
			}
			mark(i);
			goto same;
		default:
			/* if a line was selected */
			if (isdigit(c) && c != '0' && !mouse) {
				if (returnrequired == NO) {
					mark(c - '1');
				} else {
					clearprompt();
					(void) move(PRLINE, 0);
					(void) addstr(selectionprompt);
					if (getaline(buf,
					    COLS - sizeof (selectionprompt), c,
					    NO) > 0 &&
					    (i = atoi(buf)) > 0) {
						mark(i - 1);
					}
				}
			}
			goto same;
		}
	}
	/* for each line containing the old text */
	(void) fprintf(script, "ed - <<\\!\nH\n");
	*oldfile = '\0';
	seekline(1);
	for (i = 0; fscanf(refsfound, "%s%*s%s%*[^\n]", newfile, linenum) == 2;
	    ++i) {
		/* see if the line is to be changed */
		if (change[i] == YES) {
			anymarked = YES;

			/* if this is a new file */
			if (strcmp(newfile, oldfile) != 0) {

				/* make sure it can be changed */
				if (access(newfile, WRITE) != 0) {
					(void) sprintf(msg,
					    "Cannot write to file %s",
					    newfile);
					putmsg(msg);
					anymarked = NO;
					break;
				}
				/* if there was an old file */
				if (*oldfile != '\0') {
					(void) fprintf(script,
					    "w\n");	/* save it */
				}
				/* edit the new file */
				(void) strcpy(oldfile, newfile);
				(void) fprintf(script, "e %s\n", oldfile);
			}
			/* output substitute command */
			(void) fprintf(script,
			    "%ss/", linenum);	/* change */
			for (s = pattern; *s != '\0'; ++s) {	/* old text */
				if (*s == '/') {
					(void) putc('\\', script);
				}
				(void) putc(*s, script);
			}
			(void) putc('/', script);			/* to */
			for (s = newpat; *s != '\0'; ++s) {	/* new text */
				if (strchr("/\\&", *s) != NULL) {
					(void) putc('\\', script);
				}
				(void) putc(*s, script);
			}
			(void) fprintf(script, "/gp\n");	/* and print */
		}
	}
	(void) fprintf(script, "w\nq\n!\n");	/* write and quit */
	(void) fclose(script);
	clearprompt();

	/* if any line was marked */
	if (anymarked == YES) {
		/* edit the files */
		(void) refresh();
		(void) fprintf(stderr, "Changed lines:\n\r");
		(void) execute(shell, shell, temp2, (char *)NULL);
		askforreturn();
	}
nochange:
	changing = NO;
	initmenu();
	free(change);
	seekline(topline);
	return (YES);	/* clear any marks on exit without change */
}