From 3a39fb5f9d5ab24742a1d31a3c47717a21f499cf Mon Sep 17 00:00:00 2001 From: krangelov Date: Fri, 10 Dec 2021 09:56:51 +0100 Subject: [PATCH] added tabularLinearizeAll --- src/runtime/c/pgf/pgf.cxx | 51 +++++++++++++++++++++++++++----- src/runtime/c/pgf/pgf.h | 8 +++-- src/runtime/haskell/PGF2.hsc | 48 ++++++++++++++++++++---------- src/runtime/haskell/PGF2/FFI.hsc | 4 ++- 4 files changed, 86 insertions(+), 25 deletions(-) diff --git a/src/runtime/c/pgf/pgf.cxx b/src/runtime/c/pgf/pgf.cxx index fcbb275c8..91b98520b 100644 --- a/src/runtime/c/pgf/pgf.cxx +++ b/src/runtime/c/pgf/pgf.cxx @@ -2049,8 +2049,7 @@ PgfText **pgf_linearize_all(PgfDB *db, PgfConcrRevision revision, PGF_API PgfText **pgf_tabular_linearize(PgfDB *db, PgfConcrRevision revision, PgfExpr expr, PgfPrintContext *ctxt, - PgfMarshaller *m, size_t *n_fields, - PgfExn* err) + PgfMarshaller *m, PgfExn* err) { PGF_API_BEGIN { DB_scope scope(db, READER_SCOPE); @@ -2063,19 +2062,19 @@ PgfText **pgf_tabular_linearize(PgfDB *db, PgfConcrRevision revision, if (linearizer.resolve()) { ref lincat = linearizer.get_lincat(); PgfText **res = (PgfText **) - malloc(lincat->fields->len*2*sizeof(PgfText*)); + malloc((lincat->fields->len+1)*2*sizeof(PgfText*)); size_t pos = 0; for (size_t i = 0; i < lincat->fields->len; i++) { linearizer.linearize(&out, i); PgfText *text = out.get_text(); if (text != NULL) { - res[pos] = textdup(&(*lincat->fields->data[i])); - res[pos+1] = text; - pos += 2; + res[pos++] = textdup(&(*lincat->fields->data[i])); + res[pos++] = text; } } - *n_fields = pos/2; + res[pos++] = NULL; + res[pos++] = NULL; return res; } } PGF_API_END @@ -2083,6 +2082,44 @@ PgfText **pgf_tabular_linearize(PgfDB *db, PgfConcrRevision revision, return NULL; } +PGF_API +PgfText **pgf_tabular_linearize_all(PgfDB *db, PgfConcrRevision revision, + PgfExpr expr, PgfPrintContext *ctxt, + PgfMarshaller *m, PgfExn* err) +{ + PGF_API_BEGIN { + DB_scope scope(db, READER_SCOPE); + + ref concr = PgfDB::revision2concr(revision); + PgfLinearizationOutput out; + PgfLinearizer linearizer(ctxt, concr, m); + m->match_expr(&linearizer, expr); + linearizer.reverse_and_label(false); + + size_t pos = 0; + PgfText **res = NULL; + while (linearizer.resolve()) { + ref lincat = linearizer.get_lincat(); + res = (PgfText **) + realloc(res, (pos+(lincat->fields->len+1)*2)*sizeof(PgfText*)); + for (size_t i = 0; i < lincat->fields->len; i++) { + linearizer.linearize(&out, i); + + PgfText *text = out.get_text(); + if (text != NULL) { + res[pos++] = textdup(&(*lincat->fields->data[i])); + res[pos++] = text; + } + } + res[pos++] = NULL; + } + res[pos++] = NULL; + return res; + } PGF_API_END + + return NULL; +} + PGF_API_DECL void pgf_bracketed_linearize(PgfDB *db, PgfConcrRevision revision, PgfExpr expr, PgfPrintContext *ctxt, diff --git a/src/runtime/c/pgf/pgf.h b/src/runtime/c/pgf/pgf.h index 278c8a0ef..e06045b4e 100644 --- a/src/runtime/c/pgf/pgf.h +++ b/src/runtime/c/pgf/pgf.h @@ -635,8 +635,12 @@ PgfText *pgf_linearize(PgfDB *db, PgfConcrRevision revision, PGF_API PgfText **pgf_tabular_linearize(PgfDB *db, PgfConcrRevision revision, PgfExpr expr, PgfPrintContext *ctxt, - PgfMarshaller *m, size_t *n_fields, - PgfExn* err); + PgfMarshaller *m, PgfExn* err); + +PGF_API +PgfText **pgf_tabular_linearize_all(PgfDB *db, PgfConcrRevision revision, + PgfExpr expr, PgfPrintContext *ctxt, + PgfMarshaller *m, PgfExn* err); PGF_API_DECL void pgf_bracketed_linearize(PgfDB *db, PgfConcrRevision revision, diff --git a/src/runtime/haskell/PGF2.hsc b/src/runtime/haskell/PGF2.hsc index e13dc334b..2b2fa0c14 100644 --- a/src/runtime/haskell/PGF2.hsc +++ b/src/runtime/haskell/PGF2.hsc @@ -647,25 +647,43 @@ tabularLinearize c e = withForeignPtr (c_revision c) $ \c_revision -> bracket (newStablePtr e) freeStablePtr $ \c_e -> withForeignPtr marshaller $ \m -> - alloca $ \p_n_fields -> - bracket (withPgfExn "tabularLinearize" (pgf_tabular_linearize (c_db c) c_revision c_e nullPtr m p_n_fields)) free $ \c_texts -> do - n_fields <- peek p_n_fields - peekTable n_fields c_texts + bracket (withPgfExn "tabularLinearize" (pgf_tabular_linearize (c_db c) c_revision c_e nullPtr m)) free peekTable where - peekTable 0 c_texts = return [] - peekTable n c_texts = do - c_field <- peek c_texts - field <- peekText c_field - free c_field - c_lin <- peek (c_texts `plusPtr` (#size PgfText*)) - lin <- peekText c_lin - free c_lin - table <- peekTable (n-1) (c_texts `plusPtr` (2*(#size PgfText*))) - return ((field,lin):table) + peekTable c_texts = do + c_field <- peekElemOff c_texts 0 + c_lin <- peekElemOff c_texts 1 + if c_field == nullPtr && c_lin == nullPtr + then return [] + else do field <- peekText c_field + free c_field + lin <- peekText c_lin + free c_lin + table <- peekTable (c_texts `plusPtr` (2*(#size PgfText*))) + return ((field,lin):table) -- | Generates a table of linearizations for an expression tabularLinearizeAll :: Concr -> Expr -> [[(String, String)]] -tabularLinearizeAll lang e = error "TODO: tabularLinearizeAll" +tabularLinearizeAll c e = + unsafePerformIO $ + withForeignPtr (c_revision c) $ \c_revision -> + bracket (newStablePtr e) freeStablePtr $ \c_e -> + withForeignPtr marshaller $ \m -> + bracket (withPgfExn "tabularLinearizeAll" (pgf_tabular_linearize_all (c_db c) c_revision c_e nullPtr m)) free peekTables + where + peekTables c_texts = do + c_field <- peekElemOff c_texts 0 + c_lin <- peekElemOff c_texts 1 + if c_field == nullPtr && c_lin == nullPtr + then return [[]] + else if c_field == nullPtr + then do tables <- peekTables (c_texts `plusPtr` (#size PgfText*)) + return ([]:tables) + else do field <- peekText c_field + free c_field + lin <- peekText c_lin + free c_lin + (table:tables) <- peekTables (c_texts `plusPtr` (2*(#size PgfText*))) + return (((field,lin):table):tables) type FId = Int diff --git a/src/runtime/haskell/PGF2/FFI.hsc b/src/runtime/haskell/PGF2/FFI.hsc index e3b1a3570..370e22811 100644 --- a/src/runtime/haskell/PGF2/FFI.hsc +++ b/src/runtime/haskell/PGF2/FFI.hsc @@ -211,7 +211,9 @@ foreign import ccall pgf_linearize :: Ptr PgfDB -> Ptr Concr -> StablePtr Expr - foreign import ccall pgf_linearize_all :: Ptr PgfDB -> Ptr Concr -> StablePtr Expr -> Ptr PgfPrintContext -> Ptr PgfMarshaller -> Ptr CSize -> Ptr PgfExn -> IO (Ptr (Ptr PgfText)) -foreign import ccall pgf_tabular_linearize :: Ptr PgfDB -> Ptr Concr -> StablePtr Expr -> Ptr PgfPrintContext -> Ptr PgfMarshaller -> Ptr CSize -> Ptr PgfExn -> IO (Ptr (Ptr PgfText)) +foreign import ccall pgf_tabular_linearize :: Ptr PgfDB -> Ptr Concr -> StablePtr Expr -> Ptr PgfPrintContext -> Ptr PgfMarshaller -> Ptr PgfExn -> IO (Ptr (Ptr PgfText)) + +foreign import ccall pgf_tabular_linearize_all :: Ptr PgfDB -> Ptr Concr -> StablePtr Expr -> Ptr PgfPrintContext -> Ptr PgfMarshaller -> Ptr PgfExn -> IO (Ptr (Ptr PgfText)) foreign import ccall pgf_bracketed_linearize :: Ptr PgfDB -> Ptr Concr -> StablePtr Expr -> Ptr PgfPrintContext -> Ptr PgfMarshaller -> Ptr PgfLinearizationOutputIface -> Ptr PgfExn -> IO ()