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

1.1       root        1: //
                      2: // nono
1.1.1.2   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
                      7: #include "console.h"
                      8: #include "mystring.h"
                      9: #include <poll.h>
                     10: 
                     11: //
                     12: // コンソール基本クラス
                     13: //
                     14: 
                     15: // コンストラクタ
                     16: Console::Console()
                     17: {
                     18:        inp.fd = -1;
                     19:        inp.file = NULL;
                     20:        out.fd = -1;
                     21:        out.file = NULL;
                     22: }
                     23: 
                     24: #if defined(HAVE_HISTEDIT_H)
                     25: // プロンプト文字列を返す (editline からコールバックで呼ばれる)
                     26: static char *
                     27: prompt_callback(EditLine *e)
                     28: {
                     29:        void *p;
                     30: 
                     31:        // CLIENTDATA に (char *)prompt が入っている
                     32:        el_get(e, EL_CLIENTDATA, &p);
                     33:        return (char *)p;
                     34: }
                     35: #endif
                     36: 
                     37: // EditLine を初期化する。p はプロンプト文字列。
                     38: void
                     39: Console::InitEditLine(const char *prompt_arg)
                     40: {
                     41:        // editline(3) を使わない場合は、プロンプトを自前で出すために覚えておく。
                     42:        // 使う場合には代入が無駄になるけど気にしない。
                     43:        prompt = prompt_arg;
                     44: 
                     45: #if defined(HAVE_HISTEDIT_H)
                     46:        if (use_editline) {
                     47:                // ヒストリの初期化
                     48:                hist = history_init();
                     49:                history(hist, &hev, H_SETSIZE, 100);
                     50: 
                     51:                // editline の初期化、設定
                     52:                el = el_init(getprogname(), inp.file, out.file, stderr);
                     53:                if (el == NULL) {
                     54:                        // どうすべ
                     55:                        warnx("el_init failed");
                     56:                        return;
                     57:                }
                     58:                // CLIENTDATA にプロンプトを入れておく
                     59:                el_set(el, EL_CLIENTDATA, prompt_arg);
                     60:                el_set(el, EL_PROMPT, prompt_callback);
                     61:                el_set(el, EL_EDITOR, "emacs");
                     62:                el_set(el, EL_HIST, history, hist);
                     63:        }
                     64: #endif
                     65: }
                     66: 
                     67: // クローズ
                     68: void
                     69: Console::Close()
                     70: {
                     71: #if defined(HAVE_HISTEDIT_H)
                     72:        if (use_editline) {
                     73:                el_end(el);
                     74:        }
                     75: #endif
                     76: 
                     77:        // fclose は fd も閉じる。
                     78:        if (inp.file != NULL) {
                     79:                fclose(inp.file);
                     80:                inp.file = NULL;
                     81:                inp.fd = -1;
                     82:        }
                     83:        if (out.file != NULL) {
                     84:                fclose(out.file);
                     85:                out.file = NULL;
                     86:                out.fd = -1;
                     87:        }
                     88: }
                     89: 
                     90: // プロンプトを出力する
                     91: void
                     92: Console::Prompt()
                     93: {
                     94: #if defined(HAVE_HISTEDIT_H)
                     95:        if (use_editline) {
                     96:                // editline(3) を使う場合は Gets() がプロンプトを出すので
                     97:                // ここでは何もしない。
                     98:        } else
                     99: #endif
                    100:        {
                    101:                // そうでない場合は、ここで自前でプロンプトを出す。
                    102:                Print("%s", prompt);
                    103:                Flush();
                    104:        }
                    105: }
                    106: 
                    107: // 出力
                    108: void
                    109: Console::Print(const char *fmt, ...)
                    110: {
                    111:        va_list ap;
                    112: 
                    113:        va_start(ap, fmt);
                    114:        vfprintf(out.file, fmt, ap);
                    115:        va_end(ap);
                    116: }
                    117: 
                    118: // 出力フラッシュ
                    119: void
                    120: Console::Flush()
                    121: {
                    122:        fflush(out.file);
                    123: }
                    124: 
                    125: // 1行出力
                    126: bool
                    127: Console::Gets(std::string& buf)
                    128: {
                    129: #if defined(HAVE_HISTEDIT_H)
                    130:        if (use_editline)
                    131:                return Gets_editline(buf);
                    132:        else
                    133: #endif
                    134:                return Gets_normal(buf);
                    135: }
                    136: 
                    137: #if defined(HAVE_HISTEDIT_H)
                    138: // 1行出力 (Editline 版)
                    139: bool
                    140: Console::Gets_editline(std::string& buf)
                    141: {
                    142:        const char *p;
                    143:        int num;
                    144: 
                    145:        p = el_gets(el, &num);
                    146:        if (p == NULL || num < 1) {
                    147:                // EOF
                    148:                return false;
                    149:        }
                    150:        // 呼び出し元へは EditLine から入力されたものをそのまま返す
                    151:        buf = std::string(p);
                    152: 
                    153:        // ヒストリに記録
                    154:        // の前に前後の空白は取り除いておく
1.1.1.3 ! root      155:        std::string hbuf = string_trim(buf);
1.1       root      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
1.1.1.2   root      181: Console::Poll(int msec)
1.1       root      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;
1.1.1.2   root      193:        int r = poll(&pfd, 1, msec);
1.1       root      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.