/* vi: set sw=4 ts=4: */
/*
 * Support code for the hexdump and od applets,
 * based on code from util-linux v 2.11l
 *
 * Copyright (c) 1989
 *	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"
#include "dump.h"

enum _vflag bb_dump_vflag = FIRST;
FS *bb_dump_fshead;				/* head of format strings */
static FU *endfu;
static char **_argv;
static off_t savaddress;	/* saved address/offset in stream */
static off_t eaddress;	/* end address */
static off_t address;	/* address/offset in stream */
off_t bb_dump_skip;				/* bytes to skip */
static int exitval;			/* final exit value */
int bb_dump_blocksize;			/* data block size */
int bb_dump_length = -1;		/* max bytes to read */

static const char index_str[] ALIGN1 = ".#-+ 0123456789";

static const char size_conv_str[] ALIGN1 =
"\x1\x4\x4\x4\x4\x4\x4\x8\x8\x8\x8\010cdiouxXeEfgG";

static const char lcc[] ALIGN1 = "diouxX";

int bb_dump_size(FS * fs)
{
	FU *fu;
	int bcnt, cur_size;
	char *fmt;
	const char *p;
	int prec;

	/* figure out the data block bb_dump_size needed for each format unit */
	for (cur_size = 0, fu = fs->nextfu; fu; fu = fu->nextfu) {
		if (fu->bcnt) {
			cur_size += fu->bcnt * fu->reps;
			continue;
		}
		for (bcnt = prec = 0, fmt = fu->fmt; *fmt; ++fmt) {
			if (*fmt != '%')
				continue;
			/*
			 * bb_dump_skip any special chars -- save precision in
			 * case it's a %s format.
			 */
			while (strchr(index_str + 1, *++fmt));
			if (*fmt == '.' && isdigit(*++fmt)) {
				prec = atoi(fmt);
				while (isdigit(*++fmt));
			}
			if (!(p = strchr(size_conv_str + 12, *fmt))) {
				if (*fmt == 's') {
					bcnt += prec;
				} else if (*fmt == '_') {
					++fmt;
					if ((*fmt == 'c') || (*fmt == 'p') || (*fmt == 'u')) {
						bcnt += 1;
					}
				}
			} else {
				bcnt += size_conv_str[p - (size_conv_str + 12)];
			}
		}
		cur_size += bcnt * fu->reps;
	}
	return cur_size;
}

