bool noTotals = false;
bool onlyTotals = false;
ptrdiff_t itemsInitialLen = 2048;
+ ptrdiff_t maxParseCycles = PTRDIFF_MAX;
struct option longopts[] = {
{"max-str-len", required_argument, NULL, 'a'},
{"do-encode", no_argument, NULL, 'b'},
{"no-totals", no_argument, NULL, 'd'},
{"only-totals", no_argument, NULL, 'e'},
{"items-initial-len", required_argument, NULL, 'f'},
+ {"max-parse-cycles", required_argument, NULL, 'g'},
{NULL, 0, NULL, 0}};
int ch = 0;
for (;;) {
itemsInitialLen = (ptrdiff_t)tmp;
break;
}
+ case 'g': { // max-parse-cycles
+ errno = 0;
+ long tmp = strtol(optarg, NULL, 10);
+ if (errno != 0) {
+ fprintf(stderr, "--max-parse-cycles: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ if (tmp < 0) {
+ fputs("--max-parse-cycles: is negative\n", stderr);
+ exit(EXIT_FAILURE);
+ }
+ maxParseCycles = (ptrdiff_t)tmp;
+ break;
+ }
case '?':
default:
usage();
size_t off = 0;
struct timespec started;
struct timespec finished;
+ ptrdiff_t parseCycles = 0;
while (off < len) {
errno = 0;
if (clock_gettime(CLOCK_MONOTONIC_PRECISE, &started) != 0) {
1000000000 * (finished.tv_sec - started.tv_sec) + finished.tv_nsec -
started.tv_nsec);
}
+ parseCycles++;
+ if (parseCycles >= maxParseCycles) {
+ break;
+ }
}
if (off < len) {
char *hex = HexEnc(buf + off, len - off);
"go.cypherpunks.su/tai64n/v4"
)
-var MaxStrLen = flag.Uint("max-str-len", 40, "Maximal string length to print")
+var (
+ MaxStrLen = flag.Uint("max-str-len", 40, "Maximal string length to print")
+ MaxParseCycles = flag.Uint64("max-parse-cycles", 1<<63,
+ "Maximal number of parse cycles to perform")
+)
func prindent(depth int) {
fmt.Print(strings.Repeat(" ", depth))
var off int64
var ctx *keks.Decoder
var err error
- for {
+ for i := uint64(0); i < *MaxParseCycles; i++ {
ctx = keks.NewDecoderFromReader(br, &keks.DecodeOpts{SaveOffsets: true})
ctx.Read = off
if _, err = ctx.Parse(); err != nil {
printer(ctx.Iter(), 1, false, false)
off = ctx.Read
}
- fmt.Println(ctx.Read, "bytes")
+ fmt.Println(off, "bytes")
}