SHARE
TWEET

Untitled

a guest Nov 9th, 2019 88 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <getopt.h>
  4. #include <errno.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <stdarg.h>
  8. #include <fcntl.h>
  9. #include <unistd.h>
  10. #include <string.h>
  11. #include "kitten.h"
  12.  
  13. #define ERR_SIZE 256
  14. extern int errno;
  15.  
  16. char err_buf[ERR_SIZE];
  17.  
  18. int main ( int argc, char* argv[])
  19. {
  20.         struct global_opt opt = {
  21.                                         .number_nonblank = false, .number = false,
  22.                                         .squeeze_blank = false, .show_nonprinting = false,
  23.                                         .show_ends = false, .show_tabs = false
  24.                                 };
  25.         bool ok;
  26.         int c;
  27.  
  28.         while (( c = getopt_long(argc, argv, "bnsvET", NULL, NULL)) != -1)
  29.         {
  30.                 switch(c)
  31.                 {
  32.                         case 'b':
  33.                                 opt.number = true;
  34.                                 opt.number_nonblank = true;
  35.                                 break;
  36.                         case 'n':
  37.                                 opt.number = true;
  38.                                 break;
  39.                         case 's':
  40.                                 opt.squeeze_blank = true;
  41.                                 break;
  42.                         case 'v':
  43.                                 opt.show_nonprinting = true;
  44.                                 break;
  45.                         case 'E':
  46.                                 opt.show_ends = true;
  47.                                 break;
  48.                         case 'T':
  49.                                 opt.show_tabs = true;
  50.                                 break;
  51.                         default:
  52.                                 return -1;
  53.  
  54.                 }
  55.         }
  56.  
  57.         char *file = "-";
  58.         int argid = optind;
  59.         int input_desc;
  60.  
  61.         do
  62.         {
  63.                 if( argid < argc)
  64.                         file = argv[argid];
  65.                 if( STREQ(file, "-"))
  66.                         input_desc = STDIN_FILENO;
  67.                 else
  68.                 {
  69.                         input_desc = open (file, O_RDONLY);
  70.                         if (input_desc < 0)
  71.                         {
  72.                                 strncat(err_buf, "Cannot open ", 13);
  73.                                 strncat(err_buf, file, strlen(file));
  74.                                 strncat(err_buf, ": ", 2);
  75.                                 strerror_r (errno,err_buf+13+strlen(file), ERR_SIZE);
  76.                                 strncat(err_buf, "\n", 2);
  77.                                 write ( STDOUT_FILENO, err_buf, ERR_SIZE);
  78.                                 continue;
  79.                         }
  80.                 }
  81.                 if (! (opt.number || opt.show_ends || opt.show_nonprinting
  82.                         || opt.show_tabs || opt.squeeze_blank))
  83.                         ok &= simple_cat(input_desc);
  84.                 else ok &= cat_opt ( &opt, input_desc);
  85.         }
  86.         while ( ++argid < argc);
  87.  
  88.  
  89.  
  90.  
  91.  
  92.         return ok ? EXIT_SUCCESS : EXIT_FAILURE;
  93. }
  94.  
  95. static  char line_buf[ LINE_COUNTER] =
  96. {
  97.         ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0', '\t', '\0'
  98. };
  99. static char* num_print = line_buf + LINE_COUNTER - 6;
  100.  
  101. void next_line_num (void)
  102. {
  103.         static char* num_start = line_buf + LINE_COUNTER - 3;
  104.         char* endp = line_buf + LINE_COUNTER - 3;
  105.  
  106.         do
  107.         {
  108.                 if( (*endp)++ < '9')
  109.                         return;
  110.                 *endp-- = '0';
  111.         } while ( endp >= num_start);
  112.         if (num_start > line_buf)
  113.                 *--num_start = '1';
  114.         else
  115.                 *line_buf = '>';
  116.  
  117.         if(num_start < num_print)
  118.                 num_print--;
  119. }
  120.  
  121. bool simple_cat(int input_desc)
  122. {
  123.         char buf[BUF_SIZE] = {0};
  124.         int char_read;
  125.  
  126.         while ( true )
  127.         {
  128.                 char_read = read ( input_desc, buf, BUF_SIZE);
  129.  
  130.                 if( char_read == -1 )
  131.                 {
  132.                         strerror_r (errno,err_buf, ERR_SIZE);
  133.                         strncat(err_buf, "\n", 2);
  134.                         write ( STDOUT_FILENO, err_buf, ERR_SIZE);
  135.                         return false;
  136.                 }
  137.  
  138.                 if ( char_read == 0 )
  139.                         return true;
  140.  
  141.                 {
  142.                         int n = char_read;
  143.                         if( write (STDOUT_FILENO, buf, n) != n )
  144.                         {
  145.                                 strerror_r (errno,err_buf, ERR_SIZE);
  146.                                 strncat(err_buf, "\n", 2);
  147.                                 write ( STDOUT_FILENO, err_buf, ERR_SIZE);
  148.                         }
  149.                 }
  150.  
  151.         }
  152.  
  153. }
  154.  
  155. static inline void write_remain ( char* outbuf, char** bpout)
  156. {
  157.         int n_write = *bpout - outbuf;
  158.  
  159.         if ( n_write > 0)
  160.         {
  161.                 if(write (STDOUT_FILENO, outbuf, n_write) != n_write)
  162.                 {
  163.                         strerror_r (errno,err_buf, ERR_SIZE);
  164.                         strncat(err_buf, "\n", 2);
  165.                         write ( STDOUT_FILENO, err_buf, ERR_SIZE);
  166.                 }
  167.                 *bpout = outbuf;
  168.         }
  169. }
  170.  
  171. bool cat_opt( struct global_opt* p_opt, int input_desc)
  172. {
  173.         char inbuf [BUF_SIZE];
  174.         char outbuf [2*BUF_SIZE];
  175.  
  176.         int newlines = 0;
  177.  
  178.         unsigned char ch;
  179.  
  180.         char *bpin;
  181.  
  182.         char *eob;
  183.  
  184.         char *bpout;
  185.  
  186.         int n_read = 1;
  187.  
  188.         eob = inbuf;
  189.         bpin = eob + 1;
  190.  
  191.         bpout = outbuf;
  192.  
  193.         while (n_read != 0)
  194.         {
  195.                 do
  196.                 {
  197.                         if (outbuf + n_read <= bpout)
  198.                         {
  199.                                 int n_write = bpout - outbuf;
  200.                                 if( write ( STDOUT_FILENO, outbuf, n_write) != n_write)
  201.                                 {
  202.                                         strerror_r (errno,err_buf, ERR_SIZE);
  203.                                         strncat(err_buf, "\n", 2);
  204.                                         write ( STDOUT_FILENO, err_buf, ERR_SIZE);
  205.                                 }
  206.                                 bpout = outbuf;
  207.                         }
  208.  
  209.                         if ( bpin > eob)
  210.                         {
  211.                                 n_read = read ( input_desc, inbuf, BUF_SIZE);
  212.                                 if ( n_read == -1)
  213.                                 {
  214.                                         strerror_r (errno,err_buf, ERR_SIZE);
  215.                                         strncat(err_buf, "\n", 2);
  216.                                         write ( STDOUT_FILENO, err_buf, ERR_SIZE);
  217.  
  218.                                         write_remain (outbuf, &bpout);
  219.                                         return false;
  220.                                 }
  221.  
  222.                                 if ( n_read == 0)
  223.                                 {
  224.                                         write_remain (outbuf, &bpout);
  225.                                         return true;
  226.                                 }
  227.  
  228.                                 bpin = inbuf;
  229.                                 eob = bpin + n_read;
  230.                                 *eob = '\n';
  231.  
  232.                         }
  233.                         else
  234.                         {
  235.                                 if( ++newlines > 0)
  236.                                 {
  237.                                         if( newlines >= 2)
  238.                                                 if( p_opt -> squeeze_blank)
  239.                                                 {
  240.                                                         ch = *bpin++;
  241.                                                         continue;
  242.                                                 }
  243.  
  244.                                         if(p_opt -> number && !(p_opt -> number_nonblank))
  245.                                         {
  246.                                                 next_line_num();
  247.                                                 bpout = stpcpy(bpout, num_print);
  248.                                         }
  249.                                 }
  250.  
  251.                                 if (p_opt -> show_ends)
  252.                                 *bpout++ = '$';
  253.  
  254.                                 *bpout++ = '\n';
  255.                         }
  256.  
  257.                         ch = *bpin++;
  258.  
  259.                 } while ( ch == '\n');
  260.  
  261.  
  262.                 if( newlines > -1 && p_opt -> number)
  263.                 {
  264.                         next_line_num();
  265.                         bpout = stpcpy (bpout, num_print);
  266.                 }
  267.  
  268.  
  269.                 while (bpout < outbuf + 2*BUF_SIZE  )
  270.                 {
  271.                         if(ch == '\t' && p_opt -> show_tabs)
  272.                         {
  273.                                 *bpout++ = '^';
  274.                                 *bpout++ = 'I';
  275.                         }
  276.                         else if ( ch != '\n' )
  277.                                 *bpout++ = ch;
  278.                         else
  279.                         {
  280.                                 newlines = -1;
  281.                                 break;
  282.  
  283.                         }
  284.  
  285.                         ch = *bpin++;
  286.                 }
  287.         }
  288.         return true;
  289. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top