static void rewrite(FS * fs)
{
	enum { NOTOKAY, USEBCNT, USEPREC } sokay;
	PR *pr, **nextpr = NULL;
	FU *fu;
	char *p1, *p2, *p3;
	char savech, *fmtp;
	const char *byte_count_str;
	int nconv, prec = 0;

	for (fu = fs->nextfu; fu; fu = fu->nextfu) {
		/*
		 * break each format unit into print units; each
		 * conversion character gets its own.
		 */
		for (nconv = 0, fmtp = fu->fmt; *fmtp; nextpr = &pr->nextpr) {
			/* NOSTRICT */
			/* DBU:[dvae@cray.com] calloc so that forward ptrs start out NULL*/
			pr = xzalloc(sizeof(PR));
			if (!fu->nextpr)
				fu->nextpr = pr;
			/* ignore nextpr -- its unused inside the loop and is
			 * uninitialized 1st time thru.
			 */

			/* bb_dump_skip preceding text and up to the next % sign */
			for (p1 = fmtp; *p1 && *p1 != '%'; ++p1);

			/* only text in the string */
			if (!*p1) {
				pr->fmt = fmtp;
				pr->flags = F_TEXT;
				break;
			}

			/*
			 * get precision for %s -- if have a byte count, don't
			 * need it.
			 */
			if (fu->bcnt) {
				sokay = USEBCNT;
				/* bb_dump_skip to conversion character */
				for (++p1; strchr(index_str, *p1); ++p1);
			} else {
				/* bb_dump_skip any special chars, field width */
				while (strchr(index_str + 1, *++p1));
				if (*p1 == '.' && isdigit(*++p1)) {
					sokay = USEPREC;
					prec = atoi(p1);
					while (isdigit(*++p1));
				} else
					sokay = NOTOKAY;
			}

			p2 = p1 + 1;	/* set end pointer */

			/*
			 * figure out the byte count for each conversion;
			 * rewrite the format as necessary, set up blank-
			 * pbb_dump_adding for end of data.
			 */

			if (*p1 == 'c') {
				pr->flags = F_CHAR;
			DO_BYTE_COUNT_1:
				byte_count_str = "\001";
			DO_BYTE_COUNT:
				if (fu->bcnt) {
					do {
						if (fu->bcnt == *byte_count_str) {
							break;
						}
					} while (*++byte_count_str);
				}
				/* Unlike the original, output the remainder of the format string. */
				if (!*byte_count_str) {
					bb_error_msg_and_die("bad byte count for conversion character %s", p1);
				}
				pr->bcnt = *byte_count_str;
			} else if (*p1 == 'l') {
				++p2;
				++p1;
			DO_INT_CONV:
				{
					const char *e;
					if (!(e = strchr(lcc, *p1))) {
						goto DO_BAD_CONV_CHAR;
					}
					pr->flags = F_INT;
					if (e > lcc + 1) {
						pr->flags = F_UINT;
					}
					byte_count_str = "\004\002\001";
					goto DO_BYTE_COUNT;
				}
				/* NOTREACHED */
			} else if (strchr(lcc, *p1)) {
				goto DO_INT_CONV;
			} else if (strchr("eEfgG", *p1)) {
				pr->flags = F_DBL;
				byte_count_str = "\010\004";
				goto DO_BYTE_COUNT;
			} else if (*p1 == 's') {
				pr->flags = F_STR;
				if (sokay == USEBCNT) {
					pr->bcnt = fu->bcnt;
				} else if (sokay == USEPREC) {
					pr->bcnt = prec;
				} else {	/* NOTOKAY */
					bb_error_msg_and_die("%%s requires a precision or a byte count");
				}
			} else if (*p1 == '_') {
				++p2;
				switch (p1[1]) {
				case 'A':
					endfu = fu;
					fu->flags |= F_IGNORE;
					/* FALLTHROUGH */
				case 'a':
					pr->flags = F_ADDRESS;
					++p2;
					if ((p1[2] != 'd') && (p1[2] != 'o') && (p1[2] != 'x')) {
						goto DO_BAD_CONV_CHAR;
					}
					*p1 = p1[2];
					break;
				case 'c':
					pr->flags = F_C;
					/* *p1 = 'c';   set in conv_c */
					goto DO_BYTE_COUNT_1;
				case 'p':
					pr->flags = F_P;
					*p1 = 'c';
					goto DO_BYTE_COUNT_1;
				case 'u':
					pr->flags = F_U;
					/* *p1 = 'c';   set in conv_u */
					goto DO_BYTE_COUNT_1;
				default:
					goto DO_BAD_CONV_CHAR;
				}
			} else {
			DO_BAD_CONV_CHAR:
				bb_error_msg_and_die("bad conversion character %%%s", p1);
			}

			/*
			 * copy to PR format string, set conversion character
			 * pointer, update original.
			 */
			savech = *p2;
			p1[1] = '\0';
			pr->fmt = xstrdup(fmtp);
			*p2 = savech;
			pr->cchar = pr->fmt + (p1 - fmtp);

			/* DBU:[dave@cray.com] w/o this, trailing fmt text, space is lost.
			 * Skip subsequent text and up to the next % sign and tack the
			 * additional text onto fmt: eg. if fmt is "%x is a HEX number",
			 * we lose the " is a HEX number" part of fmt.
			 */
			for (p3 = p2; *p3 && *p3 != '%'; p3++);
			if (p3 > p2)
			{
				savech = *p3;
				*p3 = '\0';
				pr->fmt = xrealloc(pr->fmt, strlen(pr->fmt)+(p3-p2)+1);
				strcat(pr->fmt, p2);
				*p3 = savech;
				p2 = p3;
			}

			fmtp = p2;

			/* only one conversion character if byte count */
			if (!(pr->flags & F_ADDRESS) && fu->bcnt && nconv++) {
				bb_error_msg_and_die("byte count with multiple conversion characters");
			}
		}
		/*
		 * if format unit byte count not specified, figure it out
		 * so can adjust rep count later.
		 */
		if (!fu->bcnt)
			for (pr = fu->nextpr; pr; pr = pr->nextpr)
				fu->bcnt += pr->bcnt;
	}
	/*
	 * if the format string interprets any data at all, and it's
	 * not the same as the bb_dump_blocksize, and its last format unit
	 * interprets any data at all, and has no iteration count,
	 * repeat it as necessary.
	 *
	 * if, rep count is greater than 1, no trailing whitespace
	 * gets output from the last iteration of the format unit.
	 */
	for (fu = fs->nextfu;; fu = fu->nextfu) {
		if (!fu->nextfu && fs->bcnt < bb_dump_blocksize &&
			!(fu->flags & F_SETREP) && fu->bcnt)
			fu->reps += (bb_dump_blocksize - fs->bcnt) / fu->bcnt;
		if (fu->reps > 1) {
			for (pr = fu->nextpr;; pr = pr->nextpr)
				if (!pr->nextpr)
					break;
			for (p1 = pr->fmt, p2 = NULL; *p1; ++p1)
				p2 = isspace(*p1) ? p1 : NULL;
			if (p2)
				pr->nospace = p2;
		}
		if (!fu->nextfu)
			break;
	}
}

