optimizations, fixes, hacks, psp, ...
[picodrive.git] / tools / gcda.c
diff --git a/tools/gcda.c b/tools/gcda.c
new file mode 100644 (file)
index 0000000..1fb6baf
--- /dev/null
@@ -0,0 +1,110 @@
+#include <stdio.h>
+//#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+static int search_gcda(const char *str, int len)
+{
+       int i;
+       for (i = 0; i < len - 6; i++)
+               if (str[i]   == '.' && str[i+1] == 'g' && str[i+2] == 'c' &&
+                   str[i+3] == 'd' && str[i+4] == 'a' && str[i+5] == 0)
+                       return i;
+       return -1;
+}
+
+static int is_good_char(char c)
+{
+       return c >= ' ' && c < 0x7f;
+}
+
+static int is_good_path(char *path)
+{
+       int len = strlen(path);
+
+       path[len-2] = 'n';
+       path[len-1] = 'o';
+
+       FILE *f = fopen(path, "rb");
+
+       path[len-2] = 'd';
+       path[len-1] = 'a';
+
+       if (f) {
+               fclose(f);
+               return 1;
+       }
+       return 0;
+}
+
+int main(int argc, char *argv[])
+{
+       char buff[1024], *p;
+       char cwd[4096];
+       FILE *f;
+       int l, pos, pos1, old_len, cwd_len;
+
+       if (argc != 2) return 1;
+
+       getcwd(cwd, sizeof(cwd));
+       cwd_len = strlen(cwd);
+       if (cwd[cwd_len-1] != '/') {
+               cwd[cwd_len++] = '/';
+               cwd[cwd_len] = 0;
+       }
+
+       f = fopen(argv[1], "rb+");
+       if (f == NULL) return 2;
+
+       while (1)
+       {
+readnext:
+               l = fread(buff, 1, sizeof(buff), f);
+               if (l <= 16) break;
+
+               pos = 0;
+               while (pos < l)
+               {
+                       pos1 = search_gcda(buff + pos, l - pos);
+                       if (pos1 < 0) {
+                               fseek(f, -5, SEEK_CUR);
+                               goto readnext;
+                       }
+                       pos += pos1;
+
+                       while (pos > 0 && is_good_char(buff[pos-1])) pos--;
+
+                       if (pos == 0) {
+                               fseek(f, -16, SEEK_CUR);
+                               goto readnext;
+                       }
+
+                       // paths must start with /
+                       while (pos < l && buff[pos] != '/') pos++;
+                       p = buff + pos;
+                       old_len = strlen(p);
+
+                       if (!is_good_path(p)) {
+                               pos += old_len;
+                               continue;
+                       }
+
+                       if (strncmp(p, cwd, cwd_len) != 0) {
+                               printf("can't handle: %s\n", p);
+                               pos += old_len;
+                               continue;
+                       }
+
+                       memmove(p, p + cwd_len, old_len - cwd_len + 1);
+                       fseek(f, -(sizeof(buff) - pos), SEEK_CUR);
+                       fwrite(p, 1, old_len, f);
+                       goto readnext;
+               }
+       }
+
+       fclose(f);
+
+       return 0;
+}
+