Fl_String Fl_XmlLocator::error_line(const char *filename, const Fl_XmlLocator &locator) { FILE *fp = fopen(filename, "r"); if(!fp) return ""; int line = locator.line(); int col = locator.col(); char linebuffer[1024]; for(int i=0; i<line-1 && !feof(fp);) { int c = fgetc(fp); if(c=='\n') i++; } fread(linebuffer, 1, 1024, fp); fclose(fp); Fl_String line_str(linebuffer); if(line_str.pos('\n')>0) line_str = line_str.sub_str(0, line_str.pos('\n')); if(line_str.length()>=79) line_str.sub_delete(79, line_str.length()-79); line_str += "\n"; for(int j=2; j<col; j++) line_str += "-"; line_str += "^"; return line_str; }
// Load Hipparcos catalog // The catalog is a (n,3) cv::Mat of mag, ra, de cv::Mat load_catalog(const char* filename) { cv::Mat catalog(0, 3, CV_32FC1); std::ifstream file(filename); std::string line, cell; if (!file) { std::cerr << "Can't open catalog " << filename << std::endl; return catalog; } // Skip first line std::getline(file, line); // Extract each line data while (std::getline(file, line)) { std::stringstream line_str(line); // Read fields double hip(0.0), mag(0.0), ra(0.0), de(0.0); line_str >> hip; line_str.get(); line_str >> mag; line_str.get(); line_str >> ra; line_str.get(); line_str >> de; line_str.get(); // Convert angles to radians const double deg_to_rad = M_PI / 180.0; cv::Mat catline = (cv::Mat_<float>(1,3) << mag, ra * deg_to_rad, de * deg_to_rad); catalog.push_back(catline); } return catalog; }
VSMap *readSettings(const std::string &path) { VSMap *settings = vsapi.createMap(); std::string err; FILE *f = fopen(path.c_str(), "rb"); if (!f) { // Ignore "No such file or directory" if (errno != ENOENT) { err.append("Couldn't open '").append(path).append("' for reading. Error: ").append(strerror(errno)); vsapi.setError(settings, err.c_str()); } return settings; } if (fseek(f, 0, SEEK_END)) { err.append("Couldn't find the size of '").append(path).append("' by seeking to its end. Error: ").append(strerror(errno)); vsapi.setError(settings, err.c_str()); fclose(f); return settings; } long size = ftell(f); if (size == -1) { err.append("Couldn't find the size of '").append(path).append("'. ftell failed with the error: ").append(strerror(errno)); vsapi.setError(settings, err.c_str()); fclose(f); return settings; } if (size > 100*1024) { err.append("Configuration file '").append(path).append("' is ridiculously large. Ignoring."); vsapi.setError(settings, err.c_str()); fclose(f); return settings; } rewind(f); std::vector<char> buffer(size); if (fread(buffer.data(), 1, size, f) != (size_t)size) { err.append("Didn't read the expected number of bytes from '").append(path).append("'."); vsapi.setError(settings, err.c_str()); fclose(f); return settings; } fclose(f); buffer.push_back('\n'); int key_start = 0, key_end = 0, value_start = 0, value_end = 0; err.append("Error while parsing '").append(path).append("': "); ParserStates state = WANT_KEY_START; int line = 1; std::string line_str(std::string("Line ").append(std::to_string(line)).append(": ")); for (int i = 0; i < size; i++) { switch (state) { case WANT_KEY_START: if (isAlphaNumUnderscore(buffer[i])) { key_start = i; state = WANT_KEY_CHAR; } break; case WANT_KEY_CHAR: if (buffer[i] == '\n') { err.append(line_str).append("No delimiter found before reaching the end of the line."); vsapi.setError(settings, err.c_str()); return settings; } else if (buffer[i] == ' ') { key_end = i - 1; state = WANT_DELIMITER; } else if (buffer[i] == '=') { key_end = i - 1; state = WANT_VALUE_START; } else if (!isAlphaNumUnderscore(buffer[i])) { err.append(line_str).append("Garbage found inside key."); vsapi.setError(settings, err.c_str()); return settings; } break; case WANT_DELIMITER: if (buffer[i] == '=') { state = WANT_VALUE_START; } else if (buffer[i] == '\n') { err.append(line_str).append("No delimiter found before reaching the end of the line."); vsapi.setError(settings, err.c_str()); return settings; } else { err.append(line_str).append("Expected '=' but found garbage instead."); vsapi.setError(settings, err.c_str()); return settings; } break; case WANT_VALUE_START: if (buffer[i] == '\n') { err.append(line_str).append("No value found for key before reaching the end of the line."); vsapi.setError(settings, err.c_str()); return settings; } if (buffer[i] != ' ') { value_start = i; state = WANT_VALUE_CHAR; } break; case WANT_VALUE_CHAR: if (buffer[i] == '\n') { value_end = i - 1; std::string key(&buffer[key_start], key_end - key_start + 1); std::string value(&buffer[value_start], value_end - value_start + 1); vsapi.propSetData(settings, key.c_str(), value.c_str(), value.size(), paReplace); state = WANT_KEY_START; } break; default: err.append(line_str).append("Shit broke. This should never happen."); vsapi.setError(settings, err.c_str()); return settings; break; } if (buffer[i] == '\n') { line++; line_str = std::string("Line ").append(std::to_string(line)).append(": "); } } return settings; }