static void do_skip(const char *fname, int statok)
{
	struct stat sbuf;

	if (statok) {
		if (fstat(STDIN_FILENO, &sbuf)) {
			bb_simple_perror_msg_and_die(fname);
		}
		if ((!(S_ISCHR(sbuf.st_mode) ||
			   S_ISBLK(sbuf.st_mode) ||
			   S_ISFIFO(sbuf.st_mode))) && bb_dump_skip >= sbuf.st_size) {
			/* If bb_dump_size valid and bb_dump_skip >= size */
			bb_dump_skip -= sbuf.st_size;
			address += sbuf.st_size;
			return;
		}
	}
	if (fseek(stdin, bb_dump_skip, SEEK_SET)) {
		bb_simple_perror_msg_and_die(fname);
	}
	savaddress = address += bb_dump_skip;
	bb_dump_skip = 0;
}

static int next(char **argv)
{
	static smallint done;

	int statok;

	if (argv) {
		_argv = argv;
		return 1;
	}
	for (;;) {
		if (*_argv) {
			if (!(freopen(*_argv, "r", stdin))) {
				bb_simple_perror_msg(*_argv);
				exitval = 1;
				++_argv;
				continue;
			}
			done = statok = 1;
		} else {
			if (done)
				return 0;
			done = 1;
			statok = 0;
		}
		if (bb_dump_skip)
			do_skip(statok ? *_argv : "stdin", statok);
		if (*_argv)
			++_argv;
		if (!bb_dump_skip)
			return 1;
	}
	/* NOTREACHED */
}

