CRCDiff.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "debug.h"
  19. #include "expander.h"
  20. #include "KVPair.h"
  21. #include "misc.h"
  22. #include <iostream>
  23. #include <list>
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. //=============================================================================
  27. std::string tableRow;
  28. //=============================================================================
  29. static void exitWait(void)
  30. {
  31. system("PAUSE");
  32. }
  33. //=============================================================================
  34. #define LINESIZE 1024
  35. static bool getNextLine(FILE *fp, char *line, int& frame, int& index) {
  36. if (!fp)
  37. return false;
  38. char buf[LINESIZE];
  39. while (fgets(buf, LINESIZE-1, fp) != NULL)
  40. {
  41. int len = strlen(buf);
  42. if (buf[len-1] == '\n')
  43. buf[len-1] = '\0';
  44. if (sscanf(buf, "%d:%d ", &frame, &index) == 2)
  45. {
  46. strcpy(line, buf);
  47. return true;
  48. }
  49. }
  50. fclose(fp);
  51. return false;
  52. }
  53. //=============================================================================
  54. static std::string readInFile(const char *fname) {
  55. FILE *fp = fopen(fname, "rt");
  56. if (!fp)
  57. return "";
  58. std::string ret;
  59. char buf[LINESIZE];
  60. while (fgets(buf, LINESIZE-1, fp) != NULL)
  61. {
  62. ret.append(buf);
  63. }
  64. fclose(fp);
  65. return ret;
  66. }
  67. //=============================================================================
  68. static FILE *ofp = NULL;
  69. void dumpQueued(void);
  70. static void outputLine(const char *line)
  71. {
  72. dumpQueued();
  73. //cout << line << endl;
  74. if (ofp)
  75. {
  76. fputs(line, ofp);
  77. }
  78. }
  79. //=============================================================================
  80. static void outputLine(int frame, int index, int linkNum,
  81. const char *class1, const char *line1,
  82. const char *class2, const char *line2, bool same = false)
  83. {
  84. dumpQueued();
  85. if (!line1)
  86. line1 = "&nbsp;";
  87. if (!line2)
  88. line2 = "&nbsp;";
  89. if (!class1)
  90. class1 = "";
  91. if (!class2)
  92. class2 = "";
  93. Expander e("((", "))");
  94. e.addExpansion("LEFTCLASS", class1);
  95. e.addExpansion("LEFTLINE", line1);
  96. e.addExpansion("RIGHTCLASS", class2);
  97. e.addExpansion("RIGHTLINE", line2);
  98. if (same)
  99. {
  100. e.addExpansion("NAME", "");
  101. e.addExpansion("PREV", intToString(linkNum-1));
  102. e.addExpansion("NEXT", intToString(linkNum));
  103. }
  104. else
  105. {
  106. e.addExpansion("NAME", intToString(linkNum));
  107. e.addExpansion("PREV", intToString(linkNum-1));
  108. e.addExpansion("NEXT", intToString(linkNum+1));
  109. }
  110. std::string out;
  111. e.expand(tableRow, out);
  112. const char *buf = out.c_str();
  113. //cout << buf << endl;
  114. if (ofp)
  115. {
  116. fputs(buf, ofp);
  117. }
  118. }
  119. //=============================================================================
  120. std::list<std::string> queuedLines;
  121. static void queueLine(int frame, int index, const char *line1)
  122. {
  123. if (!line1)
  124. line1 = "&nbsp;";
  125. Expander e("((", "))");
  126. e.addExpansion("LEFTCLASS", "leftHistory");
  127. e.addExpansion("LEFTLINE", line1);
  128. e.addExpansion("RIGHTCLASS", "rightHistory");
  129. e.addExpansion("RIGHTLINE", line1);
  130. e.addExpansion("NAME", "");
  131. e.addExpansion("PREV", intToString(0));
  132. e.addExpansion("NEXT", intToString(1));
  133. std::string out;
  134. e.expand(tableRow, out);
  135. queuedLines.push_back(out);
  136. if (queuedLines.size() > 150)
  137. queuedLines.pop_front();
  138. //cout << buf << endl;
  139. }
  140. void dumpQueued(void)
  141. {
  142. while (!queuedLines.empty())
  143. {
  144. std::list<std::string>::iterator it = queuedLines.begin();
  145. const char *buf = (*it).c_str();
  146. //cout << buf << endl;
  147. if (ofp)
  148. {
  149. fputs(buf, ofp);
  150. }
  151. queuedLines.pop_front();
  152. }
  153. }
  154. //=============================================================================
  155. int main(int argc, char *argv[])
  156. {
  157. atexit(exitWait);
  158. const char *inFname[2];
  159. const char *outFname = "out.html";
  160. FILE *ifp[2] = {NULL, NULL};
  161. std::string header, footer;
  162. if (argc != 7)
  163. {
  164. cout << "Usage: munkeeDiff top.html row.html bottom.html in1.txt in2.txt out.txt" << endl;
  165. header = readInFile("top.html");
  166. tableRow = readInFile("row.html");
  167. footer = readInFile("bottom.html");
  168. inFname[0] = "test1.txt";
  169. inFname[1] = "test2.txt";
  170. //return 0;
  171. }
  172. else
  173. {
  174. header = readInFile(argv[1]);
  175. tableRow = readInFile(argv[2]);
  176. footer = readInFile(argv[3]);
  177. inFname[0] = argv[4];
  178. inFname[1] = argv[5];
  179. outFname = argv[6];
  180. }
  181. ifp[0] = fopen(inFname[0], "rt");
  182. if (!ifp[0])
  183. {
  184. cout << "could not open " << inFname[0] << endl;
  185. return 1;
  186. }
  187. ifp[1] = fopen(inFname[1], "rt");
  188. if (!ifp[1])
  189. {
  190. fclose(ifp[0]);
  191. cout << "could not open " << inFname[1] << endl;
  192. return 1;
  193. }
  194. ofp = fopen(outFname, "wt");
  195. char lastLine[2][LINESIZE];
  196. int lastFrame[2] = {-1, -1};
  197. int lastIndex[2] = {-1, -1};
  198. bool fileOk[2] = {true, true};
  199. outputLine(header.c_str());
  200. int linkNum = 1;
  201. int numDiffs = 0;
  202. bool seenRight = false;
  203. bool seenLeft = false;
  204. while (fileOk[0] || fileOk[1])
  205. {
  206. for (int i=0; i<2; ++i)
  207. {
  208. if (fileOk[i] == true && lastFrame[i] < 0)
  209. {
  210. fileOk[i] = getNextLine(ifp[i], lastLine[i],
  211. lastFrame[i], lastIndex[i]);
  212. }
  213. }
  214. if (fileOk[0] && fileOk[1])
  215. {
  216. if (lastFrame[0] < lastFrame[1] ||
  217. (lastFrame[0]==lastFrame[1] && lastIndex[0] < lastIndex[1]))
  218. {
  219. //if (!seenLeft)
  220. //cout << "Seen left on " << lastFrame[0] << ":" << lastIndex[0] << endl;
  221. //seenLeft = true;
  222. if (seenRight && seenLeft)
  223. {
  224. outputLine(lastFrame[0], lastIndex[0], linkNum++,
  225. "leftOnly", lastLine[0], NULL, NULL);
  226. ++numDiffs;
  227. }
  228. lastFrame[0] = -1;
  229. }
  230. else if (lastFrame[1] < lastFrame[0] ||
  231. (lastFrame[1]==lastFrame[0] && lastIndex[1] < lastIndex[0]))
  232. {
  233. //if (!seenRight)
  234. //cout << "Seen right on " << lastFrame[1] << ":" << lastIndex[1] << endl;
  235. //seenRight = true;
  236. if (seenRight && seenLeft)
  237. {
  238. outputLine(lastFrame[1], lastIndex[1], linkNum++,
  239. NULL, NULL, "rightOnly", lastLine[1]);
  240. ++numDiffs;
  241. }
  242. lastFrame[1] = -1;
  243. }
  244. else
  245. {
  246. int res = strcmp(lastLine[0], lastLine[1]);
  247. if (res!=0)
  248. {
  249. if (!seenLeft || !seenRight)
  250. cout << "Seen both on " << lastFrame[0] << ":" << lastIndex[0] << endl;
  251. seenLeft = seenRight = true;
  252. outputLine(lastFrame[0], lastIndex[0], linkNum++,
  253. "leftDiff", lastLine[0], "rightDiff", lastLine[1]);
  254. ++numDiffs;
  255. }
  256. else
  257. {
  258. //if (!seenLeft || !seenRight)
  259. // cout << "Seen both on " << lastFrame[0] << ":" << lastIndex[0] << endl;
  260. //seenLeft = seenRight = true;
  261. static bool printedFirst = false;
  262. if (!printedFirst)
  263. {
  264. outputLine(lastFrame[0], lastIndex[0], linkNum,
  265. "leftSame", lastLine[0], "rightSame", lastLine[1], true);
  266. printedFirst = true;
  267. }
  268. else if (seenLeft && seenRight)
  269. {
  270. outputLine(lastFrame[0], lastIndex[0], linkNum,
  271. "leftSame", lastLine[0], "rightSame", lastLine[1], true);
  272. ++numDiffs;
  273. }
  274. else
  275. queueLine(lastFrame[0], lastIndex[0], lastLine[0]);
  276. //++numDiffs;
  277. }
  278. lastFrame[0] = -1;
  279. lastFrame[1] = -1;
  280. }
  281. }
  282. else if (fileOk[0])
  283. {
  284. //if (!seenLeft)
  285. //cout << "Seen left on " << lastFrame[0] << ":" << lastIndex[0] << endl;
  286. //seenLeft = true;
  287. if (seenRight && seenLeft)
  288. {
  289. outputLine(lastFrame[0], lastIndex[0], linkNum++,
  290. "leftOnly", lastLine[0], NULL, NULL);
  291. ++numDiffs;
  292. }
  293. lastFrame[0] = -1;
  294. }
  295. else if (fileOk[1])
  296. {
  297. //if (!seenRight)
  298. //cout << "Seen right on " << lastFrame[1] << ":" << lastIndex[1] << endl;
  299. //seenRight = true;
  300. if (seenRight && seenLeft)
  301. {
  302. outputLine(lastFrame[1], lastIndex[1], linkNum++,
  303. NULL, NULL, "rightOnly", lastLine[1]);
  304. ++numDiffs;
  305. }
  306. lastFrame[1] = -1;
  307. }
  308. if (numDiffs > 1000)
  309. break;
  310. }
  311. Expander e("((", "))");
  312. e.addExpansion("LAST", intToString(linkNum-1));
  313. e.addExpansion("BOTTOM", intToString(linkNum));
  314. std::string out;
  315. e.expand(footer, out);
  316. outputLine(out.c_str());
  317. if (ofp)
  318. {
  319. fclose(ofp);
  320. }
  321. return 0;
  322. }