ref: 207f8c591b3e831f4a35185b99482cfb34fccf4b
parent: 74504c05e0be45260076e95e8e25cfc39f0ea6cf
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Wed Jun 19 13:25:43 EDT 2024
use Bprint; finish ctxpushrange/ctxpoprange/ctxreadn
--- a/otf.rkt
+++ b/otf.rkt
@@ -66,6 +66,9 @@
(define (field-cond f)
(assoc 'cond (field-attrs f)))
+(define (field-ptr f)
+ (assoc 'ptr (field-attrs f)))
+
(define (block stmt lst)
(if (= (length lst) 1) (list* stmt lst) (list (string-append stmt "{") lst "}")))
@@ -76,7 +79,7 @@
(block (~a "if(" (string-join (map (λ (n) (~a "v->" ref " " op " " n)) n) " || ") ")")
(indent (flatten lst)))]))
-(define (field-fprint-c f)
+(define (field-print-c f)
(define t (field-type f))
(define count (field-count f))
(define end (and count (if (cmplx? t) (~a "v->" (cadr count)) (cadr count))))
@@ -84,9 +87,9 @@
(define fixed-array (and basic-array (number? end)))
(define array-index (if (field-count f) "[i]" ""))
(define verb (if (type? t) (if (field-verb f) (cadr (field-verb f)) (type-verb t)) ""))
- (define fprint-index
+ (define print-index
(if basic-array
- (~a "fprint(f, \"%*s%s[%d]: "
+ (~a "Bprint(f, \"%*s%s[%d]: "
verb
"\\n\", indent, \"\", \""
(field-name f)
@@ -94,17 +97,17 @@
(field-name f)
array-index
");")
- (~a "fprint(f, \"%*s%s[%d]:\\n\", indent, \"\", \"" (field-name f) "\", i);")))
+ (~a "Bprint(f, \"%*s%s[%d]:\\n\", indent, \"\", \"" (field-name f) "\", i);")))
(define array-loop
(if count
(λ (lst)
(block (~a "for(int i = 0; i < " (if fixed-array "" "v->") (cadr count) "; i++)")
- (indent (list* fprint-index (if basic-array empty lst)))))
+ (indent (list* print-index (if basic-array empty lst)))))
identity))
(define lst
(list
(if (type? t)
- (~a "fprint(f, \"%*s%s: "
+ (~a "Bprint(f, \"%*s%s: "
verb
"\\n\", indent, \"\", \""
(field-name f)
@@ -112,7 +115,7 @@
(field-name f)
array-index
");")
- (~a "fprint_" (cmplx-name t) "(f, indent+indentΔ, &v->" (field-name f) array-index ");"))))
+ (~a "print_" (cmplx-name t) "(f, indent+indentΔ, &v->" (field-name f) array-index ");"))))
(if (field-unused? f) empty (wrap-cond-c (field-cond f) (array-loop lst))))
(define (invert-c op)
@@ -289,10 +292,10 @@
(~a "}"))
(list (~a "")
(~a "void")
- (~a "fprint_" (cmplx-name c) "(int f, int indent, " (cmplx-name c) " *v)")
+ (~a "print_" (cmplx-name c) "(Biobuf *f, int indent, " (cmplx-name c) " *v)")
(~a "{")
- (indent (flatten (map field-fprint-c (cmplx-fields c))))
- (indent (filter-extra (cmplx-extra c) 'fprint))
+ (indent (flatten (map field-print-c (cmplx-fields c))))
+ (indent (filter-extra (cmplx-extra c) 'print))
(~a "}")))))
(define (c-type c)
(cmplx-name c))])
@@ -912,10 +915,10 @@
(mkfields {Tag tableTag} {uint32 checksum unused hex} {Offset32 offset} {uint32 length})
#:extra (list (cons 'field
(list (~a "void *parsed;")
- (~a "void (*fprint)(int f, int indent, void *parsed);")))
- (cons 'fprint
- (list (~a "if(v->fprint != nil && v->parsed != nil)")
- (~a "\tv->fprint(f, indent+indentΔ, v->parsed);")))))
+ (~a "void (*print)(Biobuf *f, int indent, void *parsed);")))
+ (cons 'print
+ (list (~a "if(v->print != nil && v->parsed != nil)")
+ (~a "\tv->print(f, indent+indentΔ, v->parsed);")))))
(define (c-friendly-name t)
(string-replace (string-trim (string-downcase t)) "/" "∕"))
@@ -936,7 +939,7 @@
(~a "\t\t\tgoto err;")
(~a "\t\t}")
(~a "\t\trec->parsed = v->" (ptr c) ";")
- (~a "\t\trec->fprint = (void*)fprint_" (cmplx-name c) ";")
+ (~a "\t\trec->print = (void*)print_" (cmplx-name c) ";")
(~a "\t\tbreak;")))
(list (cons 'field (map (λ (c) (~a (cmplx-name c) " *" (ptr c) ";")) tagged))
(cons 'read
@@ -949,7 +952,8 @@
(~a "\tswitch(rec->tableTag){")
(map case-statement tagged)
(~a "\t}")
- (~a "\tctxpoprange(ctx);")
+ (~a "\tif(ctxpoprange(ctx) < 0)")
+ (~a "\t\tgoto err;")
(~a "}")))))
(mkcmplx TableDirectory
--- a/test.c
+++ b/test.c
@@ -3,39 +3,112 @@
#include <bio.h>
typedef struct Ctx Ctx;
+typedef struct Range Range;
struct Ctx {
- u8int buf[8192];
Biobuf *f;
+ Range *r;
+ u8int *buf;
+ int bufsz;
+ int off;
};
+struct Range {
+ int start;
+ int len;
+ int prevoff;
+ Range *par;
+};
+
int
-ctxpushrange(Ctx *ctx, int offset, int len)
+ctxpushrange(Ctx *ctx, int off, int len)
{
- int r;
- USED(len);
- if((r = Bseek(ctx->f, offset, 0)) != offset){
- werrstr("seek offset: need %d, got %d", offset, r);
- return -1;
+ Range *r;
+ int x;
+
+ r = nil;
+ if(ctx->r != nil){
+ if(off+len > ctx->r->len){
+ werrstr("range overflow by %d bytes", off+len - ctx->r->len);
+ goto err;
+ }
+ off += ctx->r->start;
}
+ if((r = malloc(sizeof(*r))) == nil){
+ werrstr("no memory");
+ goto err;
+ }
+ r->par = ctx->r;
+ r->start = off;
+ r->len = len;
+ r->prevoff = ctx->off;
+ if((x = Bseek(ctx->f, off, 0)) != off){
+ werrstr("seek offset: need %d, got %d", off, x);
+ goto err;
+ }
+ ctx->off = off;
+ ctx->r = r;
return 0;
+err:
+ free(r);
+ werrstr("ctxpushrange: %r");
+ return -1;
}
-void
+int
ctxpoprange(Ctx *ctx)
{
- Bseek(ctx->f, 0, 0);
+ Range *r;
+ int x;
+
+ r = ctx->r;
+ if(r == nil){
+ werrstr("pop without push");
+ goto err;
+ }
+ if((x = Bseek(ctx->f, r->prevoff, 0)) != r->prevoff){
+ werrstr("seek offset: need %d, got %d", r->prevoff, x);
+ goto err;
+ }
+ ctx->off = r->prevoff;
+ ctx->r = r->par;
+ free(r);
+ return 0;
+err:
+ werrstr("ctxpoprange: %r");
+ return -1;
}
u8int *
ctxreadn(Ctx *ctx, int n)
{
- int r;
- if((r = Bread(ctx->f, ctx->buf, n)) != n){
- werrstr("short read: need %d, got %d", n, r);
- return nil;
+ Range *r;
+ u8int *b;
+ int x;
+
+ r = ctx->r;
+ if(r != nil && ctx->off+n > r->start+r->len){
+ werrstr("short read: need %d at %d, have %d at %d", n, ctx->off, r->len, r->start);
+ goto err;
}
+ if(n > ctx->bufsz){
+ if((b = realloc(ctx->buf, n)) == nil){
+ werrstr("no memory");
+ goto err;
+ }
+ ctx->buf = b;
+ ctx->bufsz = n;
+ }
+ if((x = Bread(ctx->f, ctx->buf, n)) != n){
+ werrstr("short read: need %d, got %d; off %d", n, x, ctx->off);
+ goto err;
+ }
+ ctx->off += n;
+
return ctx->buf;
+err:
+ werrstr("ctxreadn: %r");
+ return nil;
}
int
@@ -45,17 +118,21 @@
int (*fun)(Ctx*, void*);
u8int *arr;
- if((arr = calloc(num, elsz)) == nil)
- return -1;
+ if((arr = calloc(num, elsz)) == nil){
+ werrstr("no memory");
+ goto err;
+ }
fun = fun_;
for(i = 0; i < num; i++){
- if(fun(ctx, arr + i*elsz) < 0){
- free(arr);
- return -1;
- }
+ if(fun(ctx, arr + i*elsz) < 0)
+ goto err;
}
*arr_ = arr;
return 0;
+err:
+ free(arr);
+ werrstr("ctxarray: %r");
+ return -1;
}
#include "out.h"
@@ -64,22 +141,25 @@
main(int argc, char **argv)
{
TableDirectory td;
+ Biobuf *out;
Ctx ctx;
int i;
otfinit();
+ out = Bfdopen(1, OWRITE);
for(i = 1; i < argc; i++){
- print("%s\n", argv[i]);
+ Bprint(out, "%s\n", argv[i]);
if((ctx.f = Bopen(argv[i], OREAD)) == nil){
fprint(2, "%r\n");
}else if(read_TableDirectory(&ctx, &td) != 0){
fprint(2, "%s: %r\n", argv[i]);
} else {
- fprint_TableDirectory(1, 0, &td);
+ print_TableDirectory(out, 0, &td);
}
if(ctx.f != nil)
Bterm(ctx.f);
}
+ Bterm(out);
exits(nil);
}