📄 a_more.cpp
字号:
/* Copyright is licensed under GNU LGPL. by I.J.Wang 2005 Simulate shell command more Read data from the given file and write to stdout Build: make a_more Bug: standard input device can't be tty e.g. "cat ttt | a_more" fails*/#include "../src/wy_uty.h"#include "../src/wyterminal.h"#include "../src/wytermios.h"#include "../src/wy__rdbuf.h"#include <typeinfo>#include <new>// Console tty i/o (raw mode terminal)//class RawTerm : public WyTerminal { WyTermios _ptio; // previous termio state public: RawTerm() {}; RawTerm(const char*, int); ~RawTerm(); WyRet getch(char& ch); RawTerm* _alloc(WyRet& r) const;} static mtty("/dev/tty",O_RDONLY);RawTerm::RawTerm(const char* pathname, int flag) : WyTerminal(){ WyRet r; if((r=WyTerminal::reset(pathname,flag))!=Ok) { WY_THROW( WyTerminal::Reply(r) ); } if((r=WyTerminal::flush(TCIFLUSH))!=Ok) { WY_THROW( WyTerminal::Reply(r) ); } if((r=WyTerminal::getattr(_ptio))!=Ok) { WY_THROW( WyTerminal::Reply(r) ); } try { // Set the terminal mode this program uses // WyTermios ntio(_ptio); ntio.iflag_and(~BRKINT); ntio.lflag_and(~(ICANON| ECHO| ISIG| TOSTOP)); ntio.cc_VMIN(1); ntio.cc_VTIME(0); if((r=WyTerminal::setattr(ntio,TCSANOW))!=Ok) { WY_THROW( WyTerminal::Reply(r) ); } // read back check WyTermios tmptio; if((r=WyTerminal::getattr(tmptio))!=Ok) { WY_THROW( WyTerminal::Reply(r) ); } if(tmptio!=ntio) { Wy::cerr << "Set termios is not fully accepted\n"; } } catch(const WyTermios::Reply& e) { WY_THROW( WyTerminal::Reply(r) ); };};RawTerm::~RawTerm(){ WyTerminal::flush(TCIFLUSH); WyTerminal::setattr(_ptio,TCSANOW); WyTerminal::reset();};// Get one char from terminal//WyRet RawTerm::getch(char& ch){ WyRet r; size_t n; if((r=WyTerminal::read(&ch,sizeof(ch),n))!=Ok) { WY_RETURN(r); } if(n==0) { WY_RETURN(Wym_EPIPE); } return(Ok);};// libwy.a requires deriving classes (of WyByteFlow) reimplement this member//RawTerm* RawTerm::_alloc(WyRet& r) consttry { if(typeid(*this)!=typeid(WyTerminal)) { r=Wym_ENOSYS; WY_HERE(r); // _alloc not overridden return(NULL); } RawTerm* p= new(std::nothrow) RawTerm(); if(p==NULL) { r=Wym_ENOMEM; WY_HERE(r); } else { r=Ok; } return(p);}catch(const WyTerminal::Reply& e) { r=e; WY_HERE(r); return(NULL);};// [Syn] 'more' for bf//// Note: Virtical lines of page are fixed to 20 (for simplicity)//static WyRet more_file(WyByteFlow & bf) throw()try { const int PageLines=20; const size_t MaxLineLength=2048; WyRet r; size_t file_lines=0; size_t ln_wr(PageLines); // lines to write (initially one page) Wy__RdBuf inbf(&bf); WyCSeg lseg; // loop for each line for(size_t lcnt=0; ;) { if((r=inbf.getdata(lseg,MaxLineLength,'\n'))!=Ok) { WY_RETURN(r); } if(lseg.size()==0) { break; // eof } // count lines if(lseg.back()=='\n') { ++lcnt; ++file_lines; } else { if(lseg.size()!=MaxLineLength) { ++lcnt; ++file_lines; } } Wy::cout << lseg; // Check keyboard input at each page pause // if(lcnt>=ln_wr) { lcnt=0; // reset lcnt char rply; if((r=mtty.getch(rply))!=Ok) { WY_RETURN(r); } if((rply=='q')||(rply=='Q')) { return(Ok); } ln_wr= (rply=='\n')? 1:PageLines; // lines to write before next pause } } return(Ok);}catch(const WyTerminal::Reply&) { throw;}catch(const WyStr::Reply& e) { WY_RETURN(e);}catch(const WyByteFlow::Reply& e) { WY_RETURN(e);}catch(const WyRet& e) { WY_TERMINATE("unexpected Reply");}catch(...) { WY_TERMINATE("unknown throw type");};static const char* syntax= " Read data from the given file (stdin assumed if not specified) and\n" " write to stdout\n\n" " [Usage]$./a_more [file]\n" " file= file to do the more.\n";int main(int argc, char* argv[])try { WyRet r; if(argc==1) { // do more for Wy::cin //if((r=more_file(Wy::cin))!=Ok) { // WY_THROW(r); //} Wy::cerr << "parameter required\n"; return(-1); } else if(argc==2) { WyByteFlow bf(argv[1],O_RDONLY); if((r=more_file(bf))!=Ok) { throw(r); } } else { Wy::cout << syntax; return(-1); } return(0);}catch(const WyRet& e) { if(e!=Ok) { Wy::cerr << Wy::wrd(e) << '\n'; } return e->c_repcode();}catch(...) { Wy::cerr << "main caught(...)\n"; return(-1);};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -