7 #if defined(WIN32) || defined(__WIN32__)
13 static char *clean_line(char *s);
26 void DataMap::set_path(const char *path)
28 root = std::string(path);
31 void DataMap::set_strip(bool s)
36 bool DataMap::load_map(const char *fname)
38 std::string path = root.empty() ? fname : root + std::string("/") + fname;
41 FILE *fp = fopen(fname, "r");
43 fprintf(stderr, "failed to open data map: %s\n", fname);
48 if(fread(buf, 1, 8, fp) < 8 || memcmp(buf, "DATAMAP0", 8) != 0) {
49 fprintf(stderr, "invalid datamap file: %s\n", fname);
58 while(fgets(buf, sizeof buf, fp)) {
60 line = clean_line(buf);
61 if(!line || !*line) continue;
63 char *colon = strchr(line, ':');
69 //std::pair<std::regex, std::string> pair;
70 //pair.first = std::regex(line);
71 std::pair<std::string, std::string> pair;
72 pair.first = std::string(line);
74 char *value = clean_line(colon + 1);
75 if(!value || !*value) {
78 pair.second = std::string(value);
83 printf("loaded datamap %s: %d mappings\n", fname, (int)dmap.size());
87 fprintf(stderr, "error while parsing %s, invalid line %d: %s\n", fname, nline, line);
93 void DataMap::map(const char *match, const char *path)
95 std::pair<std::string, std::string> mapping;
96 mapping.first = std::string(match);
97 mapping.second = std::string(path);
98 dmap.push_back(std::move(mapping));
101 int DataMap::lookup(const char *in, char *buf, int bsz) const
106 const char *ptr = strrchr(in, '/');
112 char *inbuf = (char*)alloca(strlen(in) + 1);
114 in = clean_line(inbuf);
116 // first check the cache
117 std::map<std::string, std::string>::iterator it = cache.find(in);
118 if(it != cache.end()) {
121 // try matching with the available mappings
122 res = root.empty() ? std::string(in) : root + "/" + std::string(in);
124 int num = dmap.size();
125 for(int i=0; i<num; i++) {
126 //if(std::regex_search(in, dmap[i].first)) {
127 if(strstr(in, dmap[i].first.c_str())) {
128 res = root.empty() ? dmap[i].second : root + "/" + dmap[i].second;
129 cache[in] = res; // add it to the cache
135 // copy result in buf, truncating if necessary and return the size of the
136 // buffer required to hold it
138 int n = std::min(bsz - 1, (int)res.length());
139 memcpy(buf, res.c_str(), n);
140 buf[n] = 0; // make sure it's null-terminated even if it got truncated
142 return res.length() + 1;
145 int DataMap::path_size(const char *in) const
147 return lookup(in, 0, 0);
150 static char *clean_line(char *s)
152 while(*s && isspace(*s)) ++s;
156 if(!(end = strchr(s, '#'))) {
157 end = s + strlen(s) - 1;
159 while(end > s && isspace(*end)) --end;
160 if(s == end) return 0;
163 // app-specific: convert backslashes
166 if(*c == '\\') *c = '/';