// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
 * All Rights Reserved.
 */

#include "libxfs.h"
#include "command.h"
#include "type.h"
#include "faddr.h"
#include "fprint.h"
#include "field.h"
#include "io.h"
#include "print.h"
#include "bit.h"
#include "flist.h"
#include "strvec.h"
#include "output.h"
#include "sig.h"
#include "write.h"

static void	print_allfields(const struct field *fields);
static int	print_f(int argc, char **argv);
static void	print_flist_1(struct flist *flist, char **pfx, int parentoff);
static void	print_somefields(const struct field *fields, int argc,
				 char **argv);

static const cmdinfo_t	print_cmd =
	{ "print", "p", print_f, 0, -1, 0, N_("[value]..."),
	  N_("print field values"), NULL };

static void
print_allfields(
	const field_t	*fields)
{
	flist_t		*flist;
#ifdef DEBUG
	int		i;
#endif

	flist = flist_make("");
	flist->fld = fields;
#ifndef DEBUG
	(void)flist_parse(fields, flist, iocur_top->data, 0);
#else
	i = flist_parse(fields, flist, iocur_top->data, 0);
	ASSERT(i == 1);
#endif
	flist_print(flist);
	print_flist(flist);
	flist_free(flist);
}

static int
print_f(
	int	argc,
	char	**argv)
{
	pfunc_t	pf;

	if (cur_typ == NULL) {
		dbprintf(_("no current type\n"));
		return 0;
	}
	pf = cur_typ->pfunc;
	if (pf == NULL) {
		dbprintf(_("no print function for type %s\n"), cur_typ->name);
		return 0;
	}
	argc--;
	argv++;
	(*pf)(DB_READ, cur_typ->fields, argc, argv);
	return 0;
}

void
print_flist(
	flist_t	*flist)
{
	char	**pfx;

	pfx = new_strvec(0);
	print_flist_1(flist, pfx, 0);
	free_strvec(pfx);
}

static void
print_flist_1(
	flist_t		*flist,
	char		**ppfx,
	int		parentoff)
{
	char		buf[16];
	const field_t	*f;
	const ftattr_t	*fa;
	flist_t		*fl;
	int		low;
	int		count;
	int		neednl;
	char		**pfx;

	for (fl = flist; fl && !seenint(); fl = fl->sibling) {
		pfx = copy_strvec(ppfx);
		if (fl->name[0])
			add_strvec(&pfx, fl->name);
		if (fl->flags & FL_OKLOW) {
			add_strvec(&pfx, "[");
			snprintf(buf, sizeof(buf), "%d", fl->low);
			add_strvec(&pfx, buf);
			if (fl->low != fl->high) {
				add_strvec(&pfx, "-");
				snprintf(buf, sizeof(buf), "%d", fl->high);
				add_strvec(&pfx, buf);
			}
			add_strvec(&pfx, "]");
		}
		if (fl->child) {
			if (fl->name[0])
				add_strvec(&pfx, ".");
			print_flist_1(fl->child, pfx, fl->offset);
		} else {
			f = fl->fld;
			fa = &ftattrtab[f->ftyp];
			ASSERT(fa->ftyp == f->ftyp);
			print_strvec(pfx);
			dbprintf(" = ");
			if (fl->flags & FL_OKLOW)
				low = fl->low;
			else
				low = 0;
			count = fcount(f, iocur_top->data, parentoff);
			if (fl->flags & FL_OKHIGH)
				count = min(count, fl->high - low + 1);
			if (fa->prfunc) {
				int	fsz;
				int	bitlen;

				/* Don't read an array off the end of the buffer */
				fsz = fsize(f, iocur_top->data, parentoff, 0);
				bitlen = iocur_top->len * NBBY;
				if ((f->flags & FLD_ARRAY) &&
				    fl->offset + (count * fsz) > bitlen) {
					count = (bitlen - fl->offset) / fsz;
				}

				neednl = fa->prfunc(iocur_top->data, fl->offset,
					count, fa->fmtstr, fsz, fa->arg, low,
					(f->flags & FLD_ARRAY) != 0);
				if (neednl)
					dbprintf("\n");
			} else if (fa->arg & FTARG_OKEMPTY) {
				dbprintf(_("(empty)\n"));
			} else {
				dbprintf(_("Unrecognized metadata or type mismatch\n"));
			}
		}
		free_strvec(pfx);
	}
}

