/* vi: set sw=4 ts=4: */
/*
 * od implementation for busybox
 * Based on code from util-linux v 2.11l
 *
 * Copyright (c) 1990
 *	The Regents of the University of California.  All rights reserved.
 *
 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
 *
 * Original copyright notice is retained at the end of this file.
 */


#include "libbb.h"
#if ENABLE_DESKTOP
/* This one provides -t (busybox's own build script needs it) */
#include "od_bloaty.c"
#else
#include <getopt.h>

#include "dump.h"

#define isdecdigit(c) isdigit(c)
#define ishexdigit(c) (isxdigit)(c)

static void
odoffset(int argc, char ***argvp)
{
	char *num, *p;
	int base;
	char *end;

	/*
	 * The offset syntax of od(1) was genuinely bizarre.  First, if
	 * it started with a plus it had to be an offset.  Otherwise, if
	 * there were at least two arguments, a number or lower-case 'x'
	 * followed by a number makes it an offset.  By default it was
	 * octal; if it started with 'x' or '0x' it was hex.  If it ended
	 * in a '.', it was decimal.  If a 'b' or 'B' was appended, it
	 * multiplied the number by 512 or 1024 byte units.  There was
	 * no way to assign a block count to a hex offset.
	 *
	 * We assumes it's a file if the offset is bad.
	 */
	p = **argvp;

	if (!p) {
		/* hey someone is probably piping to us ... */
		return;
	}

	if ((*p != '+')
		&& (argc < 2
			|| (!isdecdigit(p[0])
				&& ((p[0] != 'x') || !ishexdigit(p[1])))))
		return;

	base = 0;
	/*
	 * bb_dump_skip over leading '+', 'x[0-9a-fA-f]' or '0x', and
	 * set base.
	 */
	if (p[0] == '+')
		++p;
	if (p[0] == 'x' && ishexdigit(p[1])) {
		++p;
		base = 16;
	} else if (p[0] == '0' && p[1] == 'x') {
		p += 2;
		base = 16;
	}

	/* bb_dump_skip over the number */
	if (base == 16)
		for (num = p; ishexdigit(*p); ++p);
	else
		for (num = p; isdecdigit(*p); ++p);

	/* check for no number */
	if (num == p)
		return;

	/* if terminates with a '.', base is decimal */
	if (*p == '.') {
		if (base)
			return;
		base = 10;
	}

	bb_dump_skip = strtol(num, &end, base ? base : 8);

	/* if end isn't the same as p, we got a non-octal digit */
	if (end != p)
		bb_dump_skip = 0;
	else {
		if (*p) {
			if (*p == 'b') {
				bb_dump_skip *= 512;
				++p;
			} else if (*p == 'B') {
				bb_dump_skip *= 1024;
				++p;
			}
		}
		if (*p)
			bb_dump_skip = 0;
		else {
			++*argvp;
			/*
			 * If the offset uses a non-octal base, the base of
			 * the offset is changed as well.  This isn't pretty,
			 * but it's easy.
			 */
#define	TYPE_OFFSET	7
			{
				char x_or_d;
				if (base == 16) {
					x_or_d = 'x';
					goto DO_X_OR_D;
				}
				if (base == 10) {
					x_or_d = 'd';
				DO_X_OR_D:
					bb_dump_fshead->nextfu->fmt[TYPE_OFFSET]
						= bb_dump_fshead->nextfs->nextfu->fmt[TYPE_OFFSET]
						= x_or_d;
				}
			}
		}
	}
}

static const char *const add_strings[] = {
	"16/1 \"%3_u \" \"\\n\"",				/* a */
	"8/2 \" %06o \" \"\\n\"",				/* B, o */
	"16/1 \"%03o \" \"\\n\"",				/* b */
	"16/1 \"%3_c \" \"\\n\"",				/* c */
	"8/2 \"  %05u \" \"\\n\"",				/* d */
	"4/4 \"     %010u \" \"\\n\"",			/* D */
	"2/8 \"          %21.14e \" \"\\n\"",	/* e (undocumented in od), F */
	"4/4 \" %14.7e \" \"\\n\"",				/* f */
	"4/4 \"       %08x \" \"\\n\"",			/* H, X */
	"8/2 \"   %04x \" \"\\n\"",				/* h, x */
	"4/4 \"    %11d \" \"\\n\"",			/* I, L, l */
	"8/2 \" %6d \" \"\\n\"",				/* i */
	"4/4 \"    %011o \" \"\\n\"",			/* O */
};

static const char od_opts[] ALIGN1 = "aBbcDdeFfHhIiLlOoXxv";

static const char od_o2si[] ALIGN1 = {
	0, 1, 2, 3, 5,
	4, 6, 6, 7, 8,
	9, 0xa, 0xb, 0xa, 0xa,
	0xb, 1, 8, 9,
};

int od_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int od_main(int argc, char **argv)
{
	int ch;
	int first = 1;
	char *p;
	bb_dump_vflag = FIRST;
	bb_dump_length = -1;

	while ((ch = getopt(argc, argv, od_opts)) > 0) {
		if (ch == 'v') {
			bb_dump_vflag = ALL;
		} else if (((p = strchr(od_opts, ch)) != NULL) && (*p != '\0')) {
			if (first) {
				first = 0;
				bb_dump_add("\"%07.7_Ao\n\"");
				bb_dump_add("\"%07.7_ao  \"");
			} else {
				bb_dump_add("\"         \"");
			}
			bb_dump_add(add_strings[(int)od_o2si[(p-od_opts)]]);
		} else {	/* P, p, s, w, or other unhandled */
			bb_show_usage();
		}
	}
	if (!bb_dump_fshead) {
		bb_dump_add("\"%07.7_Ao\n\"");
		bb_dump_add("\"%07.7_ao  \" 8/2 \"%06o \" \"\\n\"");
	}

	argc -= optind;
	argv += optind;

	odoffset(argc, &argv);

	return bb_dump_dump(argv);
}
#endif /* ENABLE_DESKTOP */

/*-
 * Copyright (c) 1990 The Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
