optimizations, fixes, hacks, psp, ...
[picodrive.git] / tools / gcda.c
CommitLineData
b542be46 1#include <stdio.h>
2//#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5
6
7static int search_gcda(const char *str, int len)
8{
9 int i;
10 for (i = 0; i < len - 6; i++)
11 if (str[i] == '.' && str[i+1] == 'g' && str[i+2] == 'c' &&
12 str[i+3] == 'd' && str[i+4] == 'a' && str[i+5] == 0)
13 return i;
14 return -1;
15}
16
17static int is_good_char(char c)
18{
19 return c >= ' ' && c < 0x7f;
20}
21
22static int is_good_path(char *path)
23{
24 int len = strlen(path);
25
26 path[len-2] = 'n';
27 path[len-1] = 'o';
28
29 FILE *f = fopen(path, "rb");
30
31 path[len-2] = 'd';
32 path[len-1] = 'a';
33
34 if (f) {
35 fclose(f);
36 return 1;
37 }
38 return 0;
39}
40
41int main(int argc, char *argv[])
42{
43 char buff[1024], *p;
44 char cwd[4096];
45 FILE *f;
46 int l, pos, pos1, old_len, cwd_len;
47
48 if (argc != 2) return 1;
49
50 getcwd(cwd, sizeof(cwd));
51 cwd_len = strlen(cwd);
52 if (cwd[cwd_len-1] != '/') {
53 cwd[cwd_len++] = '/';
54 cwd[cwd_len] = 0;
55 }
56
57 f = fopen(argv[1], "rb+");
58 if (f == NULL) return 2;
59
60 while (1)
61 {
62readnext:
63 l = fread(buff, 1, sizeof(buff), f);
64 if (l <= 16) break;
65
66 pos = 0;
67 while (pos < l)
68 {
69 pos1 = search_gcda(buff + pos, l - pos);
70 if (pos1 < 0) {
71 fseek(f, -5, SEEK_CUR);
72 goto readnext;
73 }
74 pos += pos1;
75
76 while (pos > 0 && is_good_char(buff[pos-1])) pos--;
77
78 if (pos == 0) {
79 fseek(f, -16, SEEK_CUR);
80 goto readnext;
81 }
82
83 // paths must start with /
84 while (pos < l && buff[pos] != '/') pos++;
85 p = buff + pos;
86 old_len = strlen(p);
87
88 if (!is_good_path(p)) {
89 pos += old_len;
90 continue;
91 }
92
93 if (strncmp(p, cwd, cwd_len) != 0) {
94 printf("can't handle: %s\n", p);
95 pos += old_len;
96 continue;
97 }
98
99 memmove(p, p + cwd_len, old_len - cwd_len + 1);
100 fseek(f, -(sizeof(buff) - pos), SEEK_CUR);
101 fwrite(p, 1, old_len, f);
102 goto readnext;
103 }
104 }
105
106 fclose(f);
107
108 return 0;
109}
110