X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/59ecf21e36b2332f6adf2a568ef555283d8c119a..64e5fa9a495e388c922157b9a616204c299f5e05:/lunaix-os/hal/term/lcntls/lcntl.c diff --git a/lunaix-os/hal/term/lcntls/lcntl.c b/lunaix-os/hal/term/lcntls/lcntl.c index 4359830..fdaf244 100644 --- a/lunaix-os/hal/term/lcntls/lcntl.c +++ b/lunaix-os/hal/term/lcntls/lcntl.c @@ -21,25 +21,7 @@ raise_sig(struct term* at_term, struct linebuffer* lbuf, int sig) lbuf->sflags |= LSTATE_SIGRAISE; } -static inline int -lcntl_invoke_slaves(struct term* tdev, struct linebuffer* lbuf, char c) -{ - int allow_more = 0; - struct term_lcntl *lcntl, *n; - llist_for_each(lcntl, n, &tdev->lcntl_stack, lcntls) - { - allow_more = lcntl->process_and_put(tdev, lbuf, c); - if (!allow_more) { - break; - } - - line_flip(lbuf); - } - - return allow_more; -} - -static inline int optimize("ipa-cp-clone") +static inline int must_inline optimize("-fipa-cp-clone") lcntl_transform_seq(struct term* tdev, struct linebuffer* lbuf, bool out) { struct rbuffer* raw = lbuf->current; @@ -50,7 +32,9 @@ lcntl_transform_seq(struct term* tdev, struct linebuffer* lbuf, bool out) _lf = tdev->lflags; int allow_more = 1, latest_eol = cooked->ptr; char c; - bool should_flush = false; + + int (*lcntl_slave_put)(struct term*, struct linebuffer*, char) = + tdev->lcntl->process_and_put; #define EOL tdev->cc[_VEOL] #define EOF tdev->cc[_VEOF] @@ -72,20 +56,20 @@ lcntl_transform_seq(struct term* tdev, struct linebuffer* lbuf, bool out) if (c == '\r' && ((_if & _ICRNL) || (_of & _OCRNL))) { c = '\n'; } else if (c == '\n') { - if ((_if & _INLCR) || (_of & (_ONLRET | _ONLCR))) { + if ((_if & _INLCR) || (_of & (_ONLRET))) { c = '\r'; } } if (c == '\0') { + if ((_if & _IGNBRK)) { + continue; + } + if ((_if & _BRKINT)) { raise_sig(tdev, lbuf, SIGINT); break; } - - if ((_if & _IGNBRK)) { - continue; - } } if ('a' <= c && c <= 'z') { @@ -101,18 +85,16 @@ lcntl_transform_seq(struct term* tdev, struct linebuffer* lbuf, bool out) if (!out && (_lf & _ECHONL)) { rbuffer_put(output, c); } - should_flush = true; } if (out) { - goto put_char; + goto do_out; } // For input procesing if (c == '\n' || c == EOL) { lbuf->sflags |= LSTATE_EOL; - goto keep; } else if (c == EOF) { lbuf->sflags |= LSTATE_EOF; rbuffer_clear(raw); @@ -126,37 +108,50 @@ lcntl_transform_seq(struct term* tdev, struct linebuffer* lbuf, bool out) raise_sig(tdev, lbuf, SIGSTOP); } else if (c == ERASE) { rbuffer_erase(cooked); + } else if (c == KILL) { + // TODO shrink the rbuffer } else { goto keep; } + if ((_lf & _ECHOE) && c == ERASE) { + rbuffer_put(output, '\x8'); + rbuffer_put(output, ' '); + rbuffer_put(output, '\x8'); + } + if ((_lf & _ECHOK) && c == KILL) { + rbuffer_put(output, c); + rbuffer_put(output, '\n'); + } + continue; keep: if ((_lf & _ECHO)) { rbuffer_put(output, c); } - if ((_lf & _ECHOE) && c == ERASE) { - rbuffer_erase(output); - } - if ((_lf & _ECHOK) && c == KILL) { - rbuffer_put(output, c); - rbuffer_put(output, '\n'); + + goto put_char; + + do_out: + if (c == '\n' && (_of & _ONLCR)) { + rbuffer_put(cooked, '\r'); } put_char: - allow_more = rbuffer_put(cooked, c); - } - - if (out || (_lf & _IEXTEN)) { - line_flip(lbuf); - lcntl_invoke_slaves(tdev, lbuf, c); + if (!out && (_lf & _IEXTEN) && lcntl_slave_put) { + allow_more = lcntl_slave_put(tdev, lbuf, c); + } else { + allow_more = rbuffer_put(cooked, c); + } } - if (should_flush && !(_lf & _NOFLSH)) { + if (!rbuffer_empty(output) && !(_lf & _NOFLSH)) { term_flush(tdev); } + line_flip(lbuf); + return i; } @@ -169,5 +164,5 @@ lcntl_transform_inseq(struct term* tdev) int lcntl_transform_outseq(struct term* tdev) { - return lcntl_transform_seq(tdev, &tdev->line_in, true); + return lcntl_transform_seq(tdev, &tdev->line_out, true); } \ No newline at end of file