Source code of Windows XP (NT5)
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.

157 lines
4.1 KiB

  1. /*
  2. tabstospaces
  3. Usage:
  4. tabstospaces -n filenamein filenameout
  5. where n is how many spaces there are to a tab, like 4 or 8, and filenamein can be -stdin and filenameout can be -stdout
  6. (if you use -stdin or -stdout, the order is not important; likewise, -n can appear anywhere).
  7. NOTE we don't just replace a tab with n spaces, we assume a tab rounds to next multiple of n spaces, and add
  8. the appropriate, possibly smaller, number of spaces.
  9. If you only list one file, that file is the input and the output. The output will be written to a temporary file
  10. and then copied into the output.
  11. Buffered i/o into a fixed sized buffer is used, so file sizes are not limited by memory or address space.
  12. If you only list -stdin or -stdout, the other is assumed.
  13. Jay Krell
  14. May 14, 2001
  15. */
  16. #include <stdio.h>
  17. #include <ctype.h>
  18. #include <string>
  19. #include <vector>
  20. #include "fcntl.h"
  21. #include "io.h"
  22. #ifndef _DLL
  23. extern "C" { int _fmode = _O_BINARY; }
  24. #endif
  25. FILE* myfopen(const char* name, const char* mode)
  26. {
  27. FILE* f;
  28. int er;
  29. f = fopen(name, mode);
  30. if (f != NULL)
  31. return f;
  32. er = errno;
  33. fprintf(stderr, "%s", (std::string("Unable to open ") + name + " -- " + strerror(er)).c_str());
  34. exit(EXIT_FAILURE);
  35. }
  36. int __cdecl main(int argc, char** argv)
  37. {
  38. unsigned col = 1;
  39. char ch = 0;
  40. unsigned tabwidth = 1;
  41. FILE* filein = NULL;
  42. FILE* fileout = NULL;;
  43. char* filenamein = NULL;
  44. char* filenameout = NULL;
  45. char* inbuffer = NULL;
  46. FILE* tmp = NULL;
  47. const unsigned long bufsize = 32768;
  48. std::vector<char> buffer;
  49. buffer.resize(bufsize);
  50. unsigned long i = 0;
  51. unsigned long j = 0;
  52. std::vector<char> bufferout;
  53. bufferout.reserve(bufsize * 2);
  54. while (*++argv != NULL)
  55. {
  56. if (argv[0][0] == '/' || argv[0][0] == '-')
  57. {
  58. if (_stricmp(&argv[0][1], "stdin") == 0)
  59. {
  60. _setmode(_fileno(stdin), _O_BINARY);
  61. filein = stdin;
  62. }
  63. else if (_stricmp(&argv[0][1], "stdout") == 0)
  64. {
  65. _setmode(_fileno(stdout), _O_BINARY);
  66. fileout = stdout;
  67. }
  68. else if (isdigit(argv[0][1]))
  69. {
  70. tabwidth = atoi(argv[0] + 1);
  71. }
  72. }
  73. else
  74. {
  75. bool gotin = (filenamein != NULL || filein != NULL);
  76. char** name = gotin ? &filenameout : &filenamein;
  77. *name = argv[0];
  78. }
  79. }
  80. if (filein == NULL && filenamein == NULL)
  81. exit(EXIT_FAILURE);
  82. if (filein == NULL && filenamein != NULL)
  83. filein = myfopen(filenamein, "rb");
  84. if ((filein == NULL && filenamein == NULL) || (fileout == NULL && filenameout == NULL))
  85. {
  86. if (fileout == stdout)
  87. filein = stdin;
  88. else if (filein == stdin)
  89. fileout = stdout;
  90. else
  91. filenameout = filenamein;
  92. }
  93. if (filein == stdin || fileout == stdout || _stricmp(filenamein, filenameout) == 0)
  94. {
  95. tmp = tmpfile();
  96. }
  97. else
  98. {
  99. fileout = myfopen(filenameout, "wb");
  100. tmp = fileout;
  101. }
  102. while ((i = fread(&buffer[0], 1, buffer.size(), filein)) != 0)
  103. {
  104. bufferout.resize(0);
  105. for (j = 0 ; j != i ; j += 1)
  106. {
  107. switch (ch = buffer[j])
  108. {
  109. default:
  110. col += 1;
  111. bufferout.push_back(ch);
  112. break;
  113. case '\r':
  114. case '\n':
  115. col = 1;
  116. bufferout.push_back(ch);
  117. break;
  118. case '\t':
  119. do
  120. {
  121. bufferout.push_back(' ');
  122. col += 1;
  123. } while (((col - 1) % tabwidth) != 0);
  124. }
  125. }
  126. fwrite(&bufferout[0], 1, bufferout.size(), tmp);
  127. }
  128. fflush(tmp);
  129. fclose(filein);
  130. if (fileout == NULL)
  131. {
  132. fileout = myfopen(filenameout, "wb+");
  133. fseek(tmp, 0, SEEK_SET);
  134. while ((i = fread(&buffer[0], 1, buffer.size(), tmp)) != 0)
  135. fwrite(&buffer[0], 1, i, fileout);
  136. fclose(tmp);
  137. }
  138. fclose(fileout);
  139. return 0;
  140. }