static unsigned char *get(void)
{
	static smallint ateof = 1;
	static unsigned char *curp = NULL, *savp; /*DBU:[dave@cray.com]initialize curp */

	int n;
	int need, nread;
	unsigned char *tmpp;

	if (!curp) {
		address = (off_t)0; /*DBU:[dave@cray.com] initialize,initialize..*/
		curp = xmalloc(bb_dump_blocksize);
		savp = xmalloc(bb_dump_blocksize);
	} else {
		tmpp = curp;
		curp = savp;
		savp = tmpp;
		address = savaddress += bb_dump_blocksize;
	}
	for (need = bb_dump_blocksize, nread = 0;;) {
		/*
		 * if read the right number of bytes, or at EOF for one file,
		 * and no other files are available, zero-pad the rest of the
		 * block and set the end flag.
		 */
		if (!bb_dump_length || (ateof && !next((char **) NULL))) {
			if (need == bb_dump_blocksize) {
				return NULL;
			}
			if (bb_dump_vflag != ALL && !memcmp(curp, savp, nread)) {
				if (bb_dump_vflag != DUP) {
					puts("*");
				}
				return NULL;
			}
			memset((char *) curp + nread, 0, need);
			eaddress = address + nread;
			return curp;
		}
		n = fread((char *) curp + nread, sizeof(unsigned char),
				  bb_dump_length == -1 ? need : MIN(bb_dump_length, need), stdin);
		if (!n) {
			if (ferror(stdin)) {
				bb_simple_perror_msg(_argv[-1]);
			}
			ateof = 1;
			continue;
		}
		ateof = 0;
		if (bb_dump_length != -1) {
			bb_dump_length -= n;
		}
		need -= n;
		if (!need) {
			if (bb_dump_vflag == ALL || bb_dump_vflag == FIRST
				|| memcmp(curp, savp, bb_dump_blocksize)) {
				if (bb_dump_vflag == DUP || bb_dump_vflag == FIRST) {
					bb_dump_vflag = WAIT;
				}
				return curp;
			}
			if (bb_dump_vflag == WAIT) {
				puts("*");
			}
			bb_dump_vflag = DUP;
			address = savaddress += bb_dump_blocksize;
			need = bb_dump_blocksize;
			nread = 0;
		} else {
			nread += n;
		}
	}
}

static void bpad(PR * pr)
{
	char *p1, *p2;

	/*
	 * remove all conversion flags; '-' is the only one valid
	 * with %s, and it's not useful here.
	 */
	pr->flags = F_BPAD;
	*pr->cchar = 's';
	for (p1 = pr->fmt; *p1 != '%'; ++p1);
	for (p2 = ++p1; *p1 && strchr(" -0+#", *p1); ++p1)
		if (pr->nospace) pr->nospace--;
	while ((*p2++ = *p1++) != 0);
}

static const char conv_str[] ALIGN1 =
	"\0\\0\0"
	"\007\\a\0"				/* \a */
	"\b\\b\0"
	"\f\\b\0"
	"\n\\n\0"
	"\r\\r\0"
	"\t\\t\0"
	"\v\\v\0"
	;


static void conv_c(PR * pr, unsigned char * p)
{
	const char *str = conv_str;
	char buf[10];

	do {
		if (*p == *str) {
			++str;
			goto strpr;
		}
		str += 4;
	} while (*str);

	if (isprint(*p)) {
		*pr->cchar = 'c';
		(void) printf(pr->fmt, *p);
	} else {
		sprintf(buf, "%03o", (int) *p);
		str = buf;
	  strpr:
		*pr->cchar = 's';
		printf(pr->fmt, str);
	}
}

static void conv_u(PR * pr, unsigned char * p)
{
	static const char list[] ALIGN1 =
		"nul\0soh\0stx\0etx\0eot\0enq\0ack\0bel\0"
		"bs\0_ht\0_lf\0_vt\0_ff\0_cr\0_so\0_si\0_"
		"dle\0dcl\0dc2\0dc3\0dc4\0nak\0syn\0etb\0"
		"can\0em\0_sub\0esc\0fs\0_gs\0_rs\0_us";

	/* od used nl, not lf */
	if (*p <= 0x1f) {
		*pr->cchar = 's';
		printf(pr->fmt, list + (4 * (int)*p));
	} else if (*p == 0x7f) {
		*pr->cchar = 's';
		printf(pr->fmt, "del");
	} else if (isprint(*p)) {
		*pr->cchar = 'c';
		printf(pr->fmt, *p);
	} else {
		*pr->cchar = 'x';
		printf(pr->fmt, (int) *p);
	}
}

