{"id":377,"date":"2011-04-01T00:07:09","date_gmt":"2011-04-01T07:07:09","guid":{"rendered":"http:\/\/blog.mezeske.com\/?p=377"},"modified":"2011-04-01T10:52:59","modified_gmt":"2011-04-01T17:52:59","slug":"introducing-cppsh-a-bash-like-shell-with-c-syntax","status":"publish","type":"post","link":"http:\/\/blog.mezeske.com\/?p=377","title":{"rendered":"Introducing cppsh:  A bash-Like Shell with C++ Syntax"},"content":{"rendered":"<p><img loading=\"lazy\" src=\"http:\/\/blog.mezeske.com\/wp-content\/uploads\/2011\/03\/cppsh-logo.png\" alt=\"cppsh\" title=\"cppsh-logo\" width=\"307\" height=\"328\" class=\"alignleft size-full wp-image-378\" srcset=\"http:\/\/blog.mezeske.com\/wp-content\/uploads\/2011\/03\/cppsh-logo.png 307w, http:\/\/blog.mezeske.com\/wp-content\/uploads\/2011\/03\/cppsh-logo-280x300.png 280w\" sizes=\"(max-width: 307px) 100vw, 307px\"><\/p>\n<p>It\u2019s been a long time in the mak\u00ading, but I am proud to announce the first beta release of cppsh, the bash-like shell specif\u00adi\u00adcal\u00adly designed for those engi\u00adneers who find them\u00adselves most com\u00adfort\u00adable at the reins of a C++ com\u00adpil\u00ader.  The best fea\u00adtures from both bash and the C++ lan\u00adguage come togeth\u00ader in cppsh to make you a more pro\u00adduc\u00adtive shell user.  Some of the most impor\u00adtant fea\u00adtures of cppsh include:<\/p>\n<h4>File Iterators<\/h4>\n<p>File iter\u00ada\u00adtors allow you to tra\u00adverse the files in your work\u00ading direc\u00adto\u00adry using the con\u00adve\u00adnient C++ <span class=\"caps\">STL<\/span> iter\u00ada\u00adtor syntax:<\/p>\n<div class=\"codecolorer-container cpp twitlight\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"cpp codecolorer\">cppsh<span class=\"sy1\">&gt;<\/span><br>\n<span class=\"kw1\">for<\/span> <span class=\"br0\">(<\/span> cppsh<span class=\"sy4\">::<\/span><span class=\"me2\">file<\/span><span class=\"sy4\">::<\/span><span class=\"me2\">const_iterator<\/span> file_iterator <span class=\"sy1\">=<\/span><br>\n&nbsp; &nbsp; &nbsp; &nbsp; cppsh<span class=\"sy4\">::<\/span><span class=\"me2\">list_cwd<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>.<span class=\"me1\">begin<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span><br>\n&nbsp; &nbsp; &nbsp; file_iterator <span class=\"sy3\">!<\/span><span class=\"sy1\">=<\/span> cppsh<span class=\"sy4\">::<\/span><span class=\"me2\">list_cwd<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>.<span class=\"me1\">end<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span><br>\n&nbsp; &nbsp; &nbsp; <span class=\"sy2\">++<\/span>file_iterator <span class=\"br0\">)<\/span><br>\n<span class=\"br0\">{<\/span><br>\n&nbsp; <span class=\"kw4\">typedef<\/span> cppsh<span class=\"sy4\">::<\/span><span class=\"me2\">command_line_entry<\/span><span class=\"sy1\">&lt;<\/span>std<span class=\"sy4\">::<\/span><span class=\"me2\">string<\/span><span class=\"sy1\">&gt;<\/span> entry<span class=\"sy4\">;<\/span><br>\n&nbsp; std<span class=\"sy4\">::<\/span><span class=\"me2\">vector<\/span><span class=\"sy1\">&lt;<\/span>entry<span class=\"sy1\">&gt;<\/span> command_line<span class=\"sy4\">;<\/span><br>\n&nbsp; command_line.<span class=\"me1\">push_back<\/span><span class=\"br0\">(<\/span> entry<span class=\"br0\">(<\/span> <span class=\"st0\">\"mv\"<\/span> <span class=\"br0\">)<\/span> <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span><br>\n&nbsp; command_line.<span class=\"me1\">push_back<\/span><span class=\"br0\">(<\/span> entry<span class=\"br0\">(<\/span> <span class=\"st0\">\"-f\"<\/span> <span class=\"br0\">)<\/span> <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span><br>\n&nbsp; command_line.<span class=\"me1\">push_back<\/span><span class=\"br0\">(<\/span> entry<span class=\"br0\">(<\/span> <span class=\"sy2\">*<\/span>file_iterator <span class=\"br0\">)<\/span> <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span><br>\n&nbsp; command_line.<span class=\"me1\">push_back<\/span><span class=\"br0\">(<\/span> entry<span class=\"br0\">(<\/span> <span class=\"sy2\">*<\/span>file_iterator <span class=\"sy2\">+<\/span> <span class=\"st0\">\".bak\"<\/span> <span class=\"br0\">)<\/span> <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span><br>\n&nbsp; cppsh<span class=\"sy4\">::<\/span><span class=\"me2\">execute_command<\/span><span class=\"br0\">(<\/span> command_line, std<span class=\"sy4\">::<\/span><span class=\"kw3\">cout<\/span> <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span><br>\n<span class=\"br0\">}<\/span><\/div><\/div>\n<h4>Command Pipelines<\/h4>\n<p>Following the <span class=\"caps\">UNIX<\/span> tra\u00addi\u00adtion, cppsh makes it easy to feed the out\u00adput of one com\u00admand into anoth\u00ader command:<\/p>\n<div class=\"codecolorer-container cpp twitlight\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"cpp codecolorer\">cppsh<span class=\"sy1\">&gt;<\/span><br>\n<span class=\"kw4\">typedef<\/span> cppsh<span class=\"sy4\">::<\/span><span class=\"me2\">command_line_entry<\/span><span class=\"sy1\">&lt;<\/span>std<span class=\"sy4\">::<\/span><span class=\"me2\">string<\/span><span class=\"sy1\">&gt;<\/span> entry<span class=\"sy4\">;<\/span><br>\n<span class=\"kw4\">typedef<\/span> std<span class=\"sy4\">::<\/span><span class=\"me2\">vector<\/span><span class=\"sy1\">&lt;<\/span>entry<span class=\"sy1\">&gt;<\/span> command<span class=\"sy4\">;<\/span><br>\n<br>\ncommand cat_command<span class=\"sy4\">;<\/span><br>\ncat_command.<span class=\"me1\">push_back<\/span><span class=\"br0\">(<\/span> entry<span class=\"br0\">(<\/span> <span class=\"st0\">\"cat\"<\/span> <span class=\"br0\">)<\/span> <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span><br>\ncat_command.<span class=\"me1\">push_back<\/span><span class=\"br0\">(<\/span> entry<span class=\"br0\">(<\/span> <span class=\"st0\">\"datafile\"<\/span> <span class=\"br0\">)<\/span> <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span><br>\n<br>\ncommand sort_command<span class=\"sy4\">;<\/span><br>\nsort_command.<span class=\"me1\">push_back<\/span><span class=\"br0\">(<\/span> entry<span class=\"br0\">(<\/span> <span class=\"st0\">\"sort\"<\/span> <span class=\"br0\">)<\/span> <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span><br>\nsort_command.<span class=\"me1\">push_back<\/span><span class=\"br0\">(<\/span> entry<span class=\"br0\">(<\/span> <span class=\"st0\">\"--unique\"<\/span> <span class=\"br0\">)<\/span> <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span><br>\n<br>\ncommand wc_command<span class=\"sy4\">;<\/span><br>\nwc_command.<span class=\"me1\">push_back<\/span><span class=\"br0\">(<\/span> entry<span class=\"br0\">(<\/span> <span class=\"st0\">\"wc\"<\/span> <span class=\"br0\">)<\/span> <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span><br>\nwc_command.<span class=\"me1\">push_back<\/span><span class=\"br0\">(<\/span> entry<span class=\"br0\">(<\/span> <span class=\"st0\">\"--lines\"<\/span> <span class=\"br0\">)<\/span> <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span><br>\n<br>\ncppsh<span class=\"sy4\">::<\/span><span class=\"me2\">command_pipeline<\/span><span class=\"sy1\">&lt;<\/span>command<span class=\"sy1\">&gt;<\/span> pipeline<span class=\"sy4\">;<\/span><br>\npipeline.<span class=\"me1\">push_back<\/span><span class=\"br0\">(<\/span> cat_command <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span><br>\npipeline.<span class=\"me1\">push_back<\/span><span class=\"br0\">(<\/span> sort_command <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span><br>\npipeline.<span class=\"me1\">push_back<\/span><span class=\"br0\">(<\/span> wc_command <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span><br>\n<br>\npipeline.<span class=\"me1\">execute<\/span><span class=\"br0\">(<\/span> std<span class=\"sy4\">::<\/span><span class=\"kw3\">cout<\/span> <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span><\/div><\/div>\n<h4>Configurability<\/h4>\n<p>Like many <span class=\"caps\">UNIX<\/span> pro\u00adgrams, cppsh can be con\u00adfig\u00adured by edit\u00ading the .cpp\u00adshrc file in your home direc\u00adto\u00adry.  Unlike most <span class=\"caps\">UNIX<\/span> pro\u00adgrams, how\u00adev\u00ader, the .cpp\u00adshrc file is a full-fledged C++ head\u00ader file.  The .cpp\u00adshrc file is respon\u00adsi\u00adble for defin\u00ading the <em>cppsh_shell<\/em> type.  This is done by cre\u00adat\u00ading a user-spe\u00adcif\u00adic traits class and pass\u00ading it as a para\u00adme\u00adter <em>basic_cppsh_shell<\/em> template:<\/p>\n<div class=\"codecolorer-container cpp twitlight\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"cpp codecolorer\"><span class=\"co2\">#ifndef DOT_CPPSHRC<\/span><br>\n<span class=\"co2\">#define DOT_CPPSHRC<\/span><br>\n<br>\n<span class=\"co2\">#include &lt;cppsh\/basic_cppsh_shell.hpp&gt;<\/span><br>\n<br>\n<span class=\"kw2\">namespace<\/span> cppsh <span class=\"br0\">{<\/span><br>\n<br>\n<span class=\"kw4\">struct<\/span> user_cppsh_traits<br>\n<span class=\"br0\">{<\/span><br>\n&nbsp; &nbsp; <span class=\"kw4\">typedef<\/span> vi_editing_mode editing_mode_t<span class=\"sy4\">;<\/span><br>\n<br>\n&nbsp; &nbsp; <span class=\"kw4\">static<\/span> <span class=\"kw4\">const<\/span> <span class=\"kw4\">int<\/span> command_history <span class=\"sy1\">=<\/span> <span class=\"nu0\">1000<\/span><span class=\"sy4\">;<\/span><br>\n<br>\n&nbsp; &nbsp; <span class=\"kw4\">static<\/span> std<span class=\"sy4\">::<\/span><span class=\"me2\">string<\/span> prompt<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><br>\n&nbsp; &nbsp; <span class=\"br0\">{<\/span><br>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">return<\/span> <span class=\"st0\">\"cppsh&gt;\"<\/span><span class=\"sy4\">;<\/span><br>\n&nbsp; &nbsp; <span class=\"br0\">}<\/span><br>\n<span class=\"br0\">}<\/span><span class=\"sy4\">;<\/span><br>\n<br>\n<span class=\"kw4\">typedef<\/span> basic_cppsh_shell<span class=\"sy1\">&lt;<\/span>user_cppsh_traits<span class=\"sy1\">&gt;<\/span> cppsh_shell<span class=\"sy4\">;<\/span><br>\n<br>\n<span class=\"br0\">}<\/span> <span class=\"co1\">\/\/ namespace cppsh<\/span><br>\n<br>\n<span class=\"co2\">#endif \/\/ DOT_CPPSHRC<\/span><\/div><\/div>\n<h4>Extensibility<\/h4>\n<p>If you\u2019re a demand\u00ading user, you might find that the .cpp\u00adshrc file does not offer the pow\u00ader you need to cus\u00adtomize cppsh to fit your needs.  You\u2019re still in luck!  All of the fea\u00adtures described above (and more) are packed into only 412,011 lines of C++ code, so you can eas\u00adi\u00adly hack cppsh to fit your own needs.  Internally, cppsh makes exten\u00adsive use of tem\u00adplate metapro\u00adgram\u00adming, so the code is terse and easy to understand.<\/p>\n<h4>What are you waiting for?<\/h4>\n<p>Get start\u00aded with cppsh today \u2014 vis\u00adit the <a href=\"http:\/\/blog.mezeske.com\/?p=377\">project page<\/a> for down\u00adloads and doc\u00adu\u00admen\u00adta\u00adtion.  You\u2019ll be hap\u00adpy you&nbsp;did.<\/p>\n<p>\u2013 <em>The cppsh&nbsp;team<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>It\u2019s been a long time in the mak\u00ading, but I am proud to announce the first beta release of cppsh, the bash-like shell specif\u00adi\u00adcal\u00adly designed for those engi\u00adneers who find them\u00adselves most com\u00adfort\u00adable at the reins of a C++ com\u00adpil\u00ader. The best fea\u00adtures from both bash and the C++ lan\u00adguage come togeth\u00ader in cppsh&nbsp;to&nbsp;[\u2026]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"wp_typography_post_enhancements_disabled":false},"categories":[3],"tags":[4,5,23],"_links":{"self":[{"href":"http:\/\/blog.mezeske.com\/index.php?rest_route=\/wp\/v2\/posts\/377"}],"collection":[{"href":"http:\/\/blog.mezeske.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.mezeske.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.mezeske.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.mezeske.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=377"}],"version-history":[{"count":31,"href":"http:\/\/blog.mezeske.com\/index.php?rest_route=\/wp\/v2\/posts\/377\/revisions"}],"predecessor-version":[{"id":645,"href":"http:\/\/blog.mezeske.com\/index.php?rest_route=\/wp\/v2\/posts\/377\/revisions\/645"}],"wp:attachment":[{"href":"http:\/\/blog.mezeske.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=377"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.mezeske.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=377"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.mezeske.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=377"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}