/*
  SPDX-License-Identifier: GPL-2.0-only

  Copyright (C) 2007-2016 Arnaldo Carvalho de Melo <acme@kernel.org>
*/

#include <argp.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#include "dwarves.h"
#include "dutil.h"

static struct conf_fprintf conf = {
	.emit_stats	= 1,
};

static void emit_tag(struct tag *tag, uint32_t tag_id, struct cu *cu)
{
	printf("/* %d */\n", tag_id);

	if (tag__is_struct(tag))
		class__find_holes(tag__class(tag));

	if (tag->tag == DW_TAG_base_type) {
		char bf[64];
		const char *name = base_type__name(tag__base_type(tag), bf, sizeof(bf));

		if (name == NULL)
			printf("anonymous base_type\n");
		else
			puts(name);
	} else if (tag__is_pointer(tag))
		printf(" /* pointer to %lld */\n", (unsigned long long)tag->type);
	else
		tag__fprintf(tag, cu, &conf, stdout);

	printf(" /* size: %zd */\n\n", tag__size(tag, cu));
}

static int cu__emit_tags(struct cu *cu)
{
	uint32_t i;
	struct tag *tag;

	puts("/* Types: */\n");
	cu__for_each_type(cu, i, tag)
		emit_tag(tag, i, cu);

	puts("/* Functions: */\n");
	conf.no_semicolon = true;
	struct function *function;
	cu__for_each_function(cu, i, function) {
		tag__fprintf(function__tag(function), cu, &conf, stdout);
		putchar('\n');
		lexblock__fprintf(&function->lexblock, cu, function, 0,
				  &conf, stdout);
		printf(" /* size: %zd */\n\n",
		       tag__size(function__tag(function), cu));
	}
	conf.no_semicolon = false;

	puts("\n\n/* Variables: */\n");
	cu__for_each_variable(cu, i, tag) {
		tag__fprintf(tag, cu, NULL, stdout);
		printf(" /* size: %zd */\n\n", tag__size(tag, cu));
	}


	return 0;
}

static enum load_steal_kind pdwtags_stealer(struct cu *cu,
					    struct conf_load *conf_load __maybe_unused,
					    void *thr_data __maybe_unused)
{
	cu__emit_tags(cu);
	return LSK__DELETE;
}

static struct conf_load pdwtags_conf_load = {
	.steal = pdwtags_stealer,
	.conf_fprintf = &conf,
};

/* Name and version of program.  */
ARGP_PROGRAM_VERSION_HOOK_DEF = dwarves_print_version;

static const struct argp_option pdwtags__options[] = {
	{
		.name = "format_path",
		.key  = 'F',
		.arg  = "FORMAT_LIST",
		.doc  = "List of debugging formats to try"
	},
	{
		.key  = 'V',
		.name = "verbose",
		.doc  = "show details",
	},
	{
		.name = NULL,
	}
};

static error_t pdwtags__options_parser(int key, char *arg __maybe_unused,
				      struct argp_state *state)
{
	switch (key) {
	case ARGP_KEY_INIT:
		if (state->child_inputs != NULL)
			state->child_inputs[0] = state->input;
		break;
	case 'F': pdwtags_conf_load.format_path = arg;	break;
	case 'V': conf.show_decl_info = 1;		break;
	default:  return ARGP_ERR_UNKNOWN;
	}
	return 0;
}

static const char pdwtags__args_doc[] = "FILE";

static struct argp pdwtags__argp = {
	.options  = pdwtags__options,
	.parser	  = pdwtags__options_parser,
	.args_doc = pdwtags__args_doc,
};

int main(int argc, char *argv[])
{
	int remaining, rc = EXIT_FAILURE, err;
	struct cus *cus = cus__new();

	if (dwarves__init() || cus == NULL) {
		fputs("pwdtags: insufficient memory\n", stderr);
		goto out;
	}

	dwarves__resolve_cacheline_size(&pdwtags_conf_load, 0);

	if (argp_parse(&pdwtags__argp, argc, argv, 0, &remaining, NULL) ||
	    remaining == argc) {
                argp_help(&pdwtags__argp, stderr, ARGP_HELP_SEE, argv[0]);
                goto out;
	}

	err = cus__load_files(cus, &pdwtags_conf_load, argv + remaining);
	if (err == 0) {
		rc = EXIT_SUCCESS;
		goto out;
	}

	cus__fprintf_load_files_err(cus, "pdwtags", argv + remaining, err, stderr);
out:
	cus__delete(cus);
	dwarves__exit();
	return rc;
}