static void display(void)
{
/*  extern FU *endfu; */
	FS *fs;
	FU *fu;
	PR *pr;
	int cnt;
	unsigned char *bp;

	off_t saveaddress;
	unsigned char savech = 0, *savebp;

	while ((bp = get()) != NULL) {
		for (fs = bb_dump_fshead, savebp = bp, saveaddress = address; fs;
			 fs = fs->nextfs, bp = savebp, address = saveaddress) {
			for (fu = fs->nextfu; fu; fu = fu->nextfu) {
				if (fu->flags & F_IGNORE) {
					break;
				}
				for (cnt = fu->reps; cnt; --cnt) {
					for (pr = fu->nextpr; pr; address += pr->bcnt,
						 bp += pr->bcnt, pr = pr->nextpr) {
						if (eaddress && address >= eaddress &&
							!(pr->flags & (F_TEXT | F_BPAD))) {
							bpad(pr);
						}
						if (cnt == 1 && pr->nospace) {
							savech = *pr->nospace;
							*pr->nospace = '\0';
						}
/*                      PRINT; */
						switch (pr->flags) {
						case F_ADDRESS:
							printf(pr->fmt, (unsigned int) address);
							break;
						case F_BPAD:
							printf(pr->fmt, "");
							break;
						case F_C:
							conv_c(pr, bp);
							break;
						case F_CHAR:
							printf(pr->fmt, *bp);
							break;
						case F_DBL:{
							double dval;
							float fval;

							switch (pr->bcnt) {
							case 4:
								memmove((char *) &fval, (char *) bp,
									  sizeof(fval));
								printf(pr->fmt, fval);
								break;
							case 8:
								memmove((char *) &dval, (char *) bp,
									  sizeof(dval));
								printf(pr->fmt, dval);
								break;
							}
							break;
						}
						case F_INT:{
							int ival;
							short sval;

							switch (pr->bcnt) {
							case 1:
								printf(pr->fmt, (int) *bp);
								break;
							case 2:
								memmove((char *) &sval, (char *) bp,
									  sizeof(sval));
								printf(pr->fmt, (int) sval);
								break;
							case 4:
								memmove((char *) &ival, (char *) bp,
									  sizeof(ival));
								printf(pr->fmt, ival);
								break;
							}
							break;
						}
						case F_P:
							printf(pr->fmt, isprint(*bp) ? *bp : '.');
							break;
						case F_STR:
							printf(pr->fmt, (char *) bp);
							break;
						case F_TEXT:
							printf(pr->fmt);
							break;
						case F_U:
							conv_u(pr, bp);
							break;
						case F_UINT:{
							unsigned int ival;
							unsigned short sval;

							switch (pr->bcnt) {
							case 1:
								printf(pr->fmt, (unsigned int) * bp);
								break;
							case 2:
								memmove((char *) &sval, (char *) bp,
									  sizeof(sval));
								printf(pr->fmt, (unsigned int) sval);
								break;
							case 4:
								memmove((char *) &ival, (char *) bp,
									  sizeof(ival));
								printf(pr->fmt, ival);
								break;
							}
							break;
						}
						}
						if (cnt == 1 && pr->nospace) {
							*pr->nospace = savech;
						}
					}
				}
			}
		}
	}
	if (endfu) {
		/*
		 * if eaddress not set, error or file bb_dump_size was multiple of
		 * bb_dump_blocksize, and no partial block ever found.
		 */
		if (!eaddress) {
			if (!address) {
				return;
			}
			eaddress = address;
		}
		for (pr = endfu->nextpr; pr; pr = pr->nextpr) {
			switch (pr->flags) {
			case F_ADDRESS:
				(void) printf(pr->fmt, (unsigned int) eaddress);
				break;
			case F_TEXT:
				(void) printf(pr->fmt);
				break;
			}
		}
	}
}

