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.

205 lines
4.4 KiB

  1. /*
  2. This program merges binplace placefiles.
  3. It reads in the files named on the command line, and
  4. writes out a merged placefile to stdout.
  5. */
  6. #include "yvals.h"
  7. #pragma warning(disable:4100)
  8. #pragma warning(disable:4663)
  9. #pragma warning(disable:4511)
  10. #pragma warning(disable:4512)
  11. #pragma warning(disable:4127)
  12. #include <vector>
  13. #include <algorithm>
  14. #include <iostream>
  15. #include <fstream>
  16. #include <string>
  17. #include <map>
  18. #include <string.h>
  19. #include <set>
  20. #include "strtok_r.h"
  21. #include "windows.h"
  22. const char comment_char = ';';
  23. const char comment_chars[] = { comment_char , 0 };
  24. const char horizontal_whitespace_chars[] = { ' ', '\t', 0 };
  25. const char destination_delim = ':';
  26. const char destination_delims[] = { destination_delim, 0 };
  27. class String_t : public std::string
  28. {
  29. typedef std::string Base;
  30. public:
  31. String_t(const std::string & s) : Base(s) { }
  32. String_t() { }
  33. ~String_t() { }
  34. String_t(const String_t & s) : Base(s) { }
  35. String_t(const char * s) : Base(s) { }
  36. bool operator<( const String_t & s) const
  37. {
  38. return _stricmp(c_str(), s.c_str()) < 0;
  39. }
  40. bool operator==( const String_t & s) const
  41. {
  42. return _stricmp(c_str(), s.c_str()) == 0;
  43. }
  44. };
  45. class File_t : public std::map<String_t, std::set<String_t> >
  46. {
  47. public:
  48. void Read( const char * filename );
  49. };
  50. class CMutableString
  51. {
  52. public:
  53. CMutableString() { }
  54. CMutableString(const char * s)
  55. {
  56. size_t len = strlen(s);
  57. this->chars.resize(len + 1);
  58. strcpy(&this->chars[0], s);
  59. }
  60. size_t length() const { return ::strlen(&chars[0]); }
  61. void operator=(const CMutableString & t)
  62. {
  63. if (&t == this)
  64. return;
  65. this->chars = t.chars;
  66. }
  67. void operator=(const char * s)
  68. {
  69. //
  70. // s may point into chars, and resize may realloc, so use a temp
  71. //
  72. CMutableString temp(s);
  73. std::swap(this->chars, temp.chars);
  74. }
  75. operator char * () { return &chars[0]; }
  76. std::vector<char> chars;
  77. };
  78. class CStringTokenizer
  79. {
  80. public:
  81. CStringTokenizer() : state(0) { }
  82. ~CStringTokenizer() { }
  83. char * operator()(char * string, const char * delims)
  84. {
  85. return strtok_r(string, delims, &state);
  86. }
  87. char * state;
  88. };
  89. void TrimHorizontalWhitespaceFromEnds(char * & s)
  90. {
  91. s += strspn(s, horizontal_whitespace_chars);
  92. char * q = s + strlen(s);
  93. while (q != s && strchr(horizontal_whitespace_chars, *q) != NULL)
  94. {
  95. *q = 0;
  96. q -= 1;
  97. }
  98. }
  99. void File_t::Read(const char * filename)
  100. {
  101. String_t line;
  102. std::ifstream file;
  103. CMutableString mutable_line;
  104. char * p = 0;
  105. file.open(filename, std::ios_base::in);
  106. while (std::getline(file, line))
  107. {
  108. mutable_line = line.c_str();
  109. p = mutable_line;
  110. p += strspn(p, horizontal_whitespace_chars);
  111. if (p[0] == 0)
  112. continue;
  113. if (strchr(comment_chars, p[0]) != NULL)
  114. continue;
  115. char * comment = strchr(p, comment_char);
  116. if (comment != NULL)
  117. *comment = 0;
  118. mutable_line = p;
  119. p = mutable_line;
  120. const char * image_name = p;
  121. p += strcspn(p, horizontal_whitespace_chars);
  122. *p = 0;
  123. const String_t image_name_string = image_name;
  124. p += 1;
  125. p += strspn(p, horizontal_whitespace_chars);
  126. char * destinations = p;
  127. TrimHorizontalWhitespaceFromEnds(destinations);
  128. CStringTokenizer tokenize;
  129. for ( char * destination = tokenize(destinations, destination_delims) ;
  130. destination != NULL ;
  131. destination = tokenize(NULL, destination_delims)
  132. )
  133. {
  134. (*this)[image_name_string].insert(destination);
  135. //printf("%s -> %s\n", image_name, destination);
  136. }
  137. }
  138. }
  139. void MergePlacefiles(int nfiles, char ** filenames)
  140. {
  141. File_t accum;
  142. if (nfiles == 0)
  143. return;
  144. for ( int i = 0 ; i < nfiles - 1; ++i )
  145. {
  146. accum.Read(filenames[i]);
  147. }
  148. DeleteFileA(filenames[nfiles - 1]);
  149. FILE * fout = fopen(filenames[nfiles - 1], "w");
  150. if (fout == NULL)
  151. {
  152. fprintf(stderr, "Error fopen(%s)\n", filenames[nfiles - 1]);
  153. exit(-1);
  154. }
  155. for (
  156. File_t::const_iterator it = accum.begin();
  157. it != accum.end();
  158. ++it
  159. )
  160. {
  161. fprintf(fout, "%s ", it->first.c_str());
  162. bool first = true;
  163. for (
  164. std::set<String_t>::const_iterator it2 = it->second.begin();
  165. it2 != it->second.end();
  166. ++it2
  167. )
  168. {
  169. if (!first)
  170. fprintf(fout, ":");
  171. fprintf(fout, "%s", it2->c_str());
  172. first = false;
  173. }
  174. fprintf(fout, "\n");
  175. }
  176. fclose(fout);
  177. }
  178. int __cdecl main(int argc, char ** argv)
  179. {
  180. MergePlacefiles(argc - 1 , argv + 1);
  181. return 0;
  182. }