2023-07-27 14:04:50 -04:00
|
|
|
/*===========================================================================
|
2023-08-04 14:34:51 -04:00
|
|
|
Copyright (c) 1998-2000, The Santa Cruz Operation
|
2023-07-27 14:04:50 -04:00
|
|
|
All rights reserved.
|
2023-08-04 14:34:51 -04:00
|
|
|
|
2023-07-27 14:04:50 -04:00
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
modification, are permitted provided that the following conditions are met:
|
|
|
|
|
|
|
|
*Redistributions of source code must retain the above copyright notice,
|
|
|
|
this list of conditions and the following disclaimer.
|
|
|
|
|
|
|
|
*Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
this list of conditions and the following disclaimer in the documentation
|
|
|
|
and/or other materials provided with the distribution.
|
|
|
|
|
|
|
|
*Neither name of The Santa Cruz Operation nor the names of its contributors
|
|
|
|
may be used to endorse or promote products derived from this software
|
2023-08-04 14:34:51 -04:00
|
|
|
without specific prior written permission.
|
2023-07-27 14:04:50 -04:00
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
|
2023-08-04 15:09:58 -04:00
|
|
|
IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT falseT LIMITED TO,
|
2023-07-27 14:04:50 -04:00
|
|
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
2023-08-04 15:19:25 -04:00
|
|
|
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
2023-07-27 14:04:50 -04:00
|
|
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
2023-08-04 15:09:58 -04:00
|
|
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT falseT LIMITED TO, PROCUREMENT OF
|
2023-07-27 14:04:50 -04:00
|
|
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
INTERRUPTION)
|
|
|
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
2023-08-04 14:34:51 -04:00
|
|
|
DAMAGE.
|
2023-07-27 14:04:50 -04:00
|
|
|
=========================================================================*/
|
|
|
|
|
2023-08-04 13:49:03 -04:00
|
|
|
/* cscope - interactive C symbol cross-reference
|
2023-07-27 14:04:50 -04:00
|
|
|
*
|
2023-08-04 13:49:03 -04:00
|
|
|
* terminal input functions
|
2023-07-27 14:04:50 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "global.h"
|
|
|
|
#include <ncurses.h>
|
2023-08-04 13:49:03 -04:00
|
|
|
#include <setjmp.h> /* jmp_buf */
|
2023-07-27 14:04:50 -04:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#if HAVE_SYS_TERMIOS_H
|
2023-08-08 14:34:15 -04:00
|
|
|
# include <sys/termios.h>
|
2023-07-27 14:04:50 -04:00
|
|
|
#endif
|
|
|
|
|
2023-08-08 14:34:15 -04:00
|
|
|
#include "keys.h"
|
|
|
|
|
2023-08-05 05:30:18 -04:00
|
|
|
bool do_press_any_key = false;
|
|
|
|
|
2023-08-04 14:05:31 -04:00
|
|
|
static jmp_buf env; /* setjmp/longjmp buffer */
|
|
|
|
static int prevchar; /* previous, ungotten character */
|
2023-07-27 14:04:50 -04:00
|
|
|
|
|
|
|
/* Internal prototypes: */
|
|
|
|
static void catchint(int sig);
|
|
|
|
|
|
|
|
/* catch the interrupt signal */
|
|
|
|
|
|
|
|
static void
|
2023-08-10 08:36:16 -04:00
|
|
|
catchint(int sig){
|
2023-08-09 07:49:11 -04:00
|
|
|
UNUSED(sig);
|
|
|
|
|
2023-08-04 13:49:03 -04:00
|
|
|
signal(SIGINT, catchint);
|
|
|
|
longjmp(env, 1);
|
2023-07-27 14:04:50 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* unget a character */
|
|
|
|
void
|
|
|
|
myungetch(int c)
|
|
|
|
{
|
2023-08-04 13:49:03 -04:00
|
|
|
prevchar = c;
|
2023-07-27 14:04:50 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* get a line from the terminal in non-canonical mode */
|
|
|
|
int
|
2023-08-10 08:36:16 -04:00
|
|
|
mygetline(char p[], char s[], unsigned size, int firstchar, bool iscaseless){
|
2023-08-04 13:49:03 -04:00
|
|
|
int c;
|
2023-07-27 14:04:50 -04:00
|
|
|
unsigned int i = 0, j;
|
2023-08-04 13:49:03 -04:00
|
|
|
char *sright; /* substring to the right of the cursor */
|
|
|
|
unsigned int ri = 0; /* position in right-string */
|
2023-07-27 14:04:50 -04:00
|
|
|
|
|
|
|
/* 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(size, sizeof(*sright));
|
|
|
|
|
|
|
|
strcpy ( s, p);
|
|
|
|
i += strlen(p);
|
|
|
|
/* if a character already has been typed */
|
|
|
|
if (firstchar != '\0') {
|
2023-08-04 15:09:58 -04:00
|
|
|
if(iscaseless == true) {
|
2023-08-04 13:49:03 -04:00
|
|
|
firstchar = tolower(firstchar);
|
|
|
|
}
|
|
|
|
addch(firstchar); /* display it */
|
|
|
|
s[i++] = firstchar; /* save it */
|
2023-07-27 14:04:50 -04:00
|
|
|
}
|
|
|
|
/* until the end of the line is reached */
|
2023-08-05 05:30:18 -04:00
|
|
|
while ((c = getch()) != '\r' && c != '\n' && c != KEY_ENTER) {
|
2023-08-04 13:49:03 -04:00
|
|
|
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 (
|
2023-07-27 14:04:50 -04:00
|
|
|
#ifdef KEY_HOME
|
2023-08-04 13:49:03 -04:00
|
|
|
c == KEY_HOME ||
|
2023-07-27 14:04:50 -04:00
|
|
|
#endif
|
2023-08-04 13:49:03 -04:00
|
|
|
c == ctrl('A') ) {
|
|
|
|
while (i > 0) {
|
|
|
|
sright[ri++] = s[--i];
|
|
|
|
addch('\b');
|
|
|
|
addch(s[i]);
|
|
|
|
addch('\b');
|
|
|
|
}
|
|
|
|
} else if (
|
2023-07-27 14:04:50 -04:00
|
|
|
#ifdef KEY_END
|
2023-08-04 13:49:03 -04:00
|
|
|
c == KEY_END ||
|
2023-07-27 14:04:50 -04:00
|
|
|
#endif
|
2023-08-04 13:49:03 -04:00
|
|
|
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 */
|
2023-08-04 15:09:58 -04:00
|
|
|
if(iscaseless == true) {
|
2023-08-04 13:49:03 -04:00
|
|
|
c = tolower(c);
|
|
|
|
}
|
|
|
|
/* if it will fit on the line */
|
|
|
|
if (i < size) {
|
2023-08-04 14:05:31 -04:00
|
|
|
s[i++] = c; /* save it */
|
2023-08-04 13:49:03 -04:00
|
|
|
if (ri == 0) {
|
2023-08-04 14:05:31 -04:00
|
|
|
addch(c); /* display it */
|
2023-08-04 13:49:03 -04:00
|
|
|
} else {
|
2023-08-04 14:05:31 -04:00
|
|
|
insch(c); /* display it */
|
|
|
|
addch(c); /* advance cursor */
|
2023-08-04 13:49:03 -04:00
|
|
|
}
|
|
|
|
}
|
2023-07-27 14:04:50 -04:00
|
|
|
#if UNIXPC
|
2023-08-04 15:09:58 -04:00
|
|
|
} else if (unixpcmouse == true && c == ESC) { /* mouse */
|
2023-08-04 13:49:03 -04:00
|
|
|
getmouseaction(ESC); /* ignore it */
|
2023-07-27 14:04:50 -04:00
|
|
|
#endif
|
2023-08-04 15:09:58 -04:00
|
|
|
} else if (mouse == true && c == ctrl('X')) {
|
2023-08-04 13:49:03 -04:00
|
|
|
getmouseaction(ctrl('X')); /* ignore it */
|
2023-08-04 14:05:31 -04:00
|
|
|
} else if (c == EOF) { /* end-of-file */
|
2023-08-04 13:49:03 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return on an empty line to allow a command to be entered */
|
|
|
|
if (firstchar != '\0' && (i+ri) == 0) {
|
|
|
|
break;
|
|
|
|
}
|
2023-07-27 14:04:50 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* move any remaining chars on the rhs of the cursor
|
|
|
|
* onto the end of our string
|
|
|
|
*/
|
|
|
|
while (ri > 0) {
|
2023-08-04 13:49:03 -04:00
|
|
|
s[i++] = sright[--ri];
|
2023-07-27 14:04:50 -04:00
|
|
|
}
|
|
|
|
free(sright);
|
|
|
|
|
|
|
|
s[i] = '\0';
|
|
|
|
return(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ask user to enter a character after reading the message */
|
|
|
|
|
|
|
|
void
|
2023-08-10 08:36:16 -04:00
|
|
|
askforchar(void){
|
2023-07-27 14:04:50 -04:00
|
|
|
addstr("Type any character to continue: ");
|
2023-08-05 05:30:18 -04:00
|
|
|
getch();
|
2023-07-27 14:04:50 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ask user to press the RETURN key after reading the message */
|
|
|
|
|
|
|
|
void
|
2023-08-10 08:36:16 -04:00
|
|
|
askforreturn(void){
|
2023-07-27 14:04:50 -04:00
|
|
|
fprintf(stderr, "Press the RETURN key to continue: ");
|
|
|
|
getchar();
|
|
|
|
/* HBB 20060419: message probably messed up the screen --- redraw */
|
2023-08-04 15:09:58 -04:00
|
|
|
if (incurses == true) {
|
2023-08-04 13:49:03 -04:00
|
|
|
redrawwin(curscr);
|
2023-07-27 14:04:50 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* expand the ~ and $ shell meta characters in a path */
|
|
|
|
|
|
|
|
void
|
2023-08-10 08:36:16 -04:00
|
|
|
shellpath(char *out, int limit, char *in){
|
2023-08-04 13:49:03 -04:00
|
|
|
char *lastchar;
|
|
|
|
char *s, *v;
|
2023-07-27 14:04:50 -04:00
|
|
|
|
|
|
|
/* skip leading white space */
|
|
|
|
while (isspace((unsigned char)*in)) {
|
2023-08-04 13:49:03 -04:00
|
|
|
++in;
|
2023-07-27 14:04:50 -04:00
|
|
|
}
|
|
|
|
lastchar = out + limit - 1;
|
|
|
|
|
|
|
|
/* a tilde (~) by itself represents $HOME; followed by a name it
|
|
|
|
represents the $LOGDIR of that login name */
|
|
|
|
if (*in == '~') {
|
2023-08-04 13:49:03 -04:00
|
|
|
*out++ = *in++; /* copy the ~ because it may not be expanded */
|
|
|
|
|
|
|
|
/* get the login name */
|
|
|
|
s = out;
|
|
|
|
while (s < lastchar && *in != '/' && *in != '\0' && !isspace((unsigned char)*in)) {
|
|
|
|
*s++ = *in++;
|
|
|
|
}
|
|
|
|
*s = '\0';
|
|
|
|
|
|
|
|
/* if the login name is null, then use $HOME */
|
|
|
|
if (*out == '\0') {
|
|
|
|
v = getenv("HOME");
|
|
|
|
} else { /* get the home directory of the login name */
|
|
|
|
v = logdir(out);
|
|
|
|
}
|
|
|
|
/* copy the directory name if it isn't too big */
|
|
|
|
if (v != NULL && strlen(v) < (lastchar - out)) {
|
|
|
|
strcpy(out - 1, v);
|
|
|
|
out += strlen(v) - 1;
|
|
|
|
} else {
|
|
|
|
/* login not found, so ~ must be part of the file name */
|
|
|
|
out += strlen(out);
|
|
|
|
}
|
2023-07-27 14:04:50 -04:00
|
|
|
}
|
|
|
|
/* get the rest of the path */
|
|
|
|
while (out < lastchar && *in != '\0' && !isspace((unsigned char)*in)) {
|
|
|
|
|
2023-08-04 13:49:03 -04:00
|
|
|
/* look for an environment variable */
|
|
|
|
if (*in == '$') {
|
|
|
|
*out++ = *in++; /* copy the $ because it may not be expanded */
|
|
|
|
|
|
|
|
/* get the variable name */
|
|
|
|
s = out;
|
|
|
|
while (s < lastchar && *in != '/' && *in != '\0' &&
|
|
|
|
!isspace((unsigned char)*in)) {
|
|
|
|
*s++ = *in++;
|
|
|
|
}
|
|
|
|
*s = '\0';
|
2023-08-04 14:34:51 -04:00
|
|
|
|
2023-08-04 13:49:03 -04:00
|
|
|
/* get its value, but only it isn't too big */
|
|
|
|
if ((v = getenv(out)) != NULL && strlen(v) < (lastchar - out)) {
|
|
|
|
strcpy(out - 1, v);
|
|
|
|
out += strlen(v) - 1;
|
|
|
|
} else {
|
|
|
|
/* var not found, or too big, so assume $ must be part of the
|
|
|
|
* file name */
|
|
|
|
out += strlen(out);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else { /* ordinary character */
|
|
|
|
*out++ = *in++;
|
|
|
|
}
|
2023-07-27 14:04:50 -04:00
|
|
|
}
|
|
|
|
*out = '\0';
|
|
|
|
}
|
2023-08-04 13:12:06 -04:00
|
|
|
|
|
|
|
static int
|
|
|
|
wmode_input(const int c){
|
|
|
|
switch (c) {
|
2023-08-04 13:49:03 -04:00
|
|
|
case KEY_ENTER:
|
|
|
|
case '\r':
|
|
|
|
case '\n':
|
2023-08-04 14:05:31 -04:00
|
|
|
case ctrl('N'): /* go to next input field */
|
2023-08-04 13:49:03 -04:00
|
|
|
case KEY_DOWN:
|
|
|
|
case KEY_RIGHT:
|
2023-08-04 14:05:31 -04:00
|
|
|
field = (field + 1) % FIELDS;
|
|
|
|
resetcmd();
|
2023-08-04 14:19:06 -04:00
|
|
|
break;
|
2023-08-04 14:05:31 -04:00
|
|
|
case ctrl('P'): /* go to previous input field */
|
2023-08-04 13:49:03 -04:00
|
|
|
case KEY_UP:
|
|
|
|
case KEY_LEFT:
|
2023-08-04 14:05:31 -04:00
|
|
|
field = (field + (FIELDS - 1)) % FIELDS;
|
|
|
|
resetcmd();
|
2023-08-04 14:19:06 -04:00
|
|
|
break;
|
2023-08-04 13:49:03 -04:00
|
|
|
case KEY_HOME: /* go to first input field */
|
2023-08-04 14:05:31 -04:00
|
|
|
field = 0;
|
|
|
|
resetcmd();
|
2023-08-04 14:19:06 -04:00
|
|
|
break;
|
2023-08-04 13:49:03 -04:00
|
|
|
case KEY_LL: /* go to last input field */
|
2023-08-04 14:05:31 -04:00
|
|
|
curdispline = disprefs;
|
2023-08-04 14:19:06 -04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return 0;
|
2023-08-04 13:49:03 -04:00
|
|
|
}
|
2023-08-04 14:19:06 -04:00
|
|
|
|
|
|
|
window_change |= CH_MODE;
|
|
|
|
return 1;
|
2023-08-04 13:12:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
wresult_input(const int c){
|
|
|
|
switch (c) {
|
2023-08-04 13:49:03 -04:00
|
|
|
case KEY_ENTER: /* open for editing */
|
|
|
|
case '\r':
|
|
|
|
case '\n':
|
2023-08-04 14:05:31 -04:00
|
|
|
editref(curdispline);
|
|
|
|
window_change = CH_ALL;
|
2023-08-04 14:19:06 -04:00
|
|
|
break;
|
2023-08-04 13:49:03 -04:00
|
|
|
case ctrl('N'):
|
|
|
|
case KEY_DOWN:
|
|
|
|
case KEY_RIGHT:
|
2023-08-04 14:05:31 -04:00
|
|
|
if ((curdispline + 1) < disprefs) {
|
|
|
|
++curdispline;
|
|
|
|
}
|
2023-08-04 14:19:06 -04:00
|
|
|
break;
|
2023-08-04 13:49:03 -04:00
|
|
|
case ctrl('P'):
|
|
|
|
case KEY_UP:
|
|
|
|
case KEY_LEFT:
|
2023-08-04 14:05:31 -04:00
|
|
|
if (curdispline) {
|
|
|
|
--curdispline;
|
|
|
|
}
|
2023-08-04 14:19:06 -04:00
|
|
|
break;
|
2023-08-04 13:49:03 -04:00
|
|
|
case KEY_HOME:
|
|
|
|
curdispline = 0;
|
2023-08-04 14:19:06 -04:00
|
|
|
break;
|
2023-08-04 13:49:03 -04:00
|
|
|
case KEY_LL:
|
2023-08-04 14:05:31 -04:00
|
|
|
field = FIELDS - 1;
|
|
|
|
resetcmd();
|
2023-08-04 14:19:06 -04:00
|
|
|
break;
|
2023-08-04 13:49:03 -04:00
|
|
|
default:
|
2023-08-08 06:47:02 -04:00
|
|
|
if(c > mdisprefs){ goto noredisp; }
|
|
|
|
const int pos = dispchar2int(c);
|
|
|
|
if(pos > -1){ editref(pos); }
|
2023-08-04 14:19:06 -04:00
|
|
|
goto noredisp;
|
2023-08-04 13:49:03 -04:00
|
|
|
}
|
2023-08-04 14:19:06 -04:00
|
|
|
|
|
|
|
window_change |= CH_RESULT;
|
|
|
|
noredisp:
|
|
|
|
return 1;
|
2023-08-04 13:12:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
global_input(const int c){
|
2023-08-04 13:49:03 -04:00
|
|
|
switch(c){
|
2023-08-04 14:05:31 -04:00
|
|
|
case '\t':
|
|
|
|
horswp_field();
|
|
|
|
break;
|
|
|
|
case '%':
|
|
|
|
verswp_field();
|
|
|
|
break;
|
|
|
|
case ' ': /* display next page */
|
2023-08-04 13:49:03 -04:00
|
|
|
case '+':
|
|
|
|
case ctrl('V'):
|
|
|
|
case KEY_NPAGE:
|
2023-08-04 16:35:56 -04:00
|
|
|
if (totallines == 0) { return 0; } /* don't redisplay if there are no lines */
|
2023-08-04 14:05:31 -04:00
|
|
|
curdispline = 0;
|
2023-08-08 06:47:02 -04:00
|
|
|
++current_page;
|
2023-08-05 10:30:21 -04:00
|
|
|
window_change |= CH_RESULT;
|
2023-08-04 14:05:31 -04:00
|
|
|
break;
|
|
|
|
case ctrl('H'): /* display previous page */
|
2023-08-04 13:49:03 -04:00
|
|
|
case '-':
|
|
|
|
case KEY_PPAGE:
|
2023-08-04 16:35:56 -04:00
|
|
|
if (totallines == 0) { return 0; } /* don't redisplay if there are no lines */
|
2023-08-04 14:05:31 -04:00
|
|
|
curdispline = 0;
|
2023-08-08 06:47:02 -04:00
|
|
|
--current_page;
|
|
|
|
///* 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);
|
2023-08-04 14:05:31 -04:00
|
|
|
break;
|
|
|
|
case '>': /* write or append the lines to a file */
|
|
|
|
break; // XXX
|
|
|
|
//char filename[PATHLEN + 1];
|
|
|
|
//char* s;
|
|
|
|
//char ch;
|
|
|
|
//FILE* file;
|
|
|
|
//if (totallines == 0) {
|
|
|
|
// postmsg("There are no lines to write to a file");
|
|
|
|
// return(NO);
|
|
|
|
//}
|
|
|
|
//move(PRLINE, 0);
|
|
|
|
////addstr("Write to file: "); // XXX
|
|
|
|
//s = "w";
|
2023-08-05 05:30:18 -04:00
|
|
|
//if ((ch = getch()) == '>') {
|
2023-08-04 14:05:31 -04:00
|
|
|
//move(PRLINE, 0);
|
|
|
|
////addstr(appendprompt); // XXX fix
|
|
|
|
////ch = '\0';
|
|
|
|
////s = "a";
|
|
|
|
////}
|
|
|
|
////if (ch != '\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 ((ch = getc(refsfound)) != EOF) {
|
|
|
|
//// putc(ch, file);
|
|
|
|
//// }
|
|
|
|
//// seekline(topline);
|
|
|
|
//// fclose(file);
|
|
|
|
//// }
|
|
|
|
////}
|
|
|
|
////clearprompt();
|
|
|
|
break;
|
|
|
|
case '<': /* read lines from a file */
|
|
|
|
break; // XXX
|
2023-08-10 08:36:16 -04:00
|
|
|
//move(PRLINE, 0);
|
2023-08-04 14:05:31 -04:00
|
|
|
//addstr(readprompt); // XXX fix
|
|
|
|
//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);
|
|
|
|
// }
|
|
|
|
// window_change |= CH_INPUT;
|
|
|
|
// return(YES);
|
|
|
|
//}
|
|
|
|
//clearprompt();
|
2023-08-04 16:35:56 -04:00
|
|
|
return 0;
|
2023-08-04 14:05:31 -04:00
|
|
|
case '|': /* pipe the lines to a shell command */
|
2023-08-04 13:49:03 -04:00
|
|
|
case '^':
|
2023-08-04 14:05:31 -04:00
|
|
|
break; // XXX fix
|
|
|
|
if (totallines == 0) {
|
|
|
|
postmsg("There are no lines to pipe to a shell command");
|
2023-08-04 16:35:56 -04:00
|
|
|
return 0;
|
2023-08-04 14:05:31 -04:00
|
|
|
}
|
|
|
|
/* get the shell command */
|
2023-08-10 08:36:16 -04:00
|
|
|
//move(PRLINE, 0);
|
2023-08-04 14:05:31 -04:00
|
|
|
//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 {
|
|
|
|
// seekline(1);
|
|
|
|
// while ((c = getc(refsfound)) != EOF) {
|
|
|
|
// putc(c, file);
|
|
|
|
// }
|
|
|
|
// seekline(topline);
|
|
|
|
// mypclose(file);
|
|
|
|
//}
|
|
|
|
//if (commandc == '^') {
|
|
|
|
// if (readrefs(temp2) == NO) {
|
|
|
|
// postmsg("Ignoring empty output of ^ command");
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
//askforreturn();
|
|
|
|
//entercurses();
|
|
|
|
break;
|
|
|
|
case '!': /* shell escape */
|
|
|
|
execute(shell, shell, NULL);
|
2023-08-08 06:47:02 -04:00
|
|
|
current_page = 0;
|
2023-08-04 14:05:31 -04:00
|
|
|
break;
|
2023-08-04 13:49:03 -04:00
|
|
|
case KEY_RESIZE:
|
2023-08-04 14:05:31 -04:00
|
|
|
/* XXX: fill in*/
|
|
|
|
break;
|
|
|
|
case ctrl('L'): /* redraw screen */
|
2023-08-04 13:49:03 -04:00
|
|
|
case KEY_CLEAR:
|
2023-08-04 14:05:31 -04:00
|
|
|
window_change = CH_ALL;
|
|
|
|
break;
|
|
|
|
case '?': /* help */
|
2023-08-05 05:30:18 -04:00
|
|
|
window_change = CH_HELP;
|
2023-08-04 14:05:31 -04:00
|
|
|
break;
|
|
|
|
case ctrl('E'): /* edit all lines */
|
|
|
|
editall();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return 0;
|
2023-08-04 13:49:03 -04:00
|
|
|
}
|
|
|
|
|
2023-08-04 14:05:31 -04:00
|
|
|
return 1;
|
2023-08-04 13:12:06 -04:00
|
|
|
}
|
|
|
|
|
2023-08-10 08:36:16 -04:00
|
|
|
extern const void *const winput;
|
|
|
|
extern const void *const wmode;
|
|
|
|
extern const void *const wresult;
|
|
|
|
extern const void *const *const current_window;
|
2023-08-10 09:52:28 -04:00
|
|
|
extern const int topline;
|
2023-08-10 08:36:16 -04:00
|
|
|
|
2023-08-10 09:52:28 -04:00
|
|
|
int
|
2023-08-10 08:36:16 -04:00
|
|
|
change_input(const int c){
|
|
|
|
MOUSE *p; /* mouse data */
|
|
|
|
change = calloc(totallines, sizeof(*change));
|
|
|
|
|
|
|
|
switch(c){
|
2023-08-10 09:52:28 -04:00
|
|
|
case '*': /* invert page */
|
|
|
|
for(int i = 0; topline + i < nextline; i++){
|
|
|
|
change[topline + i] = !change[topline + i];
|
|
|
|
}
|
2023-08-10 08:36:16 -04:00
|
|
|
break;
|
2023-08-10 09:52:28 -04:00
|
|
|
case ctrl('A'): /* invert all lines */
|
|
|
|
for(unsigned i = 0; i < totallines; i++) {
|
2023-08-10 08:36:16 -04:00
|
|
|
change[i] = !change[i];
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ctrl('X'): /* mouse selection */
|
|
|
|
if ((p = getmouseaction(DUMMYCHAR)) == NULL) {
|
|
|
|
break; /* unknown control sequence */
|
|
|
|
}
|
|
|
|
/* if the button number is a scrollbar tag */
|
|
|
|
if (p->button == '0') {
|
2023-08-10 09:12:34 -04:00
|
|
|
//scrollbar(p);
|
2023-08-10 08:36:16 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* find the selected line */
|
|
|
|
/* NOTE: the selection is forced into range */
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for(i = disprefs - 1; i > 0; --i) {
|
|
|
|
if (p->y1 >= displine[i]) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
change[i] = !change[i];
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ctrl('D'):
|
2023-08-10 09:52:28 -04:00
|
|
|
changestring(input_line, newpat, change);
|
2023-08-10 08:36:16 -04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
/* if a line was selected */
|
|
|
|
const int cc = dispchar2int(c);
|
|
|
|
if(cc != -1){
|
|
|
|
change[cc] = !change[cc];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-08-10 09:12:34 -04:00
|
|
|
int
|
2023-08-10 09:52:28 -04:00
|
|
|
changestring(const char* from, const char* to, bool *change){
|
2023-08-10 08:36:16 -04:00
|
|
|
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 = false; /* any line marked */
|
|
|
|
|
|
|
|
/* open the temporary file */
|
|
|
|
if((script = myfopen(temp2, "w")) == NULL) {
|
|
|
|
cannotopen(temp2);
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* for each line containing the old text */
|
|
|
|
fprintf(script, "ed - <<\\!\n");
|
|
|
|
*oldfile = '\0';
|
|
|
|
fseek(refsfound, 0, SEEK_SET);
|
|
|
|
for(int i = 0;
|
|
|
|
fscanf(refsfound, "%" PATHLEN_STR "s%*s%" NUMLEN_STR "s%*[^\n]", newfile, linenum) == 2;
|
|
|
|
++i)
|
|
|
|
{
|
|
|
|
/* see if the line is to be changed */
|
|
|
|
if (change[i] == false) { break; }
|
|
|
|
anymarked = true;
|
|
|
|
|
|
|
|
/* if this is a new file */
|
|
|
|
if (strcmp(newfile, oldfile) != 0) {
|
|
|
|
|
|
|
|
/* make sure it can be changed */
|
|
|
|
if (access(newfile, WRITE) != 0) {
|
|
|
|
snprintf(msg, sizeof(msg), "Cannot write to file %s", newfile);
|
|
|
|
postmsg(msg);
|
|
|
|
anymarked = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* if there was an old file */
|
|
|
|
if (*oldfile != '\0') {
|
|
|
|
fprintf(script, "w\n"); /* save it */
|
|
|
|
}
|
|
|
|
/* edit the new file */
|
|
|
|
strcpy(oldfile, newfile);
|
|
|
|
fprintf(script, "e %s\n", oldfile);
|
|
|
|
}
|
|
|
|
/* output substitute command */
|
|
|
|
fprintf(script, "%ss/", linenum); /* change */
|
2023-08-10 09:52:28 -04:00
|
|
|
for(const char *s = from; *s != '\0'; ++s) {
|
|
|
|
/* old text */
|
|
|
|
if (strchr("/\\[.^*", *s) != NULL) {
|
|
|
|
putc('\\', script);
|
|
|
|
}
|
|
|
|
if (caseless == true && isalpha((unsigned char)*s)) {
|
|
|
|
putc('[', script);
|
|
|
|
if(islower((unsigned char)*s)) {
|
|
|
|
putc(toupper((unsigned char)*s), script);
|
|
|
|
putc(*s, script);
|
|
|
|
} else {
|
|
|
|
putc(*s, script);
|
|
|
|
putc(tolower((unsigned char)*s), script);
|
|
|
|
}
|
|
|
|
putc(']', script);
|
|
|
|
} else {
|
|
|
|
putc(*s, script);
|
|
|
|
}
|
|
|
|
}
|
2023-08-10 08:36:16 -04:00
|
|
|
putc('/', script); /* to */
|
2023-08-10 09:52:28 -04:00
|
|
|
for(const char *s = to; *s != '\0'; ++s) { /* new text */
|
2023-08-10 08:36:16 -04:00
|
|
|
if (strchr("/\\&", *s) != NULL) {
|
|
|
|
putc('\\', script);
|
|
|
|
}
|
|
|
|
putc(*s, script);
|
|
|
|
}
|
|
|
|
fprintf(script, "/gp\n"); /* and print */
|
|
|
|
}
|
|
|
|
fprintf(script, "w\nq\n!\n"); /* write and quit */
|
|
|
|
|
|
|
|
/* if any line was marked */
|
|
|
|
if (anymarked == true) {
|
|
|
|
/* edit the files */
|
|
|
|
fprintf(stderr, "Changed lines:\n\r");
|
|
|
|
execute("sh", "sh", temp2, NULL);
|
|
|
|
askforchar();
|
|
|
|
}
|
2023-08-10 09:52:28 -04:00
|
|
|
|
2023-08-10 08:36:16 -04:00
|
|
|
changing = false;
|
|
|
|
mousemenu();
|
|
|
|
fclose(script);
|
|
|
|
free(change);
|
|
|
|
return(anymarked);
|
|
|
|
}
|
2023-08-04 13:12:06 -04:00
|
|
|
|
|
|
|
int
|
2023-08-08 14:34:15 -04:00
|
|
|
handle_input(const int c){
|
2023-08-05 05:30:18 -04:00
|
|
|
/* - was wating for any input - */
|
|
|
|
if(do_press_any_key){
|
|
|
|
do_press_any_key = false;
|
|
|
|
return 0;
|
|
|
|
}
|
2023-08-04 13:49:03 -04:00
|
|
|
/* --- global --- */
|
|
|
|
const int r = global_input(c);
|
2023-08-04 14:05:31 -04:00
|
|
|
if(r){ return 0; }
|
2023-08-04 13:49:03 -04:00
|
|
|
/* --- mode specific --- */
|
2023-08-10 08:36:16 -04:00
|
|
|
switch(input_mode){
|
|
|
|
case INPUT_NORMAL:
|
|
|
|
if(*current_window == winput){
|
|
|
|
return interpret(c);
|
|
|
|
}else if(*current_window == wmode){
|
|
|
|
return wmode_input(c);
|
|
|
|
}else if(*current_window == wresult){
|
|
|
|
return wresult_input(c);
|
|
|
|
}
|
|
|
|
assert("'current_window' dangling.");
|
|
|
|
break; /* NOTREACHED */
|
|
|
|
case INPUT_CHANGE:
|
|
|
|
return change_input(c);
|
|
|
|
}
|
2023-08-04 13:49:03 -04:00
|
|
|
|
|
|
|
return 0;
|
2023-08-04 13:12:06 -04:00
|
|
|
}
|