diff --git a/src/roflcat.cpp b/src/roflcat.cpp index 254519e..4ae6476 100644 --- a/src/roflcat.cpp +++ b/src/roflcat.cpp @@ -33,6 +33,7 @@ #include //size_t #include //std::chrono::* #include //srand +#include //char_traits constexpr const char version_string[] = "roflcat version 1.0.4"; @@ -134,59 +135,70 @@ void nonprinting_notation(int in, char* dest){ } } +FILE* open_file(const char* file, const char* mode){ + FILE* fp = fopen(file, mode); + if(!fp){ + fflush(stdout); + fprintf(stderr, "Unable to open file %s\n", file); + } + return fp; +} + +template +inline void do_stdin(Printer&& p, Func&& f){ + for(T in;(in = f(stdin)) != std::char_traits::eof();){ + p.print(in); + if(in == '\n') + p.reset(); + } + clearerr(stdin); +} //Use the given type of printer to output the contents of files and/or stdin template int real_print_files(const cmd_args& args){ int ret = 0; Printer p(args); - for(size_t i = 0;i < args.filenames.size();++i){ - if(!strcmp(args.filenames[i], "-")){ //stdin - - if(args.treatbinary){ - //Don't check if buf is empty because that's not how GNU cat handles Ctrl+D in middle of line - for(int in;(in = fgetc(stdin)) != WEOF;){ - p.print(static_cast(in)); - if(in == L'\n') //Only reset on newline to save print overhead - p.reset(); + if(args.treatbinary){ //binary files + for(size_t i = 0;i < args.filenames.size();++i){ + if(!strcmp(args.filenames[i], "-")){ //stdin + do_stdin(p, fgetc); + }else{ //everything besides stdin + FILE* fp = open_file(args.filenames[i], "rb"); + if(!fp){ + ret = 2; + continue; } - }else{ - for(wint_t in;(in = fgetwc(stdin)) != WEOF;){ - p.print(static_cast(in)); - if(in == L'\n') - p.reset(); - } - } - clearerr(stdin); - }else{ //everything besides stdin - - FILE* fp = fopen(args.filenames[i], "r"); - if(!fp){ - fflush(stdout); //force color update before error - fprintf(stderr, "Unable to open file %s\n", args.filenames[i]); - ret = 2; - continue; - } - if(args.treatbinary){ if(args.nonprinting){ - for(int in;(in = fgetc(fp)) != WEOF;){ + for(char in;(in = fgetc(fp)) != EOF;){ char tmp[5]; nonprinting_notation(in, tmp); p.print(tmp); } }else{ - for(int in;(in = fgetc(fp)) != WEOF;) - p.print(static_cast(in)); + for(char in;(in = fgetc(fp)) != EOF;) + p.print(in); } - }else{ - //set to wide character mode before anything - fwide(fp, 1); - for(wint_t in;(in = fgetwc(fp)) != WEOF;) - p.print(static_cast(in)); + p.reset(); + fclose(fp); + } + } + }else{ //non binary files + for(size_t i = 0;i < args.filenames.size();++i){ + if(!strcmp(args.filenames[i], "-")){ + do_stdin(p, fgetwc); + }else{ + FILE* fp = open_file(args.filenames[i], "r"); + if(!fp){ + ret = 2; + continue; + } + for(wchar_t in;(in = fgetwc(fp)) != WEOF;){ + p.print(in); + } + p.reset(); + fclose(fp); } - p.reset(); - fclose(fp); - } } p.reset();