root/gtags-cscope/input.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. catchint
  2. myungetch
  3. mygetch
  4. mygetline
  5. askforchar
  6. askforreturn
  7. shellpath

   1 /*===========================================================================
   2  Copyright (c) 1998-2000, The Santa Cruz Operation 
   3  All rights reserved.
   4  
   5  Redistribution and use in source and binary forms, with or without
   6  modification, are permitted provided that the following conditions are met:
   7 
   8  *Redistributions of source code must retain the above copyright notice,
   9  this list of conditions and the following disclaimer.
  10 
  11  *Redistributions in binary form must reproduce the above copyright notice,
  12  this list of conditions and the following disclaimer in the documentation
  13  and/or other materials provided with the distribution.
  14 
  15  *Neither name of The Santa Cruz Operation nor the names of its contributors
  16  may be used to endorse or promote products derived from this software
  17  without specific prior written permission. 
  18 
  19  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
  20  IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  21  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  22  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
  23  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26  INTERRUPTION)
  27  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  30  DAMAGE. 
  31  =========================================================================*/
  32 
  33 /** @file
  34  *      terminal input functions
  35  *
  36  *      cscope - interactive C symbol cross-reference
  37  */
  38 
  39 #include "global-cscope.h"
  40 #if defined(USE_NCURSES) && !defined(RENAMED_NCURSES)
  41 #include <ncurses.h>
  42 #else
  43 #include <curses.h>
  44 #endif
  45 #include <setjmp.h>     /* jmp_buf */
  46 #include <stdlib.h>
  47 #include <errno.h>
  48 #if HAVE_SYS_TERMIOS_H
  49 #include <sys/termios.h>
  50 #endif
  51 
  52 static char const rcsid[] = "$Id: input.c,v 1.2 2012/10/13 07:02:07 shigio Exp $";
  53 
  54 static  jmp_buf env;            /**< setjmp/longjmp buffer */
  55 static  int     prevchar;       /**< previous, ungotten character */
  56 
  57 /* Internal prototypes: */
  58 static RETSIGTYPE catchint(int sig);
  59 
  60 /** catch the interrupt signal */
  61 
  62 /*ARGSUSED*/
  63 static RETSIGTYPE
  64 catchint(int sig)
  65 {
  66         (void) sig;             /* 'use' it, to avoid a warning */
  67 
  68         signal(SIGINT, catchint);
  69         longjmp(env, 1);
  70 }
  71 
  72 /** unget a character */
  73 void
  74 myungetch(int c)
  75 {
  76         prevchar = c;
  77 }
  78 
  79 /** get a character from the terminal */
  80 int
  81 mygetch(void)
  82 {
  83     sighandler_t savesig; /* old value of signal */
  84     int c;
  85 
  86     /* change an interrupt signal to a break key character */
  87     if (setjmp(env) == 0) {
  88         savesig = signal(SIGINT, catchint);
  89         refresh();      /* update the display */
  90         mousereinit();  /* curses can change the menu number */
  91         if(prevchar) {
  92             c = prevchar;
  93             prevchar = 0;
  94         } else {
  95             c = -1;
  96             while (c == -1) {
  97                 /* get a character from the terminal */
  98                 c = getch();
  99                 if ((c == -1) && (errno != EINTR))
 100                     break;
 101             }
 102         }
 103     } else {    /* longjmp to here from signal handler */
 104         c = KEY_BREAK;
 105     }
 106     signal(SIGINT, savesig);
 107     return(c);
 108 }
 109 
 110 
 111 /** get a line from the terminal in non-canonical mode */
 112 int
 113 mygetline(char p[], char s[], unsigned size, int firstchar, BOOL iscaseless)
 114 {
 115     int c;
 116     unsigned int i = 0, j;
 117     char *sright;       /* substring to the right of the cursor */
 118     unsigned int ri = 0;                /* position in right-string */
 119 
 120     /* Inserts and deletes are always performed on the left-string,
 121      * but we'll also have a right-string 'sright' to hold characters
 122      * which are on the right of the cursor [insertion point].
 123      *
 124      * Think of 'sright' as a stack -- we push chars into it when the cursor
 125      * moves left, and we pop chars off it when the cursor moves right again.
 126      * At the end of the function, we'll pop off any remaining characters
 127      * onto the end of 's'
 128      */
 129     sright = calloc(sizeof(char), size );
 130 
 131     strcpy ( s, p);
 132     i += strlen(p);
 133     /* if a character already has been typed */
 134     if (firstchar != '\0') {
 135         if(iscaseless == YES) {
 136             firstchar = tolower(firstchar);
 137         }
 138         addch(firstchar);       /* display it */
 139         s[i++] = firstchar;     /* save it */
 140     }
 141     /* until the end of the line is reached */
 142     while ((c = mygetch()) != '\r' && c != '\n' && c != KEY_ENTER) {
 143         if (c == KEY_LEFT || c == ctrl('B')) {  /* left */
 144             if (i > 0) {
 145                 addch('\b');
 146                 /* move this char into the second (rhs) string */
 147                 sright[ri++] = s[--i];
 148             }
 149         } else if (c == KEY_RIGHT || c == ctrl('F')) {  /* right */
 150             if (i < size && ri > 0) {
 151                 /* move this char to the left of the cursor */
 152                 s[i++] = sright[--ri];
 153                 addch(s[i-1]);
 154             }
 155         } else if (
 156 #ifdef KEY_HOME
 157                    c == KEY_HOME ||
 158 #endif
 159                    c == ctrl('A') ) {
 160             while (i > 0) {
 161                 sright[ri++] = s[--i];
 162                 addch('\b');
 163                 addch(s[i]);
 164                 addch('\b');
 165             }
 166         } else if (
 167 #ifdef KEY_END
 168                    c == KEY_END ||
 169 #endif
 170                    c == ctrl('E') ) {
 171             while (ri > 0) {
 172                 s[i++] = sright[--ri];
 173                 addch(s[i-1]);
 174             }
 175         } else if (c == erasechar() || c == KEY_BACKSPACE
 176                    || c == DEL || c == ctrl('H') ) {
 177             /* erase */
 178             if (i > 0) {
 179                 if (ri == 0)  {
 180                     addstr("\b \b");
 181                 } else {
 182                     addch('\b');
 183                     delch();
 184                 }
 185                 s[i] = '\0';
 186                 --i;
 187             }
 188         } else if (c == killchar() || c == KEY_BREAK) {
 189             /* kill */
 190             for (j = 0; j < i; ++j) {
 191                 addch('\b');
 192             }
 193             for (j = 0; j < i; ++j) {
 194                 addch(' ');
 195             }
 196             for (j = 0; j < i; ++j) {
 197                 addch('\b');
 198             }
 199             i = 0;
 200         } else if (isprint(c) || c == '\t') {
 201             /* printable */
 202             if(iscaseless == YES) {
 203                 c = tolower(c);
 204             }
 205             /* if it will fit on the line */
 206             if (i < size) {
 207                 s[i++] = c;     /* save it */
 208                 if (ri == 0) {
 209                     addch(c);   /* display it */
 210                 } else {
 211                     insch(c);   /* display it */
 212                     addch(c);   /* advance cursor */
 213                 }
 214             }
 215 #if UNIXPC
 216         } else if (unixpcmouse == YES && c == ESC) {    /* mouse */
 217             getmouseaction(ESC);        /* ignore it */
 218 #endif
 219         } else if (mouse == YES && c == ctrl('X')) {
 220             getmouseaction(ctrl('X'));  /* ignore it */
 221         } else if (c == EOF) {                          /* end-of-file */
 222             break;
 223         }
 224 
 225         /* return on an empty line to allow a command to be entered */
 226         if (firstchar != '\0' && (i+ri) == 0) {
 227             break;
 228         }
 229     }
 230 
 231     /* move any remaining chars on the rhs of the cursor
 232      * onto the end of our string
 233      */
 234     while (ri > 0) {
 235         s[i++] = sright[--ri];
 236     }
 237     free(sright);
 238 
 239     s[i] = '\0';
 240     return(i);
 241 }
 242 
 243 /** ask user to enter a character after reading the message */
 244 
 245 void
 246 askforchar(void)
 247 {
 248     addstr("Type any character to continue: ");
 249     mygetch();
 250 }
 251 
 252 /** ask user to press the @NAME{RETURN} key after reading the message */
 253 
 254 void
 255 askforreturn(void)
 256 {
 257     fprintf(stderr, "Press the RETURN key to continue: ");
 258     getchar();
 259     /* HBB 20060419: message probably messed up the screen --- redraw */
 260     if (incurses == YES) {
 261         redrawwin(curscr);
 262     }
 263 }
 264 
 265 /** expand the @CODE{~} and @CODE{\$} shell meta characters in a path */
 266 
 267 void
 268 shellpath(char *out, int limit, char *in) 
 269 {
 270     char        *lastchar;
 271     char        *s, *v;
 272 
 273     /* skip leading white space */
 274     while (isspace((unsigned char)*in)) {
 275         ++in;
 276     }
 277     lastchar = out + limit - 1;
 278 
 279     /* a tilde (~) by itself represents $HOME; followed by a name it
 280        represents the $LOGDIR of that login name */
 281     if (*in == '~') {
 282         *out++ = *in++; /* copy the ~ because it may not be expanded */
 283 
 284         /* get the login name */
 285         s = out;
 286         while (s < lastchar && *in != '/' && *in != '\0' && !isspace((unsigned char)*in)) {
 287             *s++ = *in++;
 288         }
 289         *s = '\0';
 290 
 291         /* if the login name is null, then use $HOME */
 292         if (*out == '\0') {
 293             v = getenv("HOME");
 294         } else {        /* get the home directory of the login name */
 295             v = logdir(out);
 296         }
 297         /* copy the directory name if it isn't too big */
 298         if (v != NULL && strlen(v) < (lastchar - out)) {
 299             strcpy(out - 1, v);
 300             out += strlen(v) - 1;
 301         } else {
 302             /* login not found, so ~ must be part of the file name */
 303             out += strlen(out);
 304         }
 305     }
 306     /* get the rest of the path */
 307     while (out < lastchar && *in != '\0' && !isspace((unsigned char)*in)) {
 308 
 309         /* look for an environment variable */
 310         if (*in == '$') {
 311             *out++ = *in++;     /* copy the $ because it may not be expanded */
 312 
 313             /* get the variable name */
 314             s = out;
 315             while (s < lastchar && *in != '/' && *in != '\0' &&
 316                    !isspace((unsigned char)*in)) {
 317                 *s++ = *in++;
 318             }
 319             *s = '\0';
 320         
 321             /* get its value, but only it isn't too big */
 322             if ((v = getenv(out)) != NULL && strlen(v) < (lastchar - out)) {
 323                 strcpy(out - 1, v);
 324                 out += strlen(v) - 1;
 325             } else {
 326                 /* var not found, or too big, so assume $ must be part of the
 327                  * file name */
 328                 out += strlen(out);
 329             }
 330         }
 331         else {  /* ordinary character */
 332             *out++ = *in++;
 333         }
 334     }
 335     *out = '\0';
 336 }

/* [previous][next][first][last][top][bottom][index][help] */