textfilter.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <ctype.h>
  4. static int check_defines(const char **defs, int defcount, char *tdef)
  5. {
  6. int i, len;
  7. while (isspace(*tdef)) tdef++;
  8. len = strlen(tdef);
  9. for (i = 0; i < len; i++)
  10. if (tdef[i] == ' ' || tdef[i] == '\r' || tdef[i] == '\n') break;
  11. tdef[i] = 0;
  12. for (i = 0; i < defcount; i++)
  13. {
  14. if (strcmp(defs[i], tdef) == 0)
  15. return 1;
  16. }
  17. return 0;
  18. }
  19. static void do_counters(char *str)
  20. {
  21. static int counter_id = -1, counter;
  22. char buff[1024];
  23. char *s = str;
  24. while ((s = strstr(s, "@@")))
  25. {
  26. if (s[2] < '0' || s[2] > '9') { s++; continue; }
  27. if (counter_id != s[2] - '0') {
  28. counter_id = s[2] - '0';
  29. counter = 1;
  30. }
  31. snprintf(buff, sizeof(buff), "%i%s", counter++, s + 3);
  32. strcpy(s, buff);
  33. }
  34. }
  35. static int my_fputs(char *s, FILE *stream)
  36. {
  37. char *p;
  38. for (p = s + strlen(s) - 1; p >= s; p--)
  39. if (!isspace(*p))
  40. break;
  41. p++;
  42. /* use DOS endings for better viewer compatibility */
  43. memcpy(p, "\r\n", 3);
  44. return fputs(s, stream);
  45. }
  46. int main(int argc, char *argv[])
  47. {
  48. char path[256], path_file[256];
  49. char buff[1024];
  50. FILE *fi, *fo;
  51. int skip_mode = 0, ifdef_level = 0, skip_level = 0, line = 0;
  52. char *p;
  53. if (argc < 3)
  54. {
  55. printf("usage:\n%s <file_in> <file_out> [defines...]\n", argv[0]);
  56. return 1;
  57. }
  58. fi = fopen(argv[1], "r");
  59. if (fi == NULL)
  60. {
  61. printf("failed to open: %s\n", argv[1]);
  62. return 2;
  63. }
  64. fo = fopen(argv[2], "wb");
  65. if (fo == NULL)
  66. {
  67. printf("failed to open: %s\n", argv[2]);
  68. return 3;
  69. }
  70. snprintf(path, sizeof(path), "%s", argv[1]);
  71. for (p = path + strlen(path) - 1; p > path; p--) {
  72. if (*p == '/' || *p == '\\') {
  73. p[1] = 0;
  74. break;
  75. }
  76. }
  77. for (++line; !feof(fi); line++)
  78. {
  79. char *fgs;
  80. fgs = fgets(buff, sizeof(buff), fi);
  81. if (fgs == NULL) break;
  82. if (buff[0] == '#')
  83. {
  84. /* control char */
  85. if (strncmp(buff, "#ifdef ", 7) == 0)
  86. {
  87. ifdef_level++;
  88. if (!skip_mode && !check_defines((void *) &argv[3], argc-3, buff + 7))
  89. skip_mode = 1, skip_level = ifdef_level;
  90. }
  91. else if (strncmp(buff, "#ifndef ", 8) == 0)
  92. {
  93. ifdef_level++;
  94. if (!skip_mode && check_defines((void *) &argv[3], argc-3, buff + 8))
  95. skip_mode = 1, skip_level = ifdef_level;
  96. }
  97. else if (strncmp(buff, "#else", 5) == 0)
  98. {
  99. if (!skip_mode || skip_level == ifdef_level)
  100. skip_mode ^= 1, skip_level = ifdef_level;
  101. }
  102. else if (strncmp(buff, "#endif", 6) == 0)
  103. {
  104. if (skip_level == ifdef_level)
  105. skip_mode = 0;
  106. ifdef_level--;
  107. if (ifdef_level == 0) skip_mode = 0;
  108. if (ifdef_level < 0)
  109. {
  110. printf("%i: warning: #endif without #ifdef, ignoring\n", line);
  111. ifdef_level = 0;
  112. }
  113. }
  114. else if (strncmp(buff, "#include ", 9) == 0)
  115. {
  116. char *pe, *p = buff + 9;
  117. FILE *ftmp;
  118. if (skip_mode)
  119. continue;
  120. while (*p && (*p == ' ' || *p == '\"'))
  121. p++;
  122. for (pe = p + strlen(p) - 1; pe > p; pe--) {
  123. if (isspace(*pe) || *pe == '\"') *pe = 0;
  124. else break;
  125. }
  126. snprintf(path_file, sizeof(path_file), "%s%s", path, p);
  127. ftmp = fopen(path_file, "r");
  128. if (ftmp == NULL) {
  129. printf("%i: error: failed to include \"%s\"\n", line, p);
  130. return 1;
  131. }
  132. while (!feof(ftmp))
  133. {
  134. fgs = fgets(buff, sizeof(buff), ftmp);
  135. if (fgs == NULL)
  136. break;
  137. my_fputs(buff, fo);
  138. }
  139. fclose(ftmp);
  140. continue;
  141. }
  142. /* skip line */
  143. continue;
  144. }
  145. if (!skip_mode)
  146. {
  147. do_counters(buff);
  148. my_fputs(buff, fo);
  149. }
  150. }
  151. fclose(fi);
  152. fclose(fo);
  153. return 0;
  154. }