From db2b21cf391c8d3e4e75b6170523f1835722797f Mon Sep 17 00:00:00 2001
From: "Sven M. Hallberg" <pesco@khjk.org>
Date: Tue, 28 Jan 2020 14:05:14 +0100
Subject: [PATCH] custom token type for indirect references

---
 pdf.c | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/pdf.c b/pdf.c
index 85bae4c..37eaa1f 100644
--- a/pdf.c
+++ b/pdf.c
@@ -118,7 +118,7 @@ struct Env {
 /*
  * custom token types
  */
-HTokenType TT_XREntry;
+HTokenType TT_XREntry, TT_Ref;
 
 typedef struct {
 	enum {XR_FREE, XR_INUSE, XR_OBJSTM} type;
@@ -129,6 +129,8 @@ typedef struct {
 	};
 } XREntry;
 
+typedef struct { size_t nr, gen; } Ref;
+
 void
 pp_xrentry(FILE *stream, const HParsedToken *tok, int indent, int delta)
 {
@@ -152,6 +154,14 @@ pp_xrentry(FILE *stream, const HParsedToken *tok, int indent, int delta)
 	}
 }
 
+void
+pp_ref(FILE *stream, const HParsedToken *tok, int indent, int delta)
+{
+	Ref *r = H_CAST(Ref, tok);
+
+	fprintf(stream, "[%zu,%zu]", r->nr, r->gen);
+}
+
 
 /*
  * semantic actions
@@ -246,6 +256,17 @@ act_real(const HParseResult *p, void *u)
 	return H_MAKE_UINT(x + f);	// XXX H_MAKE_DOUBLE (-> pprint)
 }
 
+HParsedToken *
+act_ref(const HParseResult *p, void *u)
+{
+	Ref *r = H_ALLOC(Ref);
+
+	r->nr = H_FIELD_UINT(0);
+	r->gen = H_FIELD_UINT(1);
+
+	return H_MAKE(Ref, r);
+}
+
 HParsedToken *
 act_token(const HParseResult *p, void *u)
 {
@@ -363,7 +384,8 @@ HParser *kxstream(HAllocator *, const HParsedToken *, void *);
 void
 init_parser(struct Env *aux)
 {
-	TT_XREntry = h_allocate_token_new("XREntry", NULL, pp_xrentry);
+	TT_XREntry =	h_allocate_token_new("XREntry", NULL, pp_xrentry);
+	TT_Ref =	h_allocate_token_new("Ref", NULL, pp_ref);
 
 	/* lines */
 	H_RULE(cr,	p_mapch('\r', '\n'));	/* semantic value: \n */
@@ -427,7 +449,7 @@ init_parser(struct Env *aux)
 	 * objects
 	 */
 	
-	H_RULE(ref,	SEQ(pnat, nat, KW("R")));
+	H_ARULE(ref,	SEQ(pnat, nat, KW("R")));
 	H_RULE(null,	KW("null"));
 	H_RULE(boole,	CHX(KW("true"), KW("false")));
 
-- 
GitLab