1 #include <stdio.h>
2 #include <unistd.h>
3 #include <string.h>
4 #include <stdlib.h>
5 
6 #undef  LF
7 #undef  CR
8 
9 #define LF '\n'    /* Unix line ender      = ctrl-J = ASCII 0x0A */
10 #define CR '\r'    /* Microsoft line ender = ctrl-M = ASCII 0x0D */
11 
12 /*----------------------------------------------------------------------------*/
13 /*! Like system fgets(), but allows LF, CR, CR+LF, and LF+CR as end of line
14     markers.  Converts all of them to a single LF character, so that the
15     results are as if the input was an honest-to-Allah Unix file, instead
16     of some bastard child of Microsoft.  (Not that I have any prejudices.)
17 *//*--------------------------------------------------------------------------*/
18 
afni_fgets(char * buf,int nbuf,FILE * fp)19 char * afni_fgets( char *buf , int nbuf , FILE *fp )
20 {
21    int nin=0 , cin , qin ;
22 
23    if( buf == NULL || nbuf <= 1 || fp == NULL ) return NULL ;
24 
25    /* use system fgets() if ordered to, or if reading from a terminal */
26 
27    if( isatty(fileno(fp)) ) return fgets(buf,nbuf,fp) ;
28 
29    /* read characters one at a time and process them */
30 
31    do{
32      cin = getc(fp) ;           /* read next char */
33      if( cin == EOF ) break ;   /* nuthin ==> quit */
34 
35      /* copy input to output, but convert CR to LF */
36 
37      if( cin != CR ) buf[nin++] = (char)cin ;
38      else            buf[nin++] = (char)LF  ;  /* Microsoft coverup */
39 
40      if( cin == CR || cin == LF ){  /* end of line */
41        qin = getc(fp) ;             /* check next character */
42                                     /* if have a CR+LF or LF+CR combo, */
43                                     /* skip next char, otherwise push it back */
44        if( (cin==CR && qin!=LF) || (cin ==LF && qin!= CR) ) ungetc(qin,fp) ;
45        break ;                      /* in either case, am done with loop */
46      }
47    } while( nin < nbuf-1 ) ;    /* don't run off the end of the world */
48    if (nin >= nbuf -1) {
49       fprintf(stderr,"** ERROR: Line too long for buffer of %d chars.\n", nbuf);
50       return NULL;
51    }
52    if( nin == 0 ) return NULL ; /* nothing was read */
53 
54    buf[nin] = '\0' ;            /* Schwarznegger the string */
55    return buf ;
56 }
57 
58 /*----------------------------------------------------------------------------*/
59 
60 #undef  NBUF
61 #define NBUF 131072
62 static char buf[NBUF] ;
63 
main(int argc,char * argv[])64 int main( int argc , char *argv[] )
65 {
66    char *bb ; FILE *fp ; int iarg=1 ;
67 
68    if( argc == 1 || strcmp(argv[1],"-help") == 0 ){
69      printf("\n"
70             "mycat fileA ...\n"
71             "\n"
72             "Copies text files to stdout, like the system 'cat', but with changes:\n"
73             "* To copy stdin, you must use '-' for a filename\n"
74             "* Microsoft end-of-line characters are changed to Unix format\n"
75             "* Because of the above, mycat should only be used with text files!\n"
76             "\n"
77      ) ;
78      exit(0) ;
79    }
80 
81    while( iarg < argc ){
82 
83      if( strcmp(argv[iarg],"-") == 0 ){
84        fp = stdin ; iarg++ ;
85      } else {
86        fp = fopen(argv[iarg++],"r") ; if( fp == NULL ) continue ;
87      }
88 
89      while(1){
90        bb = afni_fgets( buf , NBUF , fp ) ;
91        if( bb == NULL ) break ;
92        fwrite(buf,1,strlen(buf),stdout) ;
93      }
94 
95      if( fp != stdin ) fclose(fp) ;
96 
97    }
98 
99    exit(0) ;
100 }
101