static const astring *normalized_subpath(const astring *path, int start) { astring *result = astring_dupsubstr(path, start, -1); if (result != NULL) astring_replacechr(result, PATH_SEPARATOR[0], '/'); return result; }
int main(int argc, char *argv[]) { astring *srcdir = NULL, *dstdir = NULL; int unadorned = 0; int result; int argnum; /* loop over arguments */ for (argnum = 1; argnum < argc; argnum++) { char *arg = argv[argnum]; /* include path? */ if (arg[0] == '-' && arg[1] == 'I') { *incpathhead = malloc(sizeof(**incpathhead)); if (*incpathhead != NULL) { (*incpathhead)->next = NULL; (*incpathhead)->path = astring_replacechr(astring_dupc(&arg[2]), '/', PATH_SEPARATOR[0]); incpathhead = &(*incpathhead)->next; } } /* other parameter */ else if (arg[0] != '-' && unadorned == 0) { srcdir = astring_dupc(arg); unadorned++; } else if (arg[0] != '-' && unadorned == 1) { dstdir = astring_dupc(arg); unadorned++; } else goto usage; } /* make sure we got 2 parameters */ if (srcdir == NULL || dstdir == NULL) goto usage; /* recurse over subdirectories */ result = recurse_dir(astring_len(srcdir), astring_len(dstdir), srcdir, dstdir); /* free source and destination directories */ astring_free(srcdir); astring_free(dstdir); return result; usage: fprintf(stderr, "Usage:\n%s <srcroot> <destroot> [-Iincpath [-Iincpath [...]]]\n", argv[0]); return 1; }
static file_entry *compute_dependencies(int srcrootlen, const astring *srcfile) { astring *normalfile; UINT32 filelength; file_entry *file; char *filedata; int index; /* see if we already have an entry */ normalfile = astring_dup(srcfile); astring_replacechr(normalfile, PATH_SEPARATOR[0], '/'); file = (file_entry *)tagmap_find(file_map, astring_c(normalfile)); if (file != NULL) return file; /* create a new header entry */ file = (file_entry *)malloc(sizeof(*file)); file->deplist = NULL; file->name = normalfile; tagmap_add(file_map, astring_c(file->name), file, FALSE); /* read the source file */ if (core_fload(astring_c(srcfile), (void **)&filedata, &filelength) != FILERR_NONE) { fprintf(stderr, "Unable to read file '%s'\n", astring_c(srcfile)); return file; } /* find the #include directives in this file */ for (index = 0; index < filelength; index++) if (filedata[index] == '#' && strncmp(&filedata[index + 1], "include", 7) == 0) { astring *filename, *target; int scan = index; dependency *dep; int start; int just_continue = 0; /* first make sure we're not commented or quoted */ for (scan = index; scan > 2 && filedata[scan] != 13 && filedata[scan] != 10; scan--) if ((filedata[scan] == '/' && filedata[scan - 1] == '/') || filedata[scan] == '"') { just_continue = 1; break; } if (just_continue) continue; /* scan forward to find the quotes or bracket */ index += 7; for (scan = index; scan < filelength && filedata[scan] != '<' && filedata[scan] != '"' && filedata[scan] != 13 && filedata[scan] != 10; scan++) ; /* ignore if not found or if it's bracketed */ if (scan >= filelength || filedata[scan] != '"') continue; start = ++scan; /* find the closing quote */ while (scan < filelength && filedata[scan] != '"') scan++; if (scan >= filelength) continue; /* find the include file */ filename = astring_dupch(&filedata[start], scan - start); target = find_include_file(srcrootlen, srcfile, filename); /* create a new dependency */ if (target != NULL) { dep = (dependency *)malloc(sizeof(*dep)); dep->next = file->deplist; file->deplist = dep; dep->file = compute_dependencies(srcrootlen, target); astring_free(target); } astring_free(filename); } osd_free(filedata); return file; }
int main(int argc, char *argv[]) { include_path **incpathhead = &incpaths; exclude_path **excpathhead = &excpaths; astring *srcdir = NULL; int unadorned = 0; int result; int argnum; /* loop over arguments */ for (argnum = 1; argnum < argc; argnum++) { char *arg = argv[argnum]; /* include path? */ if (arg[0] == '-' && arg[1] == 'I') { *incpathhead = (include_path *)malloc(sizeof(**incpathhead)); if (*incpathhead != NULL) { (*incpathhead)->next = NULL; (*incpathhead)->path = astring_replacechr(astring_dupc(&arg[2]), '/', PATH_SEPARATOR[0]); incpathhead = &(*incpathhead)->next; } } /* exclude path? */ else if (arg[0] == '-' && arg[1] == 'X') { *excpathhead = (exclude_path *)malloc(sizeof(**excpathhead)); if (*excpathhead != NULL) { astring *path; (*excpathhead)->next = NULL; path = astring_replacechr(astring_dupc(&arg[2]), PATH_SEPARATOR[0], '/'); (*excpathhead)->recursive = (astring_replacec(path, astring_len(path) - 4, "/...", "") != 0); (*excpathhead)->path = path; (*excpathhead)->pathlen = astring_len(path); excpathhead = &(*excpathhead)->next; } } /* ignore -include which is used by sdlmame to include sdlprefix.h before all other includes */ else if (strcmp(arg,"-include") == 0) { argnum++; } /* other parameter */ else if (arg[0] != '-' && unadorned == 0) { srcdir = astring_replacechr(astring_dupc(arg), '/', PATH_SEPARATOR[0]); unadorned++; } else goto usage; } /* make sure we got 1 parameter */ if (srcdir == NULL) goto usage; /* create a tagmap for tracking files we've visited */ file_map = tagmap_alloc(); /* recurse over subdirectories */ result = recurse_dir(astring_len(srcdir), srcdir); /* free source and destination directories */ tagmap_free(file_map); astring_free(srcdir); return result; usage: fprintf(stderr, "Usage:\n%s <srcroot> [-Iincpath [-Iincpath [...]]]\n", argv[0]); return 1; }
static astring *find_include_file(int srcrootlen, int dstrootlen, const astring *srcfile, const astring *dstfile, const astring *filename) { include_path *curpath; /* iterate over include paths and find the file */ for (curpath = incpaths; curpath != NULL; curpath = curpath->next) { astring *srcincpath = astring_cat(astring_dupsubstr(srcfile, 0, srcrootlen + 1), curpath->path); core_file *testfile; int lastsepindex = 0; int sepindex; /* a '.' include path is specially treated */ if (astring_cmpc(curpath->path, ".") == 0) astring_cpysubstr(srcincpath, srcfile, 0, astring_rchr(srcfile, 0, PATH_SEPARATOR[0])); /* append the filename piecemeal to account for directories */ while ((sepindex = astring_chr(filename, lastsepindex, '/')) != -1) { astring *pathpart = astring_dupsubstr(filename, lastsepindex, sepindex - lastsepindex); /* handle .. by removing a chunk from the incpath */ if (astring_cmpc(pathpart, "..") == 0) { sepindex = astring_rchr(srcincpath, 0, PATH_SEPARATOR[0]); if (sepindex != -1) astring_substr(srcincpath, 0, sepindex); } /* otherwise, append a path separator and the pathpart */ else astring_cat(astring_catc(srcincpath, PATH_SEPARATOR), pathpart); /* advance past the previous index */ lastsepindex = sepindex + 1; /* free the path part we extracted */ astring_free(pathpart); } /* now append the filename */ astring_catsubstr(astring_catc(srcincpath, PATH_SEPARATOR), filename, lastsepindex, -1); /* see if we can open it */ if (core_fopen(astring_c(srcincpath), OPEN_FLAG_READ, &testfile) == FILERR_NONE) { astring *tempfile = astring_alloc(); astring *tempinc = astring_alloc(); /* close the file */ core_fclose(testfile); /* find the longest matching directory substring between the include and source file */ lastsepindex = 0; while ((sepindex = astring_chr(srcincpath, lastsepindex, PATH_SEPARATOR[0])) != -1) { /* get substrings up to the current directory */ astring_cpysubstr(tempfile, srcfile, 0, sepindex); astring_cpysubstr(tempinc, srcincpath, 0, sepindex); /* if we don't match, stop */ if (astring_cmp(tempfile, tempinc) != 0) break; lastsepindex = sepindex + 1; } /* chop off the common parts of the paths */ astring_cpysubstr(tempfile, srcfile, lastsepindex, -1); astring_replacechr(astring_substr(srcincpath, lastsepindex, -1), PATH_SEPARATOR[0], '/'); /* for each directory left in the filename, we need to prepend a "../" */ while ((sepindex = astring_chr(tempfile, 0, PATH_SEPARATOR[0])) != -1) { astring_substr(tempfile, sepindex + 1, -1); astring_insc(srcincpath, 0, "../"); } astring_catc(srcincpath, ".html"); /* free the strings and return the include path */ astring_free(tempfile); astring_free(tempinc); return srcincpath; } /* free our include path */ astring_free(srcincpath); } return NULL; }