mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-02 16:35:40 +02:00
Throw instead of exiting from the tile clipping and overzooming code
The code reachable from overzooming a tile no longer calls exit(). It reports errors by throwing tippecanoe_error, and owns its FILE * and json_pull * handles through RAII wrappers so that nothing leaks when an error unwinds the stack. New files: * errors.hpp/errors.cpp: the tippecanoe_error exception class, plus throw_tippecanoe_error() and throw_perror() helpers. * raii.hpp: unique_file and unique_json_pull, both std::unique_ptr aliases, for FILE * and json_pull *. exit() becomes throw in clip.cpp, mvt.cpp, mvt.hpp, read_json.cpp, evaluator.cpp, text.cpp, geometry.cpp, attribute.cpp, and write_json.hpp. Each tool's main() is now a try/catch around an inner_main(), so the command-line tools exit with the status they always did. Along the way this fixes a z_stream leaked when compress() failed, an exit() that could run from json_writer's destructor during unwinding, and an exit() in mvt_value's hash function. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DuCSVGssWNUCpVEE8Yp5HT
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include "milo/dtoa_milo.h"
|
||||
#include "milo/milo.h"
|
||||
#include "errors.hpp"
|
||||
#include "raii.hpp"
|
||||
|
||||
/**
|
||||
* Returns an empty string if `s` is valid utf8;
|
||||
@@ -135,7 +136,7 @@ int integer_zoom(std::string where, std::string text) {
|
||||
double d = atof(text.c_str());
|
||||
if (!std::isfinite(d) || d != floor(d) || d < 0 || d > 32) {
|
||||
fprintf(stderr, "%s: Expected integer zoom level in \"tippecanoe\" GeoJSON extension, not %s\n", where.c_str(), text.c_str());
|
||||
exit(EXIT_JSON);
|
||||
throw_tippecanoe_error(EXIT_JSON, "%s: Expected integer zoom level in \"tippecanoe\" GeoJSON extension, not %s", where.c_str(), text.c_str());
|
||||
}
|
||||
return d;
|
||||
}
|
||||
@@ -181,8 +182,7 @@ char *dtoa_milo(double val) {
|
||||
std::string s = milo::dtoa_milo(val);
|
||||
char *dup = strdup(s.c_str());
|
||||
if (dup == NULL) {
|
||||
perror("strdup");
|
||||
exit(EXIT_MEMORY);
|
||||
throw_perror(EXIT_MEMORY, "strdup");
|
||||
}
|
||||
return dup;
|
||||
}
|
||||
@@ -191,25 +191,22 @@ char *dtoa_milo(double val) {
|
||||
std::vector<std::string> read_unidecode(const char *fname) {
|
||||
std::string data;
|
||||
|
||||
FILE *f = fopen(fname, "rb");
|
||||
unique_file f(fopen(fname, "rb"));
|
||||
if (f == NULL) {
|
||||
perror(fname);
|
||||
exit(EXIT_OPEN);
|
||||
throw_perror(EXIT_OPEN, fname);
|
||||
}
|
||||
|
||||
std::string buf;
|
||||
buf.resize(2000);
|
||||
|
||||
while (true) {
|
||||
size_t nread = fread((void *) buf.c_str(), sizeof(char), buf.size(), f);
|
||||
size_t nread = fread((void *) buf.c_str(), sizeof(char), buf.size(), f.get());
|
||||
if (nread == 0) {
|
||||
break;
|
||||
}
|
||||
data.append(buf.c_str(), nread);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
std::vector<std::string> out;
|
||||
out.emplace_back(); // because the data file is 1-indexed
|
||||
out.emplace_back(); // ascii 001
|
||||
|
||||
Reference in New Issue
Block a user