int bb_dump_dump(char **argv)
{
	FS *tfs;

	/* figure out the data block bb_dump_size */
	for (bb_dump_blocksize = 0, tfs = bb_dump_fshead; tfs; tfs = tfs->nextfs) {
		tfs->bcnt = bb_dump_size(tfs);
		if (bb_dump_blocksize < tfs->bcnt) {
			bb_dump_blocksize = tfs->bcnt;
		}
	}
	/* rewrite the rules, do syntax checking */
	for (tfs = bb_dump_fshead; tfs; tfs = tfs->nextfs) {
		rewrite(tfs);
	}

	next(argv);
	display();

	return exitval;
}

void bb_dump_add(const char *fmt)
{
	const char *p;
	char *p1;
	char *p2;
	static FS **nextfs;
	FS *tfs;
	FU *tfu, **nextfu;
	const char *savep;

	/* start new linked list of format units */
	tfs = xzalloc(sizeof(FS)); /*DBU:[dave@cray.com] start out NULL */
	if (!bb_dump_fshead) {
		bb_dump_fshead = tfs;
	} else {
		*nextfs = tfs;
	}
	nextfs = &tfs->nextfs;
	nextfu = &tfs->nextfu;

	/* take the format string and break it up into format units */
	for (p = fmt;;) {
		/* bb_dump_skip leading white space */
		p = skip_whitespace(p);
		if (!*p) {
			break;
		}

		/* allocate a new format unit and link it in */
		/* NOSTRICT */
		/* DBU:[dave@cray.com] calloc so that forward pointers start out NULL */
		tfu = xzalloc(sizeof(FU));
		*nextfu = tfu;
		nextfu = &tfu->nextfu;
		tfu->reps = 1;

		/* if leading digit, repetition count */
		if (isdigit(*p)) {
			for (savep = p; isdigit(*p); ++p);
			if (!isspace(*p) && *p != '/') {
				bb_error_msg_and_die("bad format {%s}", fmt);
			}
			/* may overwrite either white space or slash */
			tfu->reps = atoi(savep);
			tfu->flags = F_SETREP;
			/* bb_dump_skip trailing white space */
			p = skip_whitespace(++p);
		}

		/* bb_dump_skip slash and trailing white space */
		if (*p == '/') {
			p = skip_whitespace(++p);
		}

		/* byte count */
		if (isdigit(*p)) {
// TODO: use bb_strtou
			savep = p;
			do p++; while (isdigit(*p));
			if (!isspace(*p)) {
				bb_error_msg_and_die("bad format {%s}", fmt);
			}
			tfu->bcnt = atoi(savep);
			/* bb_dump_skip trailing white space */
			p = skip_whitespace(++p);
		}

		/* format */
		if (*p != '"') {
			bb_error_msg_and_die("bad format {%s}", fmt);
		}
		for (savep = ++p; *p != '"';) {
			if (*p++ == 0) {
				bb_error_msg_and_die("bad format {%s}", fmt);
			}
		}
		tfu->fmt = xmalloc(p - savep + 1);
		strncpy(tfu->fmt, savep, p - savep);
		tfu->fmt[p - savep] = '\0';
/*      escape(tfu->fmt); */

		p1 = tfu->fmt;

		/* alphabetic escape sequences have to be done in place */
		for (p2 = p1;; ++p1, ++p2) {
			if (!*p1) {
				*p2 = *p1;
				break;
			}
			if (*p1 == '\\') {
				const char *cs = conv_str + 4;
				++p1;
				*p2 = *p1;
				do {
					if (*p1 == cs[2]) {
						*p2 = cs[0];
						break;
					}
					cs += 4;
				} while (*cs);
			}
		}

		p++;
	}
}

/*
 * Copyright (c) 1989 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.
 */
