Annotation of nono/debugger/console.cpp, revision 1.1.1.1

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2020 [email protected]
                      4: //
                      5: 
                      6: #include "console.h"
                      7: #include "mystring.h"
                      8: #include <poll.h>
                      9: 
                     10: //
                     11: // コンソール基本クラス
                     12: //
                     13: 
                     14: // コンストラクタ
                     15: Console::Console()
                     16: {
                     17:        inp.fd = -1;
                     18:        inp.file = NULL;
                     19:        out.fd = -1;
                     20:        out.file = NULL;
                     21: }
                     22: 
                     23: #if defined(HAVE_HISTEDIT_H)
                     24: // プロンプト文字列を返す (editline からコールバックで呼ばれる)
                     25: static char *
                     26: prompt_callback(EditLine *e)
                     27: {
                     28:        void *p;
                     29: 
                     30:        // CLIENTDATA に (char *)prompt が入っている
                     31:        el_get(e, EL_CLIENTDATA, &p);
                     32:        return (char *)p;
                     33: }
                     34: #endif
                     35: 
                     36: // EditLine を初期化する。p はプロンプト文字列。
                     37: void
                     38: Console::InitEditLine(const char *prompt_arg)
                     39: {
                     40:        // editline(3) を使わない場合は、プロンプトを自前で出すために覚えておく。
                     41:        // 使う場合には代入が無駄になるけど気にしない。
                     42:        prompt = prompt_arg;
                     43: 
                     44: #if defined(HAVE_HISTEDIT_H)
                     45:        if (use_editline) {
                     46:                // ヒストリの初期化
                     47:                hist = history_init();
                     48:                history(hist, &hev, H_SETSIZE, 100);
                     49: 
                     50:                // editline の初期化、設定
                     51:                el = el_init(getprogname(), inp.file, out.file, stderr);
                     52:                if (el == NULL) {
                     53:                        // どうすべ
                     54:                        warnx("el_init failed");
                     55:                        return;
                     56:                }
                     57:                // CLIENTDATA にプロンプトを入れておく
                     58:                el_set(el, EL_CLIENTDATA, prompt_arg);
                     59:                el_set(el, EL_PROMPT, prompt_callback);
                     60:                el_set(el, EL_EDITOR, "emacs");
                     61:                el_set(el, EL_HIST, history, hist);
                     62:        }
                     63: #endif
                     64: }
                     65: 
                     66: // クローズ
                     67: void
                     68: Console::Close()
                     69: {
                     70: #if defined(HAVE_HISTEDIT_H)
                     71:        if (use_editline) {
                     72:                el_end(el);
                     73:        }
                     74: #endif
                     75: 
                     76:        // fclose は fd も閉じる。
                     77:        if (inp.file != NULL) {
                     78:                fclose(inp.file);
                     79:                inp.file = NULL;
                     80:                inp.fd = -1;
                     81:        }
                     82:        if (out.file != NULL) {
                     83:                fclose(out.file);
                     84:                out.file = NULL;
                     85:                out.fd = -1;
                     86:        }
                     87: }
                     88: 
                     89: // プロンプトを出力する
                     90: void
                     91: Console::Prompt()
                     92: {
                     93: #if defined(HAVE_HISTEDIT_H)
                     94:        if (use_editline) {
                     95:                // editline(3) を使う場合は Gets() がプロンプトを出すので
                     96:                // ここでは何もしない。
                     97:        } else
                     98: #endif
                     99:        {
                    100:                // そうでない場合は、ここで自前でプロンプトを出す。
                    101:                Print("%s", prompt);
                    102:                Flush();
                    103:        }
                    104: }
                    105: 
                    106: // 出力
                    107: void
                    108: Console::Print(const char *fmt, ...)
                    109: {
                    110:        va_list ap;
                    111: 
                    112:        va_start(ap, fmt);
                    113:        vfprintf(out.file, fmt, ap);
                    114:        va_end(ap);
                    115: }
                    116: 
                    117: // 出力フラッシュ
                    118: void
                    119: Console::Flush()
                    120: {
                    121:        fflush(out.file);
                    122: }
                    123: 
                    124: // 1行出力
                    125: bool
                    126: Console::Gets(std::string& buf)
                    127: {
                    128: #if defined(HAVE_HISTEDIT_H)
                    129:        if (use_editline)
                    130:                return Gets_editline(buf);
                    131:        else
                    132: #endif
                    133:                return Gets_normal(buf);
                    134: }
                    135: 
                    136: #if defined(HAVE_HISTEDIT_H)
                    137: // 1行出力 (Editline 版)
                    138: bool
                    139: Console::Gets_editline(std::string& buf)
                    140: {
                    141:        const char *p;
                    142:        int num;
                    143: 
                    144:        p = el_gets(el, &num);
                    145:        if (p == NULL || num < 1) {
                    146:                // EOF
                    147:                return false;
                    148:        }
                    149:        // 呼び出し元へは EditLine から入力されたものをそのまま返す
                    150:        buf = std::string(p);
                    151: 
                    152:        // ヒストリに記録
                    153:        // の前に前後の空白は取り除いておく
                    154:        std::string hbuf = string_ltrim(buf);
                    155:        string_rtrim(hbuf);
                    156: 
                    157:        // 空文字列でなければ、ヒストリに記録
                    158:        if (!hbuf.empty()) {
                    159:                history(hist, &hev, H_ENTER, hbuf.c_str());
                    160:        }
                    161: 
                    162:        return true;
                    163: }
                    164: #endif
                    165: 
                    166: // 1行出力 (通常版)
                    167: bool
                    168: Console::Gets_normal(std::string& buf)
                    169: {
                    170:        char cbuf[1024];
                    171: 
                    172:        if (fgets(cbuf, sizeof(cbuf), inp.file) == NULL) {
                    173:                return false;
                    174:        }
                    175:        buf = std::string(cbuf);
                    176:        return true;
                    177: }
                    178: 
                    179: // 入力チェック
                    180: int
                    181: Console::Poll()
                    182: {
                    183:        struct pollfd pfd;
                    184: 
                    185:        if (inp.fd == -1) {
                    186:                errno = EBADF;
                    187:                return -1;
                    188:        }
                    189: 
                    190:        pfd.fd = inp.fd;
                    191:        pfd.events = POLLIN;
                    192:        pfd.revents = 0;
                    193:        int r = poll(&pfd, 1, 0);
                    194:        return r;
                    195: }
                    196: 
                    197: // ファイルディスクリプタから FILE* を開く
                    198: void
                    199: Console::FDOpen()
                    200: {
                    201:        inp.file = fdopen(inp.fd, "r");
                    202:        out.file = fdopen(out.fd, "w");
                    203: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.