/* 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); }
/* 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 {