mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-22 11:19:32 -06:00
readNGF now fails if the file doesn't exist. Instead there is newNGF
This commit is contained in:
@@ -118,31 +118,13 @@ PgfDB *pgf_read_ngf(const char *fpath,
|
|||||||
|
|
||||||
bool is_new = false;
|
bool is_new = false;
|
||||||
PGF_API_BEGIN {
|
PGF_API_BEGIN {
|
||||||
db = new PgfDB(fpath, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
db = new PgfDB(fpath, O_RDWR, 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
DB_scope scope(db, WRITER_SCOPE);
|
DB_scope scope(db, WRITER_SCOPE);
|
||||||
|
|
||||||
ref<PgfPGF> pgf = PgfDB::get_revision(&master);
|
ref<PgfPGF> pgf = PgfDB::get_revision(&master);
|
||||||
if (pgf == 0) {
|
Node<PgfPGF>::add_value_ref(pgf);
|
||||||
is_new = true;
|
|
||||||
pgf = PgfDB::malloc<PgfPGF>(master.size+1);
|
|
||||||
pgf->ref_count = 1;
|
|
||||||
pgf->major_version = PGF_MAJOR_VERSION;
|
|
||||||
pgf->minor_version = PGF_MINOR_VERSION;
|
|
||||||
pgf->gflags = 0;
|
|
||||||
pgf->abstract.name = PgfDB::malloc<PgfText>();
|
|
||||||
pgf->abstract.name->size = 0;
|
|
||||||
pgf->abstract.aflags = 0;
|
|
||||||
pgf->abstract.funs = 0;
|
|
||||||
pgf->abstract.cats = 0;
|
|
||||||
pgf->prev = 0;
|
|
||||||
pgf->next = 0;
|
|
||||||
memcpy(&pgf->name, &master, sizeof(PgfText)+master.size+1);
|
|
||||||
PgfDB::set_revision(pgf);
|
|
||||||
} else {
|
|
||||||
Node<PgfPGF>::add_value_ref(pgf);
|
|
||||||
}
|
|
||||||
*revision = pgf.as_object();
|
*revision = pgf.as_object();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,6 +140,49 @@ PgfDB *pgf_read_ngf(const char *fpath,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PGF_API
|
||||||
|
PgfDB *pgf_new_ngf(PgfText *abstract_name,
|
||||||
|
const char *fpath,
|
||||||
|
PgfRevision *revision,
|
||||||
|
PgfExn* err)
|
||||||
|
{
|
||||||
|
PgfDB *db = NULL;
|
||||||
|
|
||||||
|
PGF_API_BEGIN {
|
||||||
|
db = new PgfDB(fpath, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
|
||||||
|
|
||||||
|
{
|
||||||
|
DB_scope scope(db, WRITER_SCOPE);
|
||||||
|
|
||||||
|
ref<PgfPGF> pgf = PgfDB::malloc<PgfPGF>(master.size+1);
|
||||||
|
pgf->ref_count = 1;
|
||||||
|
pgf->major_version = PGF_MAJOR_VERSION;
|
||||||
|
pgf->minor_version = PGF_MINOR_VERSION;
|
||||||
|
pgf->gflags = 0;
|
||||||
|
pgf->abstract.name = PgfDB::malloc<PgfText>(abstract_name->size+1);
|
||||||
|
memcpy(&(*pgf->abstract.name), abstract_name, sizeof(PgfText)+abstract_name->size+1);
|
||||||
|
pgf->abstract.aflags = 0;
|
||||||
|
pgf->abstract.funs = 0;
|
||||||
|
pgf->abstract.cats = 0;
|
||||||
|
pgf->prev = 0;
|
||||||
|
pgf->next = 0;
|
||||||
|
memcpy(&pgf->name, &master, sizeof(PgfText)+master.size+1);
|
||||||
|
PgfDB::set_revision(pgf);
|
||||||
|
*revision = pgf.as_object();
|
||||||
|
}
|
||||||
|
|
||||||
|
return db;
|
||||||
|
} PGF_API_END
|
||||||
|
|
||||||
|
if (db != NULL) {
|
||||||
|
delete db;
|
||||||
|
if (fpath != NULL)
|
||||||
|
remove(fpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
PGF_API
|
PGF_API
|
||||||
void pgf_write_pgf(const char* fpath,
|
void pgf_write_pgf(const char* fpath,
|
||||||
PgfDB *db, PgfRevision revision,
|
PgfDB *db, PgfRevision revision,
|
||||||
|
|||||||
@@ -237,15 +237,23 @@ PgfDB *pgf_boot_ngf(const char* pgf_path, const char* ngf_path,
|
|||||||
PgfExn* err);
|
PgfExn* err);
|
||||||
|
|
||||||
/* Tries to read the grammar from an already booted NGF file.
|
/* Tries to read the grammar from an already booted NGF file.
|
||||||
* If the file does not exist then a new one is created, and the
|
* The function fails if the file does not exist. The default grammar
|
||||||
* grammar is set to be empty. It can later be populated with
|
* revision is stored in *revision. */
|
||||||
* rules dynamically. The default grammar revision is stored
|
|
||||||
* in *revision. */
|
|
||||||
PGF_API_DECL
|
PGF_API_DECL
|
||||||
PgfDB *pgf_read_ngf(const char* fpath,
|
PgfDB *pgf_read_ngf(const char* fpath,
|
||||||
PgfRevision *revision,
|
PgfRevision *revision,
|
||||||
PgfExn* err);
|
PgfExn* err);
|
||||||
|
|
||||||
|
/* Creates a new NGF file with a grammar with the given abstract_name.
|
||||||
|
* Aside from the name, the grammar is otherwise empty but can be later
|
||||||
|
* populated with new functions and categories. If fpath is NULL then
|
||||||
|
* the file is not stored on the disk but only in memory. */
|
||||||
|
PGF_API
|
||||||
|
PgfDB *pgf_new_ngf(PgfText *abstract_name,
|
||||||
|
const char *fpath,
|
||||||
|
PgfRevision *revision,
|
||||||
|
PgfExn* err);
|
||||||
|
|
||||||
PGF_API_DECL
|
PGF_API_DECL
|
||||||
void pgf_write_pgf(const char* fpath,
|
void pgf_write_pgf(const char* fpath,
|
||||||
PgfDB *db, PgfRevision revision,
|
PgfDB *db, PgfRevision revision,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
|
|
||||||
module PGF2 (-- * PGF
|
module PGF2 (-- * PGF
|
||||||
PGF,readPGF,bootNGF,readNGF,writePGF,showPGF,
|
PGF,readPGF,bootNGF,readNGF,newNGF,writePGF,showPGF,
|
||||||
|
|
||||||
-- * Abstract syntax
|
-- * Abstract syntax
|
||||||
AbsName,abstractName,globalFlag,abstractFlag,
|
AbsName,abstractName,globalFlag,abstractFlag,
|
||||||
@@ -101,6 +101,7 @@ import qualified Data.Map as Map
|
|||||||
import Data.IORef
|
import Data.IORef
|
||||||
import Data.List(intersperse,groupBy)
|
import Data.List(intersperse,groupBy)
|
||||||
import Data.Char(isUpper,isSpace,isPunctuation)
|
import Data.Char(isUpper,isSpace,isPunctuation)
|
||||||
|
import Data.Maybe(maybe)
|
||||||
import Text.PrettyPrint
|
import Text.PrettyPrint
|
||||||
|
|
||||||
#include <pgf/pgf.h>
|
#include <pgf/pgf.h>
|
||||||
@@ -133,10 +134,8 @@ bootNGF pgf_path ngf_path =
|
|||||||
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))
|
||||||
return (PGF fptr1 fptr2 Map.empty)
|
return (PGF fptr1 fptr2 Map.empty)
|
||||||
|
|
||||||
-- | Tries to read the grammar from an already booted NGF file.
|
-- | Reads the grammar from an already booted NGF file.
|
||||||
-- If the file does not exist then a new one is created, and the
|
-- The function fails if the file does not exist.
|
||||||
-- grammar is set to be empty. It can later be populated with
|
|
||||||
-- rules dynamically.
|
|
||||||
readNGF :: FilePath -> IO PGF
|
readNGF :: FilePath -> IO PGF
|
||||||
readNGF fpath =
|
readNGF fpath =
|
||||||
withCString fpath $ \c_fpath ->
|
withCString fpath $ \c_fpath ->
|
||||||
@@ -148,6 +147,22 @@ readNGF fpath =
|
|||||||
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))
|
||||||
return (PGF fptr1 fptr2 Map.empty)
|
return (PGF fptr1 fptr2 Map.empty)
|
||||||
|
|
||||||
|
-- | Creates a new NGF file with a grammar with the given abstract_name.
|
||||||
|
-- Aside from the name, the grammar is otherwise empty but can be later
|
||||||
|
-- populated with new functions and categories. If fpath is Nothing then
|
||||||
|
-- the file is not stored on the disk but only in memory.
|
||||||
|
newNGF :: AbsName -> Maybe FilePath -> IO PGF
|
||||||
|
newNGF abs_name mb_fpath =
|
||||||
|
withText abs_name $ \c_abs_name ->
|
||||||
|
maybe (\f -> f nullPtr) withCString mb_fpath $ \c_fpath ->
|
||||||
|
alloca $ \p_revision ->
|
||||||
|
mask_ $ do
|
||||||
|
c_db <- withPgfExn (pgf_new_ngf c_abs_name c_fpath p_revision)
|
||||||
|
c_revision <- peek p_revision
|
||||||
|
fptr1 <- newForeignPtr pgf_free_fptr c_db
|
||||||
|
fptr2 <- C.newForeignPtr c_revision (withForeignPtr fptr1 (\c_db -> pgf_free_revision c_db c_revision))
|
||||||
|
return (PGF fptr1 fptr2 Map.empty)
|
||||||
|
|
||||||
writePGF :: FilePath -> PGF -> IO ()
|
writePGF :: FilePath -> PGF -> IO ()
|
||||||
writePGF fpath p =
|
writePGF fpath p =
|
||||||
withCString fpath $ \c_fpath ->
|
withCString fpath $ \c_fpath ->
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ foreign import ccall "pgf_boot_ngf"
|
|||||||
foreign import ccall "pgf_read_ngf"
|
foreign import ccall "pgf_read_ngf"
|
||||||
pgf_read_ngf :: CString -> Ptr (Ptr PgfRevision) -> Ptr PgfExn -> IO (Ptr PgfDB)
|
pgf_read_ngf :: CString -> Ptr (Ptr PgfRevision) -> Ptr PgfExn -> IO (Ptr PgfDB)
|
||||||
|
|
||||||
|
foreign import ccall pgf_new_ngf :: Ptr PgfText -> CString -> Ptr (Ptr PgfRevision) -> Ptr PgfExn -> IO (Ptr PgfDB)
|
||||||
|
|
||||||
foreign import ccall pgf_write_pgf :: CString -> Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfExn -> IO ()
|
foreign import ccall pgf_write_pgf :: CString -> Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfExn -> IO ()
|
||||||
|
|
||||||
foreign import ccall "&pgf_free"
|
foreign import ccall "&pgf_free"
|
||||||
|
|||||||
Reference in New Issue
Block a user