X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=laserbrain_demo;a=blobdiff_plain;f=src%2Fdatamap.cc;h=626c47f88d71375a8effc8d3afe727b0cba3dfd7;hp=bf8854c60cb7e10a8d19bd58241b2077307da5ee;hb=8137121400748ee8afb1608253aae15323c5e3a2;hpb=516e9be0443cfd7f844feb9b8299f909075b7c3c diff --git a/src/datamap.cc b/src/datamap.cc index bf8854c..626c47f 100644 --- a/src/datamap.cc +++ b/src/datamap.cc @@ -1,44 +1,158 @@ +#include +#include +#include #include #include #include +#include #include "datamap.h" -static std::vector> dmap; +#ifdef WIN32 +#include +#else +#include +#endif + +static char *clean_line(char *s); + +static std::vector> dmap; static std::map cache; static std::string root; -void datmap_reset() +void datamap_reset() { root.clear(); dmap.clear(); cache.clear(); } -void datmap_set_path(const char *path) +void datamap_set_path(const char *path) { root = std::string(path); } -bool datmap_load_map(const char *fname) +bool datamap_load_map(const char *fname) { std::string path = root.empty() ? fname : root + std::string("/") + fname; - return false; // TODO cont... + fname = path.c_str(); + + FILE *fp = fopen(fname, "r"); + if(!fp) { + fprintf(stderr, "failed to open data map: %s\n", fname); + return false; + } + + char buf[256]; + if(fread(buf, 1, 8, fp) < 8 || memcmp(buf, "DATAMAP0", 8) != 0) { + fprintf(stderr, "invalid datamap file: %s\n", fname); + fclose(fp); + return false; + } + + datamap_reset(); + + char *line; + int nline = 0; + while(fgets(buf, sizeof buf, fp)) { + ++nline; + line = clean_line(buf); + if(!line || !*line) continue; + + char *colon = strchr(line, ':'); + if(!colon) { + goto err; + } + *colon = 0; + + std::pair pair; + pair.first = std::regex(line); + + char *value = clean_line(colon + 1); + if(!value || !*value) { + goto err; + } + pair.second = std::string(value); + dmap.push_back(pair); + } + fclose(fp); + + printf("loaded datamap %s: %d mappings\n", fname, (int)dmap.size()); + return true; + +err: + fprintf(stderr, "error while parsing %s, invalid line %d: %s\n", fname, nline, line); + datamap_reset(); + fclose(fp); + return false; } -void datmap_map(const char *re, const char *path) +void datamap_map(const char *re, const char *path) { - std::pair mapping; - mapping.first = std::string(re); + std::pair mapping; + mapping.first = std::regex(re); mapping.second = std::string(path); - dmap.push_back(mapping); + dmap.push_back(std::move(mapping)); +} + +int datamap_lookup(const char *in, char *buf, int bsz) +{ + std::string res; + + char *inbuf = (char*)alloca(strlen(in) + 1); + strcpy(inbuf, in); + in = clean_line(inbuf); + + // first check the cache + std::map::iterator it = cache.find(in); + if(it != cache.end()) { + res = it->second; + } else { + // try matching with the available mappings + int num = dmap.size(); + for(int i=0; i s && isspace(*end)) --end; + if(s == end) return 0; + end[1] = 0; + + // app-specific: convert backslashes + char *c = s; + while(*c) { + if(*c == '\\') *c = '/'; + ++c; + } + + return s; }