/*
 * Copyright (C) 2000-2003 ASANO Masahiro
 */

#include <unistd.h>
#include "crash.h"

PRIVATE addr_t kmem_cache(), slab();
const commandtable_t command_kmem_cache =
	{"kmem_cache", kmem_cache, "[-s] [address]", "print kmem_cache_t table\n  -s  print slab_t table"};
const commandtable_t command_slab =
	{"slab", slab, "address", "print slab table"};
extern void prhead_slab();

addr_t cache_cache_addr;
addr_t print_kmem_cache(), print_slab();

PRIVATE addr_t
kmem_cache()
{
	int i, c;
	addr_t addr = 0;
	int sflag = 0;
	void prhead_kmem_cache();

	while ((c = getopt(argcnt, args, "s")) != EOF) {
		switch (c) {
		case 's':
			sflag = 1;
			break;
		default:
			THROW(usage);
		}
	}

	GETADDR(cache_cache);

	if (argcnt > optind) {
		for (i = optind; i < argcnt; i++) {
			addr = getvalue(args[i]);
			addr = print_kmem_cache(addr, sflag, 1);
		}
	} else {
		if (!sflag) prhead_kmem_cache();
		addr = print_kmem_cache(cache_cache_addr, sflag, 0);
		while (addr && addr != cache_cache_addr) {
			if (sflag) prhead_kmem_cache();
			addr = print_kmem_cache(addr, sflag, 0);
		}
	}

	return addr;
}

PRIVATE addr_t
slab()
{
	int i, c;
	addr_t addr = 0;

	while ((c = getopt(argcnt, args, "")) != EOF) {
		switch (c) {
		default:
			THROW(usage);
		}
	}

	if (argcnt > optind) {
		prhead_slab();
		for (i = optind; i < argcnt; i++) {
			addr = getvalue(args[i]);
			addr = print_slab(addr, 0);
		}
	} else {
		THROW(usage);
	}
	return addr;
}