void
print_init(void)
{
	add_command(&print_cmd);
}

void
print_sarray(
	void		*obj,
	int		bit,
	int		count,
	int		size,
	int		base,
	int		array,
	const field_t	*flds,
	int		skipnms)
{
	int		bitoff;
	const field_t	*f;
	const ftattr_t	*fa;
	int		first;
	int		i;

	ASSERT(bitoffs(bit) == 0);
	if (skipnms == 0) {
		for (f = flds, first = 1; f->name; f++) {
			if (f->flags & FLD_SKIPALL)
				continue;
			dbprintf("%c%s", first ? '[' : ',', f->name);
			first = 0;
		}
		dbprintf("] ");
	}
	for (i = 0, bitoff = bit;
	     i < count && !seenint();
	     i++, bitoff += size) {
		if (array)
			dbprintf("\n%d:", i + base);
		for (f = flds, first = 1; f->name; f++) {
			if (f->flags & FLD_SKIPALL)
				continue;
			fa = &ftattrtab[f->ftyp];
			ASSERT(fa->ftyp == f->ftyp);
			dbprintf("%c", first ? '[' : ',');
			first = 0;
			if (fa->prfunc)
				fa->prfunc(obj,
					bitoff +
					    bitoffset(f, obj, bitoff, i + base),
					fcount(f, obj, bitoff), fa->fmtstr,
					fsize(f, obj, bitoff, i + base),
					fa->arg, (f->flags & FLD_ABASE1) != 0,
					f->flags & FLD_ARRAY);
			else {
				ASSERT(fa->arg & FTARG_OKEMPTY);
				dbprintf(_("(empty)"));
			}
		}
		dbprintf("]");
		if (i < count - 1)
			dbprintf(" ");
	}
}

static void
print_somefields(
	const field_t	*fields,
	int		argc,
	char		**argv)
{
	const ftattr_t	*fa;
	flist_t		*fl;
	flist_t		*lfl;
	flist_t		*nfl;

	fl = lfl = NULL;
	while (argc > 0) {
		nfl = flist_scan(*argv);
		if (!nfl) {
			if (fl)
				flist_free(fl);
			return;
		}
		if (lfl)
			lfl->sibling = nfl;
		else
			fl = nfl;
		lfl = nfl;
		argc--;
		argv++;
	}
	if (fields->name[0] == '\0') {
		fa = &ftattrtab[fields->ftyp];
		ASSERT(fa->ftyp == fields->ftyp);
		fields = fa->subfld;
	}
	if (!flist_parse(fields, fl, iocur_top->data, 0)) {
		flist_free(fl);
		return;
	}
	flist_print(fl);
	print_flist(fl);
	flist_free(fl);
}

/*ARGSUSED*/
void
print_string(
	const field_t	*fields,
	int		argc,
	char		**argv)
{
	char		*cp;

	if (argc != 0)
		dbprintf(_("no arguments allowed\n"));
	dbprintf("\"");
	for (cp = iocur_top->data;
	     cp < (char *)iocur_top->data + iocur_top->len && *cp &&
		     !seenint();
	     cp++)
		dbprintf("%c", *cp);
	dbprintf("\"\n");
}

void
print_struct(
	const field_t	*fields,
	int		argc,
	char		**argv)
{
	if (argc == 0)
		print_allfields(fields);
	else
		print_somefields(fields, argc, argv);
}
