⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tgetch.c

📁 db.* (pronounced dee-be star) is an advanced, high performance, small footprint embedded database fo
💻 C
字号:
/*************************************************************************** *                                                                         * * db.*                                                                    * * open source database, ida utility                                       * *                                                                         * * Copyright (c) 2000 Centura Software Corporation. All rights reserved.   * *                                                                         * * Use of this software, whether in source code format, or in executable,  * * binary object code form, is governed by the CENTURA OPEN SOURCE LICENSE * * which is fully described in the LICENSE.TXT file, included within this  * * distribution of source code files.                                      *  *                                                                         * **************************************************************************//*--------------------------------------------------------------------------    IDA - Terminal Character Input Function--------------------------------------------------------------------------*/#ifdef QNX/***************************** QNX VERSION ****************************/#include <conio.h>#include "keyboard.h"/* ********************** LOCAL VARIABLE DECLARATIONS **************** */static char unget[20];static char unptr=0;/****************************************************************************/char tgetch()       /* get next terminal input character */{     int i;     char j;     while (1)     {          if (unptr)                i = unget[--unptr];          else                i = getch( );          if ((i>=' ' && i<='~') || i=='\n')      /* return normal char */                return ((char) i);          if (i == 127)                           /* return backspace */                return ('\b');          if (i == 255 )          {                i = getch();                j = 0;                switch (i)                {                     case 0201:  j = K_F1; break;                     case 0202:  j = K_F2; break;                     case 0203:  j = K_F3; break;                     case 0204:  j = K_F4; break;                     case 0205:  j = K_F5; break;                     case 0206:  j = K_F6; break;                     case 0207:  j = K_F7; break;                     case 0210:  j = K_F8; break;                     case 0211:  j = K_F9; break;                     case 0212:  j = K_F10; break;                     case 0240:  j = K_HOME; break;                     case 0241:  j = K_UP; break;                     case 0242:  j = K_PGUP; break;                     case 0244:  j = K_LEFT; break;                     case 0246:  j = K_RIGHT; break;                     case 0250:  j = K_END; break;                     case 0251:  j = K_DOWN; break;                     case 0252:  j = K_PGDN; break;                     case 0253:  j = K_INS; break;                     case 0254:  j = K_DEL; break;                     case 0003:  j = K_BREAK; break;                     case 0033:  j = K_ESC; break;                     default:    break;                }                if (j)                     return (j);          }     }}/****************************************************************************/int untgetch(char ch){    if (unptr < 18)        unget[unptr++] = ch;    return 0;}#else  /* QNX *//****************************** UNIX VERSION ******************************/#include <signal.h>#include <unistd.h>#include "db.star.h"#include "ida.h"#include "keyboard.h"/**************************** EXTERNAL FUNCTIONS **************************/extern int tgetent();extern char *tgetstr();/**************************** LOCAL VARIABLES *****************************/static jmp_buf sjbuf;typedef struct token{    struct token *t_next;               /* next token */    char ch;                            /* valid input token (character) */    int action;                         /* action associated with 'seen'                                         * token: */}  TOKEN;                               /* > 0 => next state, < 0 => return                                         * keytab.kchar for keytab entry                                         * -(action+1) */typedef struct state{    struct state *s_next;               /* next state (used only during                                         * table build) */    int state_no;                       /* state number (used only during                                         * table build) */    int end_action;                     /* action associated with end of                                         * input */    TOKEN *token_list;                  /* list of valid token characters */}  STATE;static int state_no = 1;static STATE start = {NULL, 0, 0, NULL};static STATE *cur_state = &start;static STATE **state_table;            /* state_table[state_no] points to                                        * state entry */static struct fcnkeys{    char kchar;                         /* returned character code */    char kstr[9];                       /* code string from terminal */    char *tcstr;                        /* termcap code string: note the                                         * upper-case special codes */}  keytab[] ={    {        K_INS, "\001", "IN"    },    {        K_HOME, "\002", "kh"    },    {        K_END, "\003", "EN"    },    {        K_UP, "\004", "ku"    },    {        K_DOWN, "\005", "kd"    },    {        K_LEFT, "\006", "kl"    },    {        K_RIGHT, "\007", "kr"    },    {        K_FTAB, "\011", NULL    },    {        K_PGUP, "\013", "PU"    },    {        K_PGDN, "\014", "PD"    },    {        K_F1, "\016", "k0"    },    {        K_F2, "\017", "k1"    },    {        K_F3, "\020", "k2"    },    {        K_F4, "\021", "k3"    },    {        K_F5, "\022", "k4"    },    {        K_F6, "\023", "k5"    },    {        K_F7, "\024", "k6"    },    {        K_F8, "\025", "k7"    },    {        K_F9, "\026", "k8"    },    {        K_F10, "\027", "k9"    },    {        K_CANCEL, "\030", "CN"    },    {        K_BREAK, "\032", "BR"    },    {        K_ESC, "\033", NULL    },    {        K_DEL, "\177", "DE"    },    {        '\0', "", NULL    }};/* put back input stack */struct in_stack{    struct in_stack *nextch;    char ch;};static struct in_stack *isp = NULL;static int initialized = 0;/* ========================================================================    Locate input token in current state*/static TOKEN *loctok( STATE *sp, char ch ){    register TOKEN *tokp, *tokq;    for (tokq = NULL, tokp = sp->token_list; tokp; tokp = tokp->t_next)    {        if (tokp->ch == ch)            return (tokp);        tokq = tokp;    }    if (!initialized)    {        tokp = (TOKEN *) calloc(1, sizeof(TOKEN));        if (tokq)            tokq->t_next = tokp;        else            sp->token_list = tokp;        tokp->t_next = NULL;        tokp->ch = ch;        tokp->action = 0;    }    return (tokp);}/* ========================================================================    Build terminal function key input state transition table*/static void bld_state_table(){    register TOKEN *tokp;    register STATE *sp;    register int i, cp, len;    for (i = 0; keytab[i].kchar; ++i)    {        sp = &start;        len = strlen(keytab[i].kstr);        for (cp = 0; cp < len; ++cp)        {            tokp = loctok(sp, keytab[i].kstr[cp]);            if (tokp->action > 0)            {                /* switch states */                while (tokp->action > sp->state_no)                    sp = sp->s_next;            }            else if (cp == len - 1)            {                tokp->action = -i - 1;            }            else            {                /* create new state */                cur_state->s_next = (STATE *) calloc(1, sizeof(STATE));                cur_state = cur_state->s_next;                cur_state->end_action = tokp->action;                tokp->action = cur_state->state_no = state_no++;                cur_state->token_list = NULL;                sp = cur_state;            }        }    }    state_table = (STATE **) calloc(state_no, sizeof(STATE *));    for (i = 0, sp = &start; i < state_no; ++i)    {        state_table[i] = sp;        sp = sp->s_next;    }}/* ========================================================================    Initialize terminal input*/static void tgetinit(){    char bp[1024];    char sbuf[80];    char *term, *p;    register int i, j;    term = getenv("TERM");    switch (tgetent(bp, term))    {        case -1:            fprintf(stderr, "unable to open termcap\n");            exit(1);        case 0:            fprintf(stderr, "no termcap entry for terminal %s\n", term);            exit(1);    }    for (i = 0; keytab[i].kchar; ++i)    {        p = sbuf;        if (keytab[i].tcstr)        {            if (p = tgetstr(keytab[i].tcstr, &p))            {                for (j = 0; p[j]; ++j)                    keytab[i].kstr[j] = (p[j] == '\r' ? '\n' : p[j]);                keytab[i].kstr[j] = '\0';            }        }    }    bld_state_table();    initialized = 1;}/* ========================================================================    Wake up getchar()*/static void wakeup(int dummy){    longjmp(sjbuf, 1);}/* ========================================================================    Push character back onto input stack*/void untgetch( char ch ){    struct in_stack *tsp;    tsp = (struct in_stack *) calloc(1, sizeof(struct in_stack));    if (tsp)    {        tsp->nextch = isp;        isp = tsp;        isp->ch = ch;    }}/* ========================================================================    Get next terminal input character*/char tgetch(){    char chbuf[20];    struct in_stack *tsp;    int awake;    char ch = 0;    register TOKEN *tokp;    /* FIXME: warning: variable `i' might be clobbered by      * `longjmp' or `vfork'     * there is no need to use a register var here - sp     */    register int i = 0;;    if (!initialized)        tgetinit();    /* return any put back character */    if (isp)    {        ch = isp->ch;        tsp = isp;        isp = isp->nextch;        free(tsp);        return (ch);    }    ch = getchar();    /* return any normal character */    if ((ch >= ' ' && ch <= '~') || ch == '\n' || ch == '\b')        return (ch);    /* possible function key */    state_no = 0;    chbuf[0] = ch;    chbuf[1] = '\0';    i = 1;    awake = setjmp(sjbuf);    while (!awake)    {        if (tokp = loctok(state_table[state_no], ch))        {            if (tokp->action > 0)                /* switch states */                state_no = tokp->action;            else                /* matched input sequence */                return (keytab[-(tokp->action + 1)].kchar);        }        else                             /* character sequence not found */            goto send_back;        signal(SIGALRM, wakeup);         /* This is how we can tell */        alarm(1);                        /* when there isn't any input char. */        ch = getchar();                  /* The alarm will wake up this                                          * getchar. */        signal(SIGALRM, SIG_IGN);        /* we'll only return if a char is                                          * avail. */        chbuf[i++] = ch;        chbuf[i] = '\0';    }    /* end of input */    if (state_table[state_no]->end_action < 0)        return (keytab[-(state_table[state_no]->end_action + 1)].kchar);send_back:    for (i = strlen(chbuf) - 1; i > 0; --i)        /* put back extra characters */        untgetch(chbuf[i]);    return (chbuf[0]);}#endif /* QNX */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -