add a hack for Decap Attack
[picodrive.git] / tools / textfilter.c
index 212555b..c7a088b 100644 (file)
@@ -1,11 +1,13 @@
 #include <stdio.h>
 #include <string.h>
+#include <ctype.h>
 
 
 static int check_defines(const char **defs, int defcount, char *tdef)
 {
        int i, len;
 
+       while (isspace(*tdef)) tdef++;
        len = strlen(tdef);
        for (i = 0; i < len; i++)
                if (tdef[i] == ' ' || tdef[i] == '\r' || tdef[i] == '\n') break;
@@ -20,30 +22,47 @@ static int check_defines(const char **defs, int defcount, char *tdef)
        return 0;
 }
 
-
 static void do_counters(char *str)
 {
-       static int counters[4] = { 1, 1, 1, 1 };
+       static int counter_id = -1, counter;
        char buff[1024];
-       int counter;
        char *s = str;
 
        while ((s = strstr(s, "@@")))
        {
-               if (s[2] < '0' || s[2] > '3') { s++; continue; }
+               if (s[2] < '0' || s[2] > '9') { s++; continue; }
 
-               counter = s[2] - '0';
-               snprintf(buff, sizeof(buff), "%i%s", counters[counter]++, s + 3);
+               if (counter_id != s[2] - '0') {
+                       counter_id = s[2] - '0';
+                       counter = 1;
+               }
+               snprintf(buff, sizeof(buff), "%i%s", counter++, s + 3);
                strcpy(s, buff);
        }
 }
 
+static int my_fputs(char *s, FILE *stream)
+{
+       char *p;
+
+       for (p = s + strlen(s) - 1; p >= s; p--)
+               if (!isspace(*p))
+                       break;
+       p++;
+
+       /* use DOS endings for better viewer compatibility */
+       memcpy(p, "\r\n", 3);
+
+       return fputs(s, stream);
+}
 
 int main(int argc, char *argv[])
 {
+       char path[256], path_file[256];
        char buff[1024];
        FILE *fi, *fo;
-       int skip_mode = 0, ifdef_level = 0, line = 0;
+       int skip_mode = 0, ifdef_level = 0, skip_level = 0, line = 0;
+       char *p;
 
        if (argc < 3)
        {
@@ -58,13 +77,21 @@ int main(int argc, char *argv[])
                return 2;
        }
 
-       fo = fopen(argv[2], "w");
+       fo = fopen(argv[2], "wb");
        if (fo == NULL)
        {
                printf("failed to open: %s\n", argv[2]);
                return 3;
        }
 
+       snprintf(path, sizeof(path), "%s", argv[1]);
+       for (p = path + strlen(path) - 1; p > path; p--) {
+               if (*p == '/' || *p == '\\') {
+                       p[1] = 0;
+                       break;
+               }
+       }
+
        for (++line; !feof(fi); line++)
        {
                char *fgs;
@@ -77,20 +104,25 @@ int main(int argc, char *argv[])
                        /* control char */
                        if (strncmp(buff, "#ifdef ", 7) == 0)
                        {
-                               if (!check_defines((void *) &argv[3], argc-3, buff + 7)) skip_mode = 1;
                                ifdef_level++;
+                               if (!skip_mode && !check_defines((void *) &argv[3], argc-3, buff + 7))
+                                       skip_mode = 1, skip_level = ifdef_level;
                        }
                        else if (strncmp(buff, "#ifndef ", 8) == 0)
                        {
-                               if ( check_defines((void *) &argv[3], argc-3, buff + 7)) skip_mode = 1;
                                ifdef_level++;
+                               if (!skip_mode &&  check_defines((void *) &argv[3], argc-3, buff + 8))
+                                       skip_mode = 1, skip_level = ifdef_level;
                        }
                        else if (strncmp(buff, "#else", 5) == 0)
                        {
-                               skip_mode ^= 1;
+                               if (!skip_mode || skip_level == ifdef_level)
+                                       skip_mode ^= 1, skip_level = ifdef_level;
                        }
                        else if (strncmp(buff, "#endif", 6) == 0)
                        {
+                               if (skip_level == ifdef_level)
+                                       skip_mode = 0;
                                ifdef_level--;
                                if (ifdef_level == 0) skip_mode = 0;
                                if (ifdef_level < 0)
@@ -99,6 +131,34 @@ int main(int argc, char *argv[])
                                        ifdef_level = 0;
                                }
                        }
+                       else if (strncmp(buff, "#include ", 9) == 0)
+                       {
+                               char *pe, *p = buff + 9;
+                               FILE *ftmp;
+                               if (skip_mode)
+                                       continue;
+                               while (*p && (*p == ' ' || *p == '\"'))
+                                       p++;
+                               for (pe = p + strlen(p) - 1; pe > p; pe--) {
+                                       if (isspace(*pe) || *pe == '\"') *pe = 0;
+                                       else break;
+                               }
+                               snprintf(path_file, sizeof(path_file), "%s%s", path, p);
+                               ftmp = fopen(path_file, "r");
+                               if (ftmp == NULL) {
+                                       printf("%i: error: failed to include \"%s\"\n", line, p);
+                                       return 1;
+                               }
+                               while (!feof(ftmp))
+                               {
+                                       fgs = fgets(buff, sizeof(buff), ftmp);
+                                       if (fgs == NULL)
+                                               break;
+                                       my_fputs(buff, fo);
+                               }
+                               fclose(ftmp);
+                               continue;
+                       }
 
                        /* skip line */
                        continue;
@@ -106,7 +166,7 @@ int main(int argc, char *argv[])
                if (!skip_mode)
                {
                        do_counters(buff);
-                       fputs(buff, fo);
+                       my_fputs(buff, fo);
                }
        }