1
0
forked from GitHub/gf-core

better error handling which always reports the right file name

This commit is contained in:
krangelov
2021-09-07 15:54:27 +02:00
parent 8936e6211e
commit a843ddba55
11 changed files with 95 additions and 49 deletions

View File

@@ -30,6 +30,35 @@ private:
const char *msg; const char *msg;
}; };
class PGF_INTERNAL_DECL pgf_systemerror : public std::runtime_error {
public:
pgf_systemerror(int code) : std::runtime_error("pgf_systemerror")
{
this->m_code = code;
this->m_filepath = NULL;
}
pgf_systemerror(int code, const char *filepath) : std::runtime_error("pgf_systemerror")
{
this->m_code = code;
this->m_filepath = filepath;
}
virtual int code() const
{
return m_code;
}
const char *filepath() const
{
return m_filepath;
}
private:
int m_code;
const char *m_filepath;
};
struct PGF_INTERNAL_DECL PgfFlag { struct PGF_INTERNAL_DECL PgfFlag {
PgfLiteral value; PgfLiteral value;
PgfText name; PgfText name;

View File

@@ -2,7 +2,6 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <system_error>
#include "data.h" #include "data.h"
@@ -270,30 +269,33 @@ struct malloc_state
}; };
PGF_INTERNAL PGF_INTERNAL
PgfDB::PgfDB(const char* pathname, int flags, int mode) { PgfDB::PgfDB(const char* filepath, int flags, int mode) {
size_t file_size; size_t file_size;
bool is_new = false; bool is_new = false;
fd = -1; fd = -1;
ms = NULL; ms = NULL;
if (pathname == NULL) { if (filepath == NULL) {
this->filepath = NULL;
file_size = getpagesize(); file_size = getpagesize();
is_new = true; is_new = true;
} else { } else {
fd = open(pathname, flags, mode); fd = open(filepath, flags, mode);
if (fd < 0) if (fd < 0)
throw std::system_error(errno, std::generic_category()); throw pgf_systemerror(errno, filepath);
this->filepath = strdup(filepath);
file_size = lseek(fd, 0, SEEK_END); file_size = lseek(fd, 0, SEEK_END);
if (file_size == ((off_t) -1)) if (file_size == ((off_t) -1))
throw std::system_error(errno, std::generic_category()); throw pgf_systemerror(errno, filepath);
is_new = false; is_new = false;
if (file_size == 0) { if (file_size == 0) {
file_size = getpagesize(); file_size = getpagesize();
if (ftruncate(fd, file_size) < 0) if (ftruncate(fd, file_size) < 0)
throw std::system_error(errno, std::generic_category()); throw pgf_systemerror(errno, filepath);
is_new = true; is_new = true;
} }
} }
@@ -302,7 +304,7 @@ PgfDB::PgfDB(const char* pathname, int flags, int mode) {
ms = (malloc_state*) ms = (malloc_state*)
mmap(NULL, file_size, PROT_READ | PROT_WRITE, mflags, fd, 0); mmap(NULL, file_size, PROT_READ | PROT_WRITE, mflags, fd, 0);
if (ms == MAP_FAILED) if (ms == MAP_FAILED)
throw std::system_error(errno, std::generic_category()); throw pgf_systemerror(errno, filepath);
if (is_new) { if (is_new) {
init_state(file_size); init_state(file_size);
@@ -310,7 +312,7 @@ PgfDB::PgfDB(const char* pathname, int flags, int mode) {
int res = pthread_rwlock_init(&rwlock, NULL); int res = pthread_rwlock_init(&rwlock, NULL);
if (res != 0) { if (res != 0) {
throw std::system_error(res, std::generic_category()); throw pgf_systemerror(errno);
} }
} }
@@ -327,6 +329,8 @@ PgfDB::~PgfDB() {
close(fd); close(fd);
pthread_rwlock_destroy(&rwlock); pthread_rwlock_destroy(&rwlock);
::free((void*) filepath);
} }
PGF_INTERNAL PGF_INTERNAL
@@ -338,7 +342,7 @@ void PgfDB::sync()
int res = msync((void *) ms, size, MS_SYNC | MS_INVALIDATE); int res = msync((void *) ms, size, MS_SYNC | MS_INVALIDATE);
if (res != 0) if (res != 0)
throw std::system_error(errno, std::generic_category()); throw pgf_systemerror(errno);
} }
PGF_INTERNAL PGF_INTERNAL
@@ -837,13 +841,13 @@ object PgfDB::malloc_internal(size_t bytes)
if (fd >= 0) { if (fd >= 0) {
if (ftruncate(fd, new_size) < 0) if (ftruncate(fd, new_size) < 0)
throw std::system_error(errno, std::generic_category()); throw pgf_systemerror(errno, filepath);
} }
malloc_state* new_ms = malloc_state* new_ms =
(malloc_state*) mremap(ms, old_size, new_size, MREMAP_MAYMOVE); (malloc_state*) mremap(ms, old_size, new_size, MREMAP_MAYMOVE);
if (new_ms == MAP_FAILED) if (new_ms == MAP_FAILED)
throw std::system_error(errno, std::generic_category()); throw pgf_systemerror(errno);
ms = new_ms; ms = new_ms;
current_base = (unsigned char*) ms; current_base = (unsigned char*) ms;
@@ -961,7 +965,7 @@ DB_scope::DB_scope(PgfDB *db, DB_scope_mode tp)
(tp == READER_SCOPE) ? pthread_rwlock_rdlock(&db->rwlock) (tp == READER_SCOPE) ? pthread_rwlock_rdlock(&db->rwlock)
: pthread_rwlock_wrlock(&db->rwlock); : pthread_rwlock_wrlock(&db->rwlock);
if (res != 0) if (res != 0)
throw std::system_error(res, std::generic_category()); throw pgf_systemerror(res);
save_db = current_db; save_db = current_db;
current_db = db; current_db = db;
@@ -978,7 +982,7 @@ DB_scope::~DB_scope()
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wterminate" #pragma GCC diagnostic ignored "-Wterminate"
if (res != 0) if (res != 0)
throw std::system_error(res, std::generic_category()); throw pgf_systemerror(res);
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
current_db = save_db; current_db = save_db;

View File

@@ -57,6 +57,7 @@ public:
class PgfDB { class PgfDB {
private: private:
int fd; int fd;
const char *filepath;
malloc_state* ms; malloc_state* ms;
pthread_rwlock_t rwlock; pthread_rwlock_t rwlock;
@@ -64,7 +65,7 @@ private:
friend class PgfReader; friend class PgfReader;
public: public:
PGF_INTERNAL_DECL PgfDB(const char* pathname, int flags, int mode); PGF_INTERNAL_DECL PgfDB(const char* filepath, int flags, int mode);
PGF_INTERNAL_DECL ~PgfDB(); PGF_INTERNAL_DECL ~PgfDB();
template<class A> template<class A>

View File

@@ -23,16 +23,15 @@ PgfDB *pgf_read_pgf(const char* fpath,
try { try {
db = new PgfDB(NULL, 0, 0); db = new PgfDB(NULL, 0, 0);
std::ifstream in(fpath, std::ios::binary); std::ifstream in(fpath, std::ios::binary);
if (in.fail()) { if (in.fail()) {
throw std::system_error(errno, std::generic_category()); throw pgf_systemerror(errno, fpath);
} }
{ {
DB_scope scope(db, WRITER_SCOPE); DB_scope scope(db, WRITER_SCOPE);
PgfReader rdr(&in); PgfReader rdr(&in, fpath);
ref<PgfPGF> pgf = rdr.read_pgf(); ref<PgfPGF> pgf = rdr.read_pgf();
PgfDB::set_root(pgf); PgfDB::set_root(pgf);
@@ -40,14 +39,16 @@ PgfDB *pgf_read_pgf(const char* fpath,
} }
return db; return db;
} catch (std::system_error& e) { } catch (pgf_systemerror& e) {
err->type = PGF_EXN_SYSTEM_ERROR; err->type = PGF_EXN_SYSTEM_ERROR;
err->code = e.code().value(); err->code = e.code();
err->msg = e.filepath();
} catch (pgf_error& e) { } catch (pgf_error& e) {
err->type = PGF_EXN_PGF_ERROR; err->type = PGF_EXN_PGF_ERROR;
err->msg = strdup(e.what()); err->msg = strdup(e.what());
} }
end:
if (db != NULL) if (db != NULL)
delete db; delete db;
@@ -68,13 +69,13 @@ PgfDB *pgf_boot_ngf(const char* pgf_path, const char* ngf_path,
std::ifstream in(pgf_path, std::ios::binary); std::ifstream in(pgf_path, std::ios::binary);
if (in.fail()) { if (in.fail()) {
throw std::system_error(errno, std::generic_category()); throw pgf_systemerror(errno, pgf_path);
} }
{ {
DB_scope scope(db, WRITER_SCOPE); DB_scope scope(db, WRITER_SCOPE);
PgfReader rdr(&in); PgfReader rdr(&in, pgf_path);
ref<PgfPGF> pgf = rdr.read_pgf(); ref<PgfPGF> pgf = rdr.read_pgf();
db->set_root<PgfPGF>(pgf); db->set_root<PgfPGF>(pgf);
@@ -84,9 +85,10 @@ PgfDB *pgf_boot_ngf(const char* pgf_path, const char* ngf_path,
} }
return db; return db;
} catch (std::system_error& e) { } catch (pgf_systemerror& e) {
err->type = PGF_EXN_SYSTEM_ERROR; err->type = PGF_EXN_SYSTEM_ERROR;
err->code = e.code().value(); err->code = e.code();
err->msg = e.filepath();
} catch (pgf_error& e) { } catch (pgf_error& e) {
err->type = PGF_EXN_PGF_ERROR; err->type = PGF_EXN_PGF_ERROR;
err->msg = strdup(e.what()); err->msg = strdup(e.what());
@@ -135,9 +137,10 @@ PgfDB *pgf_read_ngf(const char *fpath,
} }
return db; return db;
} catch (std::system_error& e) { } catch (pgf_systemerror& e) {
err->type = PGF_EXN_SYSTEM_ERROR; err->type = PGF_EXN_SYSTEM_ERROR;
err->code = e.code().value(); err->code = e.code();
err->msg = e.filepath();
} catch (pgf_error& e) { } catch (pgf_error& e) {
err->type = PGF_EXN_PGF_ERROR; err->type = PGF_EXN_PGF_ERROR;
err->msg = strdup(e.what()); err->msg = strdup(e.what());
@@ -431,9 +434,10 @@ PgfRevision pgf_clone_revision(PgfDB *db, PgfRevision revision,
pgf->abstract.cats->ref_count++; pgf->abstract.cats->ref_count++;
return new_pgf.as_object(); return new_pgf.as_object();
} catch (std::system_error& e) { } catch (pgf_systemerror& e) {
err->type = PGF_EXN_SYSTEM_ERROR; err->type = PGF_EXN_SYSTEM_ERROR;
err->code = e.code().value(); err->code = e.code();
err->msg = e.filepath();
} catch (pgf_error& e) { } catch (pgf_error& e) {
err->type = PGF_EXN_PGF_ERROR; err->type = PGF_EXN_PGF_ERROR;
err->msg = strdup(e.what()); err->msg = strdup(e.what());
@@ -471,9 +475,10 @@ void pgf_create_function(PgfDB *db, PgfRevision revision,
namespace_insert(pgf->abstract.funs, absfun); namespace_insert(pgf->abstract.funs, absfun);
namespace_release(pgf->abstract.funs); namespace_release(pgf->abstract.funs);
pgf->abstract.funs = nmsp; pgf->abstract.funs = nmsp;
} catch (std::system_error& e) { } catch (pgf_systemerror& e) {
err->type = PGF_EXN_SYSTEM_ERROR; err->type = PGF_EXN_SYSTEM_ERROR;
err->code = e.code().value(); err->code = e.code();
err->msg = e.filepath();
} catch (pgf_error& e) { } catch (pgf_error& e) {
err->type = PGF_EXN_PGF_ERROR; err->type = PGF_EXN_PGF_ERROR;
err->msg = strdup(e.what()); err->msg = strdup(e.what());

View File

@@ -55,6 +55,7 @@ typedef struct {
* - If the exception was caused by external factors such as an error * - If the exception was caused by external factors such as an error
* from a system call, then type will be PGF_EXN_SYSTEM_ERROR and * from a system call, then type will be PGF_EXN_SYSTEM_ERROR and
* the field code will contain the value of errno from the C runtime. * the field code will contain the value of errno from the C runtime.
* The field msg will be NULL or it may contain a file name.
* *
* - If the exception was caused by factors related to the GF runtime * - If the exception was caused by factors related to the GF runtime
* itself, then the error type is PGF_EXN_PGF_ERROR, and the field * itself, then the error type is PGF_EXN_PGF_ERROR, and the field

View File

@@ -3,9 +3,10 @@
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
PgfReader::PgfReader(std::istream *in) PgfReader::PgfReader(std::istream *in, const char *filepath)
{ {
this->in = in; this->in = in;
this->filepath = filepath;
} }
uint8_t PgfReader::read_uint8() uint8_t PgfReader::read_uint8()
@@ -15,7 +16,7 @@ uint8_t PgfReader::read_uint8()
if (in->eof()) if (in->eof())
throw pgf_error("reached end of file while reading a grammar"); throw pgf_error("reached end of file while reading a grammar");
if (in->fail()) if (in->fail())
throw std::system_error(errno, std::generic_category()); throw pgf_systemerror(errno, filepath);
return b; return b;
} }
@@ -27,7 +28,7 @@ uint16_t PgfReader::read_u16be()
if (in->eof()) if (in->eof())
throw pgf_error("reached end of file while reading a grammar"); throw pgf_error("reached end of file while reading a grammar");
if (in->fail()) if (in->fail())
throw std::system_error(errno, std::generic_category()); throw pgf_systemerror(errno, filepath);
return (((uint16_t) buf[0]) << 8 | buf[1]); return (((uint16_t) buf[0]) << 8 | buf[1]);
} }
@@ -39,7 +40,7 @@ uint64_t PgfReader::read_u64be()
if (in->eof()) if (in->eof())
throw pgf_error("reached end of file while reading a grammar"); throw pgf_error("reached end of file while reading a grammar");
if (in->fail()) if (in->fail())
throw std::system_error(errno, std::generic_category()); throw pgf_systemerror(errno, filepath);
return (((uint64_t) buf[0]) << 56 | return (((uint64_t) buf[0]) << 56 |
((uint64_t) buf[1]) << 48 | ((uint64_t) buf[1]) << 48 |
@@ -95,7 +96,7 @@ object PgfReader::read_name_internal(size_t struct_size)
if (in->eof()) if (in->eof())
throw pgf_error("utf8 decoding error"); throw pgf_error("utf8 decoding error");
if (in->fail()) if (in->fail())
throw std::system_error(errno, std::generic_category()); throw pgf_systemerror(errno, filepath);
ptext->text[size] = 0; ptext->text[size] = 0;
@@ -131,7 +132,7 @@ object PgfReader::read_text_internal(size_t struct_size)
if (in->eof()) if (in->eof())
throw pgf_error("utf8 decoding error"); throw pgf_error("utf8 decoding error");
if (in->fail()) if (in->fail())
throw std::system_error(errno, std::generic_category()); throw pgf_systemerror(errno, filepath);
p += len; p += len;
} }

View File

@@ -10,7 +10,7 @@
class PGF_INTERNAL_DECL PgfReader class PGF_INTERNAL_DECL PgfReader
{ {
public: public:
PgfReader(std::istream *in); PgfReader(std::istream *in, const char *filepath);
uint8_t read_uint8(); uint8_t read_uint8();
uint16_t read_u16be(); uint16_t read_u16be();
@@ -74,6 +74,7 @@ public:
private: private:
std::istream *in; std::istream *in;
const char* filepath;
object read_name_internal(size_t struct_size); object read_name_internal(size_t struct_size);
object read_text_internal(size_t struct_size); object read_text_internal(size_t struct_size);

View File

@@ -69,7 +69,7 @@ readPGF fpath =
withCString fpath $ \c_fpath -> withCString fpath $ \c_fpath ->
alloca $ \p_revision -> alloca $ \p_revision ->
mask_ $ do mask_ $ do
c_pgf <- withPgfExn fpath (pgf_read_pgf c_fpath p_revision) c_pgf <- withPgfExn (pgf_read_pgf c_fpath p_revision)
c_revision <- peek p_revision c_revision <- peek p_revision
fptr1 <- newForeignPtr pgf_free_fptr c_pgf fptr1 <- newForeignPtr pgf_free_fptr c_pgf
fptr2 <- C.newForeignPtr c_revision (withForeignPtr fptr1 (\c_db -> pgf_free_revision c_db c_revision)) fptr2 <- C.newForeignPtr c_revision (withForeignPtr fptr1 (\c_db -> pgf_free_revision c_db c_revision))
@@ -85,7 +85,7 @@ bootNGF pgf_path ngf_path =
withCString ngf_path $ \c_ngf_path -> withCString ngf_path $ \c_ngf_path ->
alloca $ \p_revision -> alloca $ \p_revision ->
mask_ $ do mask_ $ do
c_pgf <- withPgfExn pgf_path (pgf_boot_ngf c_pgf_path c_ngf_path p_revision) c_pgf <- withPgfExn (pgf_boot_ngf c_pgf_path c_ngf_path p_revision)
c_revision <- peek p_revision c_revision <- peek p_revision
fptr1 <- newForeignPtr pgf_free_fptr c_pgf fptr1 <- newForeignPtr pgf_free_fptr c_pgf
fptr2 <- C.newForeignPtr c_revision (withForeignPtr fptr1 (\c_db -> pgf_free_revision c_db c_revision)) fptr2 <- C.newForeignPtr c_revision (withForeignPtr fptr1 (\c_db -> pgf_free_revision c_db c_revision))
@@ -100,7 +100,7 @@ readNGF fpath =
withCString fpath $ \c_fpath -> withCString fpath $ \c_fpath ->
alloca $ \p_revision -> alloca $ \p_revision ->
mask_ $ do mask_ $ do
c_db <- withPgfExn fpath (pgf_read_ngf c_fpath p_revision) c_db <- withPgfExn (pgf_read_ngf c_fpath p_revision)
c_revision <- peek p_revision c_revision <- peek p_revision
fptr1 <- newForeignPtr pgf_free_fptr c_db fptr1 <- newForeignPtr pgf_free_fptr c_db
fptr2 <- C.newForeignPtr c_revision (withForeignPtr fptr1 (\c_db -> pgf_free_revision c_db c_revision)) fptr2 <- C.newForeignPtr c_revision (withForeignPtr fptr1 (\c_db -> pgf_free_revision c_db c_revision))
@@ -175,7 +175,7 @@ categories p =
withForeignPtr (a_db p) $ \c_db -> withForeignPtr (a_db p) $ \c_db ->
withForeignPtr (revision p) $ \c_revision -> do withForeignPtr (revision p) $ \c_revision -> do
(#poke PgfItor, fn) itor fptr (#poke PgfItor, fn) itor fptr
withPgfExn "" (pgf_iter_categories c_db c_revision itor) withPgfExn (pgf_iter_categories c_db c_revision itor)
cs <- readIORef ref cs <- readIORef ref
return (reverse cs)) return (reverse cs))
where where
@@ -234,7 +234,7 @@ functions p =
withForeignPtr (a_db p) $ \c_db -> withForeignPtr (a_db p) $ \c_db ->
withForeignPtr (revision p) $ \c_revision -> do withForeignPtr (revision p) $ \c_revision -> do
(#poke PgfItor, fn) itor fptr (#poke PgfItor, fn) itor fptr
withPgfExn "" (pgf_iter_functions c_db c_revision itor) withPgfExn (pgf_iter_functions c_db c_revision itor)
fs <- readIORef ref fs <- readIORef ref
return (reverse fs)) return (reverse fs))
where where
@@ -255,7 +255,7 @@ functionsByCat p cat =
withForeignPtr (a_db p) $ \c_db -> withForeignPtr (a_db p) $ \c_db ->
withForeignPtr (revision p) $ \c_revision -> do withForeignPtr (revision p) $ \c_revision -> do
(#poke PgfItor, fn) itor fptr (#poke PgfItor, fn) itor fptr
withPgfExn "" (pgf_iter_functions_by_cat c_db c_revision c_cat itor) withPgfExn (pgf_iter_functions_by_cat c_db c_revision c_cat itor)
fs <- readIORef ref fs <- readIORef ref
return (reverse fs)) return (reverse fs))
where where

View File

@@ -193,7 +193,7 @@ newtype PGFError = PGFError String
instance Exception PGFError instance Exception PGFError
withPgfExn fpath f = withPgfExn f =
allocaBytes (#size PgfExn) $ \c_exn -> do allocaBytes (#size PgfExn) $ \c_exn -> do
res <- f c_exn res <- f c_exn
ex_type <- (#peek PgfExn, type) c_exn :: IO (#type PgfExnType) ex_type <- (#peek PgfExn, type) c_exn :: IO (#type PgfExnType)
@@ -201,7 +201,11 @@ withPgfExn fpath f =
(#const PGF_EXN_NONE) -> return res (#const PGF_EXN_NONE) -> return res
(#const PGF_EXN_SYSTEM_ERROR) -> do (#const PGF_EXN_SYSTEM_ERROR) -> do
errno <- (#peek PgfExn, code) c_exn errno <- (#peek PgfExn, code) c_exn
ioError (errnoToIOError "readPGF" (Errno errno) Nothing (Just fpath)) c_msg <- (#peek PgfExn, msg) c_exn
mb_fpath <- if c_msg == nullPtr
then return Nothing
else fmap Just (peekCString c_msg)
ioError (errnoToIOError "readPGF" (Errno errno) Nothing mb_fpath)
(#const PGF_EXN_PGF_ERROR) -> do (#const PGF_EXN_PGF_ERROR) -> do
c_msg <- (#peek PgfExn, msg) c_exn c_msg <- (#peek PgfExn, msg) c_exn
msg <- peekCString c_msg msg <- peekCString c_msg

View File

@@ -42,7 +42,7 @@ modifyPGF :: PGF -> Transaction a -> IO PGF
modifyPGF p (Transaction f) = modifyPGF p (Transaction f) =
withForeignPtr (a_db p) $ \c_db -> withForeignPtr (a_db p) $ \c_db ->
withForeignPtr (revision p) $ \c_revision -> withForeignPtr (revision p) $ \c_revision ->
withPgfExn "" $ \c_exn -> do withPgfExn $ \c_exn -> do
c_revision <- pgf_clone_revision c_db c_revision c_exn c_revision <- pgf_clone_revision c_db c_revision c_exn
ex_type <- (#peek PgfExn, type) c_exn ex_type <- (#peek PgfExn, type) c_exn
if (ex_type :: (#type PgfExnType)) == (#const PGF_EXN_NONE) if (ex_type :: (#type PgfExnType)) == (#const PGF_EXN_NONE)

View File

@@ -2391,7 +2391,7 @@ pgf_readPGF(PyObject *self, PyObject *args)
py_pgf->db = pgf_read_pgf(fpath, &py_pgf->revision, &err); py_pgf->db = pgf_read_pgf(fpath, &py_pgf->revision, &err);
if (err.type == PGF_EXN_SYSTEM_ERROR) { if (err.type == PGF_EXN_SYSTEM_ERROR) {
errno = err.code; errno = err.code;
PyErr_SetFromErrnoWithFilename(PyExc_IOError, fpath); PyErr_SetFromErrnoWithFilename(PyExc_IOError, err.msg);
Py_DECREF(py_pgf); Py_DECREF(py_pgf);
return NULL; return NULL;
} else if (err.type == PGF_EXN_PGF_ERROR) { } else if (err.type == PGF_EXN_PGF_ERROR) {
@@ -2419,7 +2419,7 @@ pgf_bootNGF(PyObject *self, PyObject *args)
py_pgf->db = pgf_boot_ngf(fpath, npath, &py_pgf->revision, &err); py_pgf->db = pgf_boot_ngf(fpath, npath, &py_pgf->revision, &err);
if (err.type == PGF_EXN_SYSTEM_ERROR) { if (err.type == PGF_EXN_SYSTEM_ERROR) {
errno = err.code; errno = err.code;
PyErr_SetFromErrnoWithFilename(PyExc_IOError, npath); PyErr_SetFromErrnoWithFilename(PyExc_IOError, err.msg);
Py_DECREF(py_pgf); Py_DECREF(py_pgf);
return NULL; return NULL;
} else if (err.type == PGF_EXN_PGF_ERROR) { } else if (err.type == PGF_EXN_PGF_ERROR) {
@@ -2446,7 +2446,7 @@ pgf_readNGF(PyObject *self, PyObject *args)
py_pgf->db = pgf_read_ngf(fpath, &py_pgf->revision, &err); py_pgf->db = pgf_read_ngf(fpath, &py_pgf->revision, &err);
if (err.type == PGF_EXN_SYSTEM_ERROR) { if (err.type == PGF_EXN_SYSTEM_ERROR) {
errno = err.code; errno = err.code;
PyErr_SetFromErrnoWithFilename(PyExc_IOError, fpath); PyErr_SetFromErrnoWithFilename(PyExc_IOError, err.msg);
Py_DECREF(py_pgf); Py_DECREF(py_pgf);
return NULL; return NULL;
} else if (err.type == PGF_EXN_PGF_ERROR) { } else if (err.type == PGF_EXN_PGF_ERROR) {