示例#1
0
/* get a line from the terminal in non-canonical mode */
int
mygetline(char p[], char s[], unsigned size, int firstchar, BOOL iscaseless)
{
    int	c;
    unsigned int i = 0, j;
    char *sright;	/* substring to the right of the cursor */
    unsigned int ri = 0;		/* position in right-string */

    /* Inserts and deletes are always performed on the left-string,
     * but we'll also have a right-string 'sright' to hold characters
     * which are on the right of the cursor [insertion point].
     *
     * Think of 'sright' as a stack -- we push chars into it when the cursor
     * moves left, and we pop chars off it when the cursor moves right again.
     * At the end of the function, we'll pop off any remaining characters
     * onto the end of 's'
     */
    sright = calloc(sizeof(char), size );

    strcpy ( s, p);
    i += strlen(p);
    /* if a character already has been typed */
    if (firstchar != '\0') {
	if(iscaseless == YES) {
	    firstchar = tolower(firstchar);
	}
	addch(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) {
	if (c == KEY_LEFT || c == ctrl('B')) {	/* left */
	    if (i > 0) {
		addch('\b');
		/* move this char into the second (rhs) string */
		sright[ri++] = s[--i];
	    }
	} else if (c == KEY_RIGHT || c == ctrl('F')) {	/* right */
	    if (i < size && ri > 0) {
		/* move this char to the left of the cursor */
		s[i++] = sright[--ri];
		addch(s[i-1]);
	    }
	} else if (
#ifdef KEY_HOME
		   c == KEY_HOME ||
#endif
		   c == ctrl('A') ) {
	    while (i > 0) {
		sright[ri++] = s[--i];
		addch('\b');
		addch(s[i]);
		addch('\b');
	    }
	} else if (
#ifdef KEY_END
		   c == KEY_END ||
#endif
		   c == ctrl('E') ) {
	    while (ri > 0) {
		s[i++] = sright[--ri];
		addch(s[i-1]);
	    }
	} else if (c == erasechar() || c == KEY_BACKSPACE
		   || c == DEL || c == ctrl('H') ) {
	    /* erase */
	    if (i > 0) {
		if (ri == 0)  {
		    addstr("\b \b");
		} else {
		    addch('\b');
		    delch();
		}
		s[i] = '\0';
		--i;
	    }
	} else if (c == killchar() || c == KEY_BREAK) {
	    /* kill */
	    for (j = 0; j < i; ++j) {
		addch('\b');
	    }
	    for (j = 0; j < i; ++j) {
		addch(' ');
	    }
	    for (j = 0; j < i; ++j) {
		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) {
		s[i++] = c;	/* save it */
		if (ri == 0) {
		    addch(c);	/* display it */
		} else {
		    insch(c);	/* display it */
		    addch(c);	/* advance cursor */
		}
	    }
#if UNIXPC
	} else if (unixpcmouse == YES && c == ESC) {	/* mouse */
	    getmouseaction(ESC);	/* ignore it */
#endif
	} else if (mouse == YES && c == ctrl('X')) {
	    getmouseaction(ctrl('X'));	/* 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+ri) == 0) {
	    break;
	}
    }

    /* move any remaining chars on the rhs of the cursor
     * onto the end of our string
     */
    while (ri > 0) {
	s[i++] = sright[--ri];
    }
    free(sright);

    s[i] = '\0';
    return(i);
}
示例#2
0
/* execute the command */
BOOL
command(int commandc)
{
    char filename[PATHLEN + 1];	/* file path name */
    MOUSE *p;			/* mouse data */
    int	c, i;
    FILE *file;
    struct cmd *curritem, *item;	/* command history */
    char *s;

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

    case ctrl('R'):	/* rebuild the cross reference */
	if (isuptodate == YES) {
	    postmsg("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();
	clearmsg();		/* clear any previous message */
	totallines = 0;
	disprefs = 0;	
	topline = nextline = 1;
	selecting = 0;
	break;

#if UNIXPC
    case ESC:	/* possible unixpc mouse selection */
#endif
    case ctrl('X'):	/* mouse selection */
	if ((p = getmouseaction(DUMMYCHAR)) == 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 = p->y1 - FLDLINE;
	    /* force it into range */
	    if (field >= FIELDS) {
		field = FIELDS - 1;
	    }
	    setfield();
	    resetcmd();
	    return(NO);
	}
	break;

    case '\t':	/* go to next input field */
	if (disprefs) {
	    selecting = !selecting;
	    if (selecting) {
		move(displine[curdispline], 0);
		refresh();
	    } else {
		atfield();
		resetcmd();
	    }
	}
	return(NO);

#ifdef KEY_ENTER
    case KEY_ENTER:
#endif
    case '\r':
    case '\n':	/* go to reference */
	if (selecting) {
	    editref(curdispline);
	    return(YES);
	}
	/* FALLTHROUGH */

    case ctrl('N'):
#ifdef KEY_DOWN
    case KEY_DOWN:
#endif		
#ifdef KEY_RIGHT
    case KEY_RIGHT:
#endif
	if (selecting) {
	    if ((curdispline + 1) < disprefs) {
		move(displine[++curdispline], 0);
		refresh();
	    }
	} else {
	    field = (field + 1) % FIELDS;
	    setfield();
	    atfield();
	    resetcmd();
	}
	return(NO);

    case ctrl('P'):	/* go to previous input field */
#ifdef KEY_UP
    case KEY_UP:
#endif
#ifdef KEY_LEFT		
    case KEY_LEFT:
#endif
	if (selecting) {
	    if (curdispline) {
		move(displine[--curdispline], 0);
		refresh();
	    }
	} else {
	    field = (field + (FIELDS - 1)) % FIELDS;
	    setfield();
	    atfield();
	    resetcmd();
	}
	return(NO);
#ifdef KEY_HOME
    case KEY_HOME:	/* go to first input field */
	if (selecting) {
	    curdispline = 0;
	    move(REFLINE, 0);
	    refresh();
	} else {
	    field = 0;
	    setfield();
	    atfield();
	    resetcmd();
	}
	return(NO);
#endif

#ifdef KEY_LL
    case KEY_LL:	/* go to last input field */
	if (selecting) {
	    move(displine[disprefs - 1], 0);
	    refresh();
	} else {
	    field = FIELDS - 1;
	    setfield();
	    atfield();
	    resetcmd();
	}
	return(NO);
#endif /* def(KEY_LL) */

    case ' ':	/* display next page */
    case '+':
    case ctrl('V'):
#ifdef KEY_NPAGE
    case KEY_NPAGE:
#endif
	/* 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
	 */
	curdispline = 0;
	break;

    case ctrl('H'):
    case '-':	/* display previous page */
#ifdef KEY_PPAGE
    case KEY_PPAGE:
#endif
	/* don't redisplay if there are no lines */
	if (totallines == 0) {
	    return(NO);
	}

	curdispline = 0;

	/* if there are only two pages, just go to the other one */
	if (totallines <= 2 * mdisprefs) {
	    break;
	}
	/* if on first page but not at beginning, go to beginning */
	nextline -= mdisprefs;	/* already at next page */
	if (nextline > 1 && nextline <= mdisprefs) {
	    nextline = 1;
	} else {
	    nextline -= mdisprefs;
	    if (nextline < 1) {
		nextline = totallines - mdisprefs + 1;
		if (nextline < 1) {
		    nextline = 1;
		}
	    }
	}
	seekline(nextline);
	break;

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

    case '<':	/* read lines from a file */
	move(PRLINE, 0);
	addstr(readprompt);
	if (mygetline("", newpat, COLS - sizeof(readprompt),
		      '\0', NO) > 0) {
	    clearprompt();
	    shellpath(filename, sizeof(filename), newpat);
	    if (readrefs(filename) == NO) {
		postmsg2("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) {
	    postmsg("There are no lines to pipe to a shell command");
	    return(NO);
	}
	/* get the shell command */
	move(PRLINE, 0);
	addstr(pipeprompt);
	if (mygetline("", newpat, COLS - sizeof(pipeprompt), '\0', NO)
	    == 0) {
	    clearprompt();
	    return(NO);
	}
	/* if the ^ command, redirect output to a temp file */
	if (commandc == '^') {
	    strcat(strcat(newpat, " >"), temp2);
	    /* HBB 20020708: somebody might have even
	     * their non-interactive default shells
	     * complain about clobbering
	     * redirections... --> delete before
	     * overwriting */
	    remove(temp2);
	}
	exitcurses();
	if ((file = mypopen(newpat, "w")) == NULL) {
	    fprintf(stderr, "\
cscope: cannot open pipe to shell command: %s\n", newpat);
	} else {