Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

182 lines
4.2 KiB

  1. /*
  2. ** DETAB - replaces tabs with multiple spaces as appropriate
  3. ** tab width defaults to 8 but may be anything
  4. ** Steve Salisbury 1988-03-09 Wed
  5. **
  6. ** 1989 Aug 30 Wed -- arg parsing was wrong
  7. ** 1989 Nov 01 Wed 12:00 add selection of non-space fill character
  8. ** 1991 Jan 14 Mon 18:20 fix selection of non-space fill character
  9. ** 1991 Jan 17 Thu 12:00 change message every 4KB to every 16KB
  10. ** allow command line argument for input file
  11. ** do not use big output buffer if stdout=con
  12. **
  13. ** cl -G2s -Oaltr detab.c -o detab.exr -link slibcr libh /nod:slibce;
  14. ** cl detab -link slibcp libh /nod:slibce, detab;
  15. */
  16. #include <fcntl.h>
  17. #include <io.h>
  18. #include <stdio.h>
  19. #define SPACE ' '
  20. #define TAB '\t'
  21. #define TABWIDTH 8
  22. #define REG register
  23. #define NEWLINE(c) ( (c) == '\n' || (c) == '\r' || (c) == '\f' )
  24. #ifndef BIGBUFSIZE
  25. #define BIGBUFSIZE 8192
  26. #endif
  27. char inbuf [ BIGBUFSIZE ] ;
  28. char outbuf [ BIGBUFSIZE ] ;
  29. static char MsgInternalError [ ] = "detab: internal error: %s(%s)\n" ;
  30. static char MsgOpenError [ ] = "detab: cannot open `%s' for input\n" ;
  31. static char MsgWriteError [ ] = "detab: error writing to `%s'\n" ;
  32. static char MsgStdin [ ] = "<stdin>" ;
  33. static char MsgStdout [ ] = "<stdout>" ;
  34. static char MsgSetmode [ ] = "setmode" ;
  35. static char MsgSetvbuf [ ] = "setvbuf" ;
  36. int main ( int argc , char * * argv )
  37. {
  38. REG int column ;
  39. REG int ch ;
  40. REG int spcount ;
  41. FILE * input ;
  42. char * MsgInput ;
  43. int tabwidth = TABWIDTH ;
  44. int countflag = 0 ;
  45. long kilobytes ;
  46. unsigned bytecount ;
  47. char * cp ;
  48. int FillChar = SPACE ; /* default character to use when detabbing */
  49. while ( -- argc > 0 && * ( cp = * ++ argv ) == '-' )
  50. {
  51. ++cp;
  52. while (*cp)
  53. {
  54. if ( * cp == 'k' )
  55. ++ countflag , ++ cp ;
  56. else if ( '0' <= * cp && * cp <= '9' )
  57. {
  58. tabwidth = * cp ++ - '0' ;
  59. while ( '0' <= * cp && * cp <= '9' )
  60. tabwidth = 10 * tabwidth + * cp ++ - '0' ;
  61. }
  62. else if ( * cp == 'c' )
  63. {
  64. FillChar = * ++ cp ;
  65. ++ cp ;
  66. }
  67. else
  68. {
  69. Usage :
  70. fprintf ( stderr ,
  71. "Usage: detab [-cX -k -###] [inputfile]\n"
  72. "where ### is the number of colums per tab stop (default=8)\n"
  73. "-k selects progress reports (written to stderr) every 16 Kbytes\n"
  74. "and X is the character to use for tabs (default is space)\n"
  75. ) ;
  76. exit ( 1 ) ;
  77. }
  78. }
  79. }
  80. if ( argc == 0 )
  81. {
  82. MsgInput = MsgStdin ;
  83. input = stdin ;
  84. if ( _setmode ( _fileno(stdin) , O_BINARY ) == -1 )
  85. {
  86. fprintf ( stderr , MsgInternalError , MsgSetmode , MsgStdin ) ;
  87. exit ( -1 ) ;
  88. }
  89. }
  90. else if ( argc == 1 )
  91. {
  92. MsgInput = * argv ;
  93. if ( ! ( input = fopen ( MsgInput , "rb" ) ) )
  94. {
  95. fprintf ( stderr , MsgOpenError , MsgInput ) ;
  96. exit ( 1 ) ;
  97. }
  98. }
  99. else
  100. goto Usage ;
  101. if ( setvbuf ( input , inbuf , _IOFBF , BIGBUFSIZE ) )
  102. {
  103. fprintf ( stderr , MsgInternalError , MsgSetvbuf , MsgInput ) ;
  104. exit ( -1 ) ;
  105. }
  106. if ( _setmode ( _fileno(stdout) , O_BINARY ) == -1 )
  107. {
  108. fprintf ( stderr , MsgInternalError , MsgSetmode , MsgStdout ) ;
  109. exit ( -1 ) ;
  110. }
  111. if ( ! _isatty ( _fileno ( stdin ) )
  112. && setvbuf ( stdout , outbuf , _IOFBF , BIGBUFSIZE ) )
  113. {
  114. fprintf ( stderr , MsgInternalError , MsgSetvbuf , MsgStdout ) ;
  115. exit ( -1 ) ;
  116. }
  117. kilobytes = bytecount = 0 ;
  118. column = 0 ;
  119. while ( ( ch = getc ( input ) ) != EOF )
  120. {
  121. if ( ch == TAB )
  122. {
  123. do
  124. putchar ( FillChar ) ;
  125. while ( ++ column < tabwidth ) ;
  126. column = 0 ;
  127. }
  128. else {
  129. putchar ( ch ) ;
  130. if ( NEWLINE(ch) )
  131. column = 0 ;
  132. else if ( ++ column == tabwidth )
  133. column = 0 ;
  134. else if ( column > tabwidth )
  135. {
  136. fprintf ( stderr , MsgInternalError , "" , "column>tabwidth" ) ;
  137. return 1 ;
  138. }
  139. }
  140. if ( ++ bytecount >= 16384 )
  141. {
  142. bytecount -= 16384 ;
  143. if ( countflag )
  144. fprintf ( stderr , "%ldK\r" , kilobytes += 16 ) ;
  145. if ( ferror ( stdout) )
  146. {
  147. fprintf ( stderr , MsgWriteError , MsgStdout ) ;
  148. return 1 ;
  149. }
  150. }
  151. }
  152. if ( ferror ( stdout) || fflush ( stdout ) )
  153. {
  154. fprintf ( stderr , MsgWriteError , MsgStdout ) ;
  155. return 1 ;
  156. }
  157. return 0 ;
  158. }