7 #define OUT_FILE "PicoAll.c"
9 // files to amalgamate, in order
10 static const char *files[] =
13 // PicoInt.h includes some CD stuff, so start with them
35 "Pico/cd/buffering.c",
49 static char *includes[128];
51 static void eprintf(const char *fmt, ...)
62 static void emit_header(FILE *f, const char *fname)
64 char tmp[128] = "/* */";
65 memcpy(tmp + 3, fname, strlen(fname));
67 fprintf(f, "/**************************************************************/\n");
68 fprintf(f, "/**************************************************************/\n");
69 fprintf(f, "%s\n", tmp);
70 fprintf(f, "/**************************************************************/\n");
73 static const char *add_include(const char *include)
76 char processed_inc[128+4];
78 // must first quote relative includes
79 snprintf(processed_inc, sizeof(processed_inc), (include[0] != '<') ? "\"%s\"" : "%s", include);
81 // find in include list
82 for (i = 0; includes[i] && i < 128; i++)
84 if (strcmp(processed_inc, includes[i]) == 0) break;
86 if (i == 128) eprintf("add_include: includes overflowed\n");
87 if (includes[i] != NULL)
89 printf("already have: %s\n", processed_inc);
94 printf("adding: %s\n", processed_inc);
95 includes[i] = strdup(processed_inc);
96 if (includes[i] == NULL) eprintf("add_include: OOM\n");
101 static const char *add_raw_include(const char *include, const char *base)
104 char processed_inc[128];
106 for (ps = include; *ps && isspace(*ps); ps++);
111 // system include, search for '>'
112 for (pe = ps; *pe && *pe != '>'; pe++, len++);
113 if (*pe == 0 || len > 127) eprintf("add_raw_include: failed sysinclude, len=%i\n", len);
114 strncpy(processed_inc, ps, len);
115 processed_inc[len] = 0;
117 else if (*ps == '\"')
120 // relative include, make path absolute (or relative to base dir)
121 strcpy(processed_inc, base);
125 if (strncmp(ps, "../", 3) == 0)
128 if (processed_inc[0] == 0)
129 eprintf("add_raw_include: already in root, can't go down: %s | %s\n", ps, include);
130 p = strrchr(processed_inc, '/');
131 if (p == NULL) eprintf("add_raw_include: can't happen\n");
133 p = strrchr(processed_inc, '/');
134 if (p != NULL) p[1] = 0;
135 else processed_inc[0] = 0;
138 else if (strncmp(ps, "./", 2) == 0)
140 ps += 2; // just skip
142 while (*ps == '/') ps++;
144 if (*ps == 0) eprintf("add_raw_include: failed with %s\n", include);
146 len = pos = strlen(processed_inc);
147 for (pe = ps; *pe && *pe != '\"'; pe++, len++);
148 if (*pe == 0 || len > 127) eprintf("add_raw_include: failed with %s, len=%i\n", include, len);
149 strncpy(processed_inc + pos, ps, len - pos);
150 processed_inc[len] = 0;
153 eprintf("add_raw_include: unhandled include: %s\n", ps);
155 return add_include(processed_inc);
158 // returns pointer to location after part in string
159 static const char *substr_end(const char *string, const char *part)
161 const char *p = string;
162 int len = strlen(part);
164 while (*p && isspace(*p)) p++;
165 return (strncmp(p, part, len) == 0) ? (p + len) : NULL;
168 static void strip_cr(char *str)
170 int len = strlen(str);
173 while ((p = strchr(p, '\r')))
175 memmove(p, p + 1, len - (p - str) + 1);
179 p = str + strlen(str) - 1;
180 while (p >= str && isspace(*p)) { *p = 0; p--; } // strip spaces on line ends
182 strcat(str, "\n"); // re-add newline
187 char buff[512]; // tmp buffer
188 char path[128]; // path to file being included, with ending slash
192 memset(includes, 0, sizeof(includes));
194 fo = fopen(OUT_FILE, "w");
195 if (fo == NULL) return 1;
198 fprintf(fo, "#define PICO_INTERNAL static\n");
199 fprintf(fo, "#define PICO_INTERNAL_ASM\n");
201 for (ifile = 0; ifile < sizeof(files) / sizeof(files[0]); ifile++)
204 const char *file = files[ifile], *p;
205 p = strrchr(file, '/');
206 if (p == NULL) eprintf("main: file in root? %s\n", file);
207 strncpy(path, file, p - file + 1);
208 path[p - file + 1] = 0;
210 fi = fopen(file, "r");
211 if (fi == NULL) eprintf("main: failed to open %s\n", file);
213 // if (strcmp(file + strlen(file) - 2, ".h") == 0)
215 emit_header(fo, file);
219 p = fgets(buff, sizeof(buff), fi);
220 if (p == NULL) break;
223 p = substr_end(buff, "#include");
226 p = add_raw_include(p, path);
227 if (p != NULL) fprintf(fo, "#include %s\n", p);
235 emit_header(fo, "EOF");
237 for (i = 0; includes[i] && i < 128; i++)