ref: 7848f6493fbae545088432575e801baad8ea879d
parent: 5949d53a09a809482abc6fc4e4db6e8c8266afd0
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Fri Aug 11 14:12:45 EDT 2023
add "xref" eval (prints xref table); add "#<offset>" eval (prints an object at the offset within the file)
--- a/eval.c
+++ b/eval.c
@@ -63,6 +63,30 @@
}
Object *
+pdfevaloff(Object *o, int off)
+{
+ Object *d;
+
+ if(o == nil)
+ return &null;
+ if(o->type != Oindir)
+ return o;
+ if(o->indir.o != nil)
+ return o->indir.o;
+
+ if(Sseek(o->pdf->s, off, 0) != off){
+ werrstr("evaloff: seek failed");
+ return &null;
+ }
+ if((d = pdfobj(o->pdf, o->pdf->s, 0)) == nil){
+ werrstr("evaloff: %r [at %p]", (void*)off);
+ return &null;
+ }
+ o->indir.o = d;
+ return d;
+}
+
+Object *
pdfeval(Object *o)
{
Object *d;
@@ -82,18 +106,18 @@
break;
}
if(i >= o->pdf->nxref){
- werrstr("no object id %d in xref", o->indir.id);
+ werrstr("eval: no object id %d in xref", o->indir.id);
return &null;
}
if(x->objstm > 0){
if((d = evalobjstm(o->pdf, x)) == &null)
- werrstr("ObjStm: %r");
+ werrstr("eval: ObjStm: %r");
o->indir.o = d;
return d;
}
if(Sseek(o->pdf->s, x->off, 0) != x->off){
- werrstr("xref seek failed");
+ werrstr("eval: xref seek failed");
return &null;
}
if((d = pdfobj(o->pdf, o->pdf->s, 0)) == nil){
--- a/main.c
+++ b/main.c
@@ -140,10 +140,18 @@
o.pdf = pdf;
o.type = Oindir;
o.indir.id = atoi(argv[i]+1);
- if((v = pdfeval(&o)) == nil){
- v = &null;
+ if((v = pdfeval(&o)) == &null)
break;
- }
+ }else if(argv[i][0] == '#' && isdigit(argv[i][1])){
+ memset(&o, 0, sizeof(o));
+ o.ref = 1;
+ o.pdf = pdf;
+ o.type = Oindir;
+ if((v = pdfevaloff(&o, atoi(argv[i]+1))) == &null)
+ break;
+ }else if(i == 1 && strcmp(argv[i], "xref") == 0){
+ for(n = 0; n < pdf->nxref; n++)
+ print("%08d %⊗\n", n, pdf->xref[n]);
}else{
v = dictget(v, argv[i]);
}
--- a/pdf.h
+++ b/pdf.h
@@ -219,6 +219,12 @@
void pdfobjfree(Object *o);
/*
+ * Return an object from the offset within the file or &null if
+ * can't. Object must be marked indirect.
+ */
+Object *pdfevaloff(Object *o, int off);
+
+/*
* Return a resolved object or &null if can't. Operation is
* not recursive, ie values of a dictionary won't be resolved
* automatically.