writePGF now allows to select list of languages

This commit is contained in:
Krasimir Angelov
2023-01-28 11:59:39 +01:00
parent 471adbf63a
commit 8fca37cfeb
9 changed files with 76 additions and 14 deletions

View File

@@ -847,7 +847,7 @@ pgfCommands = Map.fromList [
prGrammar pgf opts
| isOpt "pgf" opts = do
let outfile = valStrOpts "file" (abstractName pgf ++ ".pgf") opts
restricted $ writePGF outfile pgf
restricted $ writePGF outfile pgf (Just (map concreteName (optLangs pgf opts)))
putStrLn $ "wrote file " ++ outfile
return void
| isOpt "cats" opts = return $ fromString $ unwords $ categories pgf

View File

@@ -180,7 +180,7 @@ writeGrammar :: Options -> PGF -> IOE ()
writeGrammar opts pgf =
if fst (flag optLinkTargets opts)
then do let outfile = outputPath opts (grammarName opts pgf <.> "pgf")
writing opts outfile (writePGF outfile pgf)
writing opts outfile (writePGF outfile pgf Nothing)
else return ()
writeOutput :: Options -> FilePath-> String -> IOE ()

View File

@@ -244,6 +244,7 @@ void pgf_merge_pgf(PgfDB *db, PgfRevision revision,
PGF_API
void pgf_write_pgf(const char* fpath,
PgfDB *db, PgfRevision revision,
PgfText **langs,
PgfExn* err)
{
FILE *out = NULL;
@@ -258,7 +259,7 @@ void pgf_write_pgf(const char* fpath,
DB_scope scope(db, READER_SCOPE);
ref<PgfPGF> pgf = db->revision2pgf(revision);
PgfWriter wtr(out);
PgfWriter wtr(langs, out);
wtr.write_pgf(pgf);
}
} PGF_API_END

View File

@@ -287,6 +287,7 @@ void pgf_merge_pgf(PgfDB *db, PgfRevision revision,
PGF_API_DECL
void pgf_write_pgf(const char* fpath,
PgfDB *db, PgfRevision revision,
PgfText **langs, // null terminated list or null
PgfExn* err);
PGF_API_DECL

View File

@@ -2,9 +2,10 @@
#include "data.h"
#include "writer.h"
PgfWriter::PgfWriter(FILE *out)
PgfWriter::PgfWriter(PgfText **langs, FILE *out)
{
this->out = out;
this->langs = langs;
this->abstract = 0;
}
@@ -411,6 +412,22 @@ void PgfWriter::write_printname(ref<PgfConcrPrintname> printname)
void PgfWriter::write_concrete(ref<PgfConcr> concr)
{
if (langs != NULL) {
bool found = false;
PgfText** p = langs;
while (*p) {
if (textcmp(*p, &concr->name) == 0) {
found = true;
break;
}
p++;
}
if (!found) {
return;
}
}
seq_ids.start(concr);
write_name(&concr->name);
@@ -431,5 +448,16 @@ void PgfWriter::write_pgf(ref<PgfPGF> pgf)
write_namespace<PgfFlag>(pgf->gflags, &PgfWriter::write_flag);
write_abstract(ref<PgfAbstr>::from_ptr(&pgf->abstract));
write_namespace<PgfConcr>(pgf->concretes, &PgfWriter::write_concrete);
if (langs == NULL)
write_len(namespace_size(pgf->concretes));
else {
size_t len = 0;
PgfText** p = langs;
while (*p) {
len++; p++;
}
write_len(len);
}
write_namespace_helper<PgfConcr>(pgf->concretes, &PgfWriter::write_concrete);
}

View File

@@ -4,7 +4,7 @@
class PGF_INTERNAL_DECL PgfWriter
{
public:
PgfWriter(FILE *out);
PgfWriter(PgfText **langs, FILE *out);
void write_uint8(uint8_t b);
void write_u16be(uint16_t u);
@@ -66,6 +66,7 @@ private:
void write_presult(ref<ref<PgfPResult>> r) { write_presult(*r); };
FILE *out;
PgfText **langs;
ref<PgfAbstr> abstract;
PgfPhrasetableIds seq_ids;

View File

@@ -188,11 +188,15 @@ newNGF abs_name mb_fpath =
fptr <- newForeignPtrEnv pgf_free_revision c_db c_revision
return (PGF c_db fptr Map.empty)
writePGF :: FilePath -> PGF -> IO ()
writePGF fpath p =
writePGF :: FilePath -> PGF -> Maybe [ConcName] -> IO ()
writePGF fpath p mb_langs =
withCString fpath $ \c_fpath ->
withForeignPtr (a_revision p) $ \c_revision ->
withPgfExn "writePGF" (pgf_write_pgf c_fpath (a_db p) c_revision)
maybe (\f -> f nullPtr) (withLangs []) mb_langs $ \c_langs ->
withPgfExn "writePGF" (pgf_write_pgf c_fpath (a_db p) c_revision c_langs)
where
withLangs clangs [] f = withArray0 nullPtr (reverse clangs) f
withLangs clangs (lang:langs) f = withText lang $ \clang -> withLangs (clang:clangs) langs f
showPGF :: PGF -> String
showPGF p =

View File

@@ -78,7 +78,7 @@ foreign import ccall pgf_new_ngf :: Ptr PgfText -> CString -> Ptr (Ptr PGF) -> P
foreign import ccall pgf_merge_pgf :: Ptr PgfDB -> Ptr PGF -> CString -> Ptr PgfExn -> IO ()
foreign import ccall pgf_write_pgf :: CString -> Ptr PgfDB -> Ptr PGF -> Ptr PgfExn -> IO ()
foreign import ccall pgf_write_pgf :: CString -> Ptr PgfDB -> Ptr PGF -> Ptr (Ptr PgfText) -> Ptr PgfExn -> IO ()
foreign import ccall "pgf_free_revision" pgf_free_revision_ :: Ptr PgfDB -> Ptr PGF -> IO ()

View File

@@ -517,18 +517,45 @@ PGF_dealloc(PGFObject *self)
}
static PyObject *
PGF_writePGF(PGFObject *self, PyObject *args)
PGF_writePGF(PGFObject *self, PyObject *args, PyObject *kwargs)
{
char *kwds[] = {"","langs",NULL};
const char *fpath;
if (!PyArg_ParseTuple(args, "s", &fpath))
PyObject *py_langs = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|O!", &kwds[0], &fpath, &PyList_Type, &py_langs))
return NULL;
PgfText **langs = NULL;
if (py_langs != NULL) {
size_t len = PyList_Size(py_langs);
langs = (PgfText **) alloca((len+1)*sizeof(PgfText*));
for (size_t i = 0; i < len; i++) {
langs[i] = PyUnicode_AsPgfText(PyList_GetItem(py_langs,i));
if (!langs[i]) {
while (i > 0) {
FreePgfText(langs[--i]);
}
return NULL;
}
}
langs[len] = NULL;
}
PgfExn err;
pgf_write_pgf(fpath, self->db, self->revision, &err);
pgf_write_pgf(fpath, self->db, self->revision, langs, &err);
if (handleError(err) != PGF_EXN_NONE) {
return NULL;
}
if (langs != NULL) {
PgfText **p = langs;
while (*p) {
FreePgfText(*p);
p++;
}
}
Py_RETURN_NONE;
}
@@ -1152,7 +1179,7 @@ PGF_embed(PGFObject* self, PyObject *modname)
#endif
static PyMethodDef PGF_methods[] = {
{"writePGF", (PyCFunction)PGF_writePGF, METH_VARARGS,
{"writePGF", (PyCFunction)PGF_writePGF, METH_VARARGS | METH_KEYWORDS,
"Writes to a PGF file"},
{"categoryContext", (PyCFunction)PGF_categoryContext, METH_VARARGS,
"Returns the context for a given category"