/*
 * 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. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. 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.
 */

 /* 1999-02-22 Arkadiusz Miśkiewicz <misiek@pld.ORG.PL>
  * - added Native Language Support
  */

#include <sys/types.h>
#include <sys/file.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "hexdump.h"
#include "nls.h"
#include "xalloc.h"
#include "strutils.h"
#include "colors.h"

static void escape(char *p1);
static struct list_head *color_fmt(char *cfmt, int bcnt);

static void __attribute__ ((__noreturn__)) badcnt(const char *s)
{
        errx(EXIT_FAILURE, _("bad byte count for conversion character %s"), s);
}

static void __attribute__ ((__noreturn__)) badsfmt(void)
{
        errx(EXIT_FAILURE, _("%%s requires a precision or a byte count"));
}

static void __attribute__ ((__noreturn__)) badfmt(const char *fmt)
{
        errx(EXIT_FAILURE, _("bad format {%s}"), fmt);
}

static void __attribute__ ((__noreturn__)) badconv(const char *ch)
{
        errx(EXIT_FAILURE, _("bad conversion character %%%s"), ch);
}

#define first_letter(s,f) strchr(f, *(s))

struct hexdump_fu *endfu;					/* format at end-of-data */

void addfile(char *name, struct hexdump *hex)
{
	char *fmt, *buf = NULL;
	FILE *fp;
	size_t n;

	if ((fp = fopen(name, "r")) == NULL)
	        err(EXIT_FAILURE, _("can't read %s"), name);

	while (getline(&buf, &n, fp) != -1) {
		fmt = buf;

		while (*fmt && isspace(*fmt))
			++fmt;
		if (!*fmt || *fmt == '#')
			continue;

		add_fmt(fmt, hex);
	}

	free(buf);
	fclose(fp);
}

void add_fmt(const char *fmt, struct hexdump *hex)
{
	const char *p, *savep;
	struct hexdump_fs *tfs;
	struct hexdump_fu *tfu;

	/* Start new linked list of format units. */
	tfs = xcalloc(1, sizeof(struct hexdump_fs));
	INIT_LIST_HEAD(&tfs->fslist);
	INIT_LIST_HEAD(&tfs->fulist);
	list_add_tail(&tfs->fslist, &hex->fshead);

	/* Take the format string and break it up into format units. */
	p = fmt;
	while (TRUE) {
		/* Skip leading white space. */
		if (!*(p = skip_space(p)))
			break;

		/* Allocate a new format unit and link it in. */
		tfu = xcalloc(1, sizeof(struct hexdump_fu));
		tfu->reps = 1;

		INIT_LIST_HEAD(&tfu->fulist);
		INIT_LIST_HEAD(&tfu->prlist);
		list_add_tail(&tfu->fulist, &tfs->fulist);

		/* If leading digit, repetition count. */
		if (isdigit(*p)) {
			savep = p;
			while (isdigit(*p) && ++p)
				;
			if (!isspace(*p) && *p != '/')
				badfmt(fmt);
			/* may overwrite either white space or slash */
			tfu->reps = atoi(savep);
			tfu->flags = F_SETREP;
			/* skip trailing white space */
			p = skip_space(++p);
		}

		/* Skip slash and trailing white space. */
		if (*p == '/')
			p = skip_space(++p);

		/* byte count */
		if (isdigit(*p)) {
			savep = p;
			while (isdigit(*p) && ++p)
				;
			if (!isspace(*p))
				badfmt(fmt);
			tfu->bcnt = atoi(savep);
			/* skip trailing white space */
			p = skip_space(++p);
		}

		/* format */
		if (*p != '"')
			badfmt(fmt);
		savep = ++p;
		while (*p != '"') {
			if (!*p++)
				badfmt(fmt);
		}
		tfu->fmt = xmalloc(p - savep + 1);
		xstrncpy(tfu->fmt, savep, p - savep + 1);
		escape(tfu->fmt);
		++p;
	}
}

static const char *spec = ".#-+ 0123456789";

int block_size(struct hexdump_fs *fs)
{
	struct hexdump_fu *fu;
	int bcnt, prec, cursize = 0;
	char *fmt;
	struct list_head *p;

	/* figure out the data block size needed for each format unit */
	list_for_each (p, &fs->fulist) {
		fu = list_entry(p, struct hexdump_fu, fulist);
		if (fu->bcnt) {
			cursize += fu->bcnt * fu->reps;
			continue;
		}
		bcnt = prec = 0;
		fmt = fu->fmt;
		while (*fmt) {
			if (*fmt != '%') {
				++fmt;
				continue;
			}
			/*
			 * skip any special chars -- save precision in
			 * case it's a %s format.
			 */
			while (strchr(spec + 1, *++fmt))
				;
			if (*fmt == '.' && isdigit(*++fmt)) {
				prec = atoi(fmt);
				while (isdigit(*++fmt))
					;
			}
			if (first_letter(fmt, "diouxX"))
				bcnt += 4;
			else if (first_letter(fmt, "efgEG"))
				bcnt += 8;
			else if (*fmt == 's')
				bcnt += prec;
			else if (*fmt == 'c' || (*fmt == '_' && first_letter(++fmt, "cpu")))
				++bcnt;
			++fmt;
		}
		cursize += bcnt * fu->reps;
	}
	return(cursize);
}

void rewrite_rules(struct hexdump_fs *fs, struct hexdump *hex)
{
	enum { NOTOKAY, USEBCNT, USEPREC } sokay;
	struct hexdump_pr *pr;
	struct hexdump_fu *fu;
	struct list_head *p, *q;
	char *p1, *p2, *fmtp;
	char savech, cs[4];
	int nconv, prec = 0;

	list_for_each (p, &fs->fulist) {
		fu = list_entry(p, struct hexdump_fu, fulist);
		/*
		 * Break each format unit into print units; each
		 * conversion character gets its own.
		 */
		nconv = 0;
		fmtp = fu->fmt;
		while (*fmtp) {
			pr = xcalloc(1, sizeof(struct hexdump_pr));
			INIT_LIST_HEAD(&pr->prlist);
			list_add_tail(&pr->prlist, &fu->prlist);

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

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

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

			p2 = p1 + 1;		/* Set end pointer. */
			cs[0] = *p1;		/* Set conversion string. */
			cs[1] = 0;

			/*
			 * Figure out the byte count for each conversion;
			 * rewrite the format as necessary, set up blank-
			 * padding for end of data.
			 */
			if (*cs == 'c') {
				pr->flags = F_CHAR;
				switch(fu->bcnt) {
					case 0:
					case 1:
						pr->bcnt = 1;
						break;
					default:
						p1[1] = '\0';
						badcnt(p1);
				}
			} else if (first_letter(cs, "di")) {
				pr->flags = F_INT;
				goto isint;
			} else if (first_letter(cs, "ouxX")) {
				pr->flags = F_UINT;
isint:				cs[3] = '\0';
				cs[2] = cs[0];
				cs[1] = 'l';
				cs[0] = 'l';
				switch(fu->bcnt) {
					case 0:
						pr->bcnt = 4;
						break;
					case 1:
					case 2:
					case 4:
					case 8:
						pr->bcnt = fu->bcnt;
						break;
					default:
						p1[1] = '\0';
						badcnt(p1);
				}
			} else if (first_letter(cs, "efgEG")) {
				pr->flags = F_DBL;
				switch(fu->bcnt) {
					case 0:
						pr->bcnt = 8;
						break;
					case 4:
					case 8:
						pr->bcnt = fu->bcnt;
						break;
					default:
						p1[1] = '\0';
						badcnt(p1);
				}
			} else if(*cs == 's') {
				pr->flags = F_STR;
				switch(sokay) {
					case NOTOKAY:
						badsfmt();
					case USEBCNT:
						pr->bcnt = fu->bcnt;
						break;
					case USEPREC:
						pr->bcnt = prec;
						break;
				}
			} else if (*cs == '_') {
				++p2;
				switch(p1[1]) {
					case 'A':
						endfu = fu;
						fu->flags |= F_IGNORE;
						/* fallthrough */
					case 'a':
						pr->flags = F_ADDRESS;
						++p2;
						if (first_letter(p1 + 2, "dox")) {
							cs[0] = 'l';
							cs[1] = 'l';
							cs[2] = p1[2];
							cs[3] = '\0';
						} else {
							p1[3] = '\0';
							badconv(p1);
						}
						break;
					case 'c':
						pr->flags = F_C;
						/* cs[0] = 'c';	set in conv_c */
						goto isint2;
					case 'p':
						pr->flags = F_P;
						cs[0] = 'c';
						goto isint2;
					case 'u':
						pr->flags = F_U;
						/* cs[0] = 'c';	set in conv_u */
	isint2:					switch(fu->bcnt) {
							case 0:
							case 1:
								pr->bcnt = 1;
								break;
							default:
								p1[2] = '\0';
								badcnt(p1);
						}
						break;
					default:
						p1[2] = '\0';
						badconv(p1);
				}
			} else {
				p1[1] = '\0';
				badconv(p1);
			}

			/* Color unit(s) specified */
			if (*p2 == '_' && p2[1] == 'L') {
				if (colors_wanted()) {
					char *a;

					/* "cut out" the color_unit(s) */
					a = strchr(p2, '[');
					p2 = strrchr(p2, ']');
					if (a++ && p2)
						pr->colorlist = color_fmt(xstrndup(a, p2++ - a), pr->bcnt);
					else
						badconv(p2);
				}
				/* we don't want colors, quietly skip over them */
				else {
					p2 = strrchr(p2, ']');
					/* be a bit louder if we don't know how to skip over them */
					if (!p2)
						badconv("_L");
					++p2;
				}
			}
			/*
			 * Copy to hexdump_pr format string, set conversion character
			 * pointer, update original.
			 */
			savech = *p2;
			p1[0] = '\0';
			pr->fmt = xmalloc(strlen(fmtp) + strlen(cs) + 1);
			strcpy(pr->fmt, fmtp);
			strcat(pr->fmt, cs);
			*p2 = savech;
			pr->cchar = pr->fmt + (p1 - fmtp);
			fmtp = p2;

			/* Only one conversion character if byte count */
			if (!(pr->flags&F_ADDRESS) && fu->bcnt && nconv++)
				errx(EXIT_FAILURE,
				    _("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)
			list_for_each(q, &fu->prlist)
				fu->bcnt
				  += (list_entry(q, struct hexdump_pr, prlist))->bcnt;
	}
	/*
	 * If the format string interprets any data at all, and it's
	 * not the same as the 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.
	 */
	list_for_each (p, &fs->fulist) {
		fu = list_entry(p, struct hexdump_fu, fulist);

		if (list_entry_is_last(&fu->fulist, &fs->fulist) &&
			fs->bcnt < hex->blocksize &&
			!(fu->flags&F_SETREP) && fu->bcnt)
				fu->reps += (hex->blocksize - fs->bcnt) / fu->bcnt;
		if (fu->reps > 1 && !list_empty(&fu->prlist)) {
			pr = list_last_entry(&fu->prlist, struct hexdump_pr, prlist);
			for (p1 = pr->fmt, p2 = NULL; *p1; ++p1)
				p2 = isspace(*p1) ? p1 : NULL;
			if (p2)
				pr->nospace = p2;
		}
	}
}

/* [!]color[:string|:hex_number|:oct_number][@offt|@offt_start-offt_end],... */
static struct list_head *color_fmt(char *cfmt, int bcnt)
{
	struct hexdump_clr *hc, *hcnext;
	struct list_head *ret_head;
	char *clr, *fmt;

	ret_head = xmalloc(sizeof(struct list_head));
	hcnext = hc = xcalloc(1, sizeof(struct hexdump_clr));

	INIT_LIST_HEAD(&hc->colorlist);
	INIT_LIST_HEAD(ret_head);
	list_add_tail(&hc->colorlist, ret_head);

	fmt = cfmt;
	while (cfmt && *cfmt) {
		char *end;
		/* invert this condition */
		if (*cfmt == '!') {
			hcnext->invert = 1;
			++cfmt;
		}

		clr = xstrndup(cfmt, strcspn(cfmt, ":@,"));
		cfmt += strlen(clr);
		hcnext->fmt = color_sequence_from_colorname(clr);
		free(clr);

		if (!hcnext->fmt)
			return NULL;

		/* only colorize this specific value */
		if (*cfmt == ':') {
			++cfmt;
			/* a hex or oct value */
			if (*cfmt == '0') {
				/* hex */
				errno = 0;
				end = NULL;
				if (cfmt[1] == 'x' || cfmt[1] == 'X')
					hcnext->val = strtoul(cfmt + 2, &end, 16);
				else
					hcnext->val = strtoul(cfmt, &end, 8);
				if (errno || end == cfmt)
					badfmt(fmt);
				cfmt = end;
			/* a string */
			} else {
				off_t fmt_end;
				char endchar;
				char *endstr;

				hcnext->val = -1;
				/* temporarily null-delimit the format, so we can reverse-search
				 * for the start of an offset specifier */
				fmt_end = strcspn(cfmt, ",");
				endchar = cfmt[fmt_end];
				cfmt[fmt_end] = '\0';
				endstr = strrchr(cfmt, '@');

				if (endstr) {
					if (endstr[1] != '\0')
						--endstr;
					hcnext->str = xstrndup(cfmt, endstr - cfmt + 1);
				} else
					hcnext->str = xstrndup(cfmt, fmt_end);

				/* restore the character */
				cfmt[fmt_end] = endchar;
				cfmt += strlen(hcnext->str);
			}

		/* no specific value */
		} else
			hcnext->val = -1;

		/* only colorize at this offset */
		hcnext->range = bcnt;
		if (cfmt && *cfmt == '@') {
			errno = 0;
			hcnext->offt = strtoul(++cfmt, &cfmt, 10);
			if (errno)
				badfmt(fmt);

			/* offset range */
			if (*cfmt == '-') {
				++cfmt;
				errno = 0;

				hcnext->range =
				  strtoul(cfmt, &cfmt, 10) - hcnext->offt + 1;
				if (errno)
					badfmt(fmt);
				/* offset range must be between 0 and format byte count */
				if (hcnext->range < 0)
					badcnt("_L");
				/* the offset extends over several print units, clone
				 * the condition, link it in and adjust the address/offset */
				while (hcnext->range > bcnt) {
					hc = xcalloc(1, sizeof(struct hexdump_clr));
					memcpy(hc, hcnext, sizeof(struct hexdump_clr));

					hc->range = bcnt;

					INIT_LIST_HEAD(&hc->colorlist);
					list_add_tail(&hc->colorlist, ret_head);

					hcnext->offt += bcnt;
					hcnext->range -= bcnt;
				}
			}
		/* no specific offset */
		} else
			hcnext->offt = (off_t)-1;

		/* check if the string we're looking for is the same length as the range */
		if (hcnext->str && (int)strlen(hcnext->str) != hcnext->range)
			badcnt("_L");

		/* link in another condition */
		if (cfmt && *cfmt == ',') {
			++cfmt;

			hcnext = xcalloc(1, sizeof(struct hexdump_clr));
			INIT_LIST_HEAD(&hcnext->colorlist);
			list_add_tail(&hcnext->colorlist, ret_head);
		}
	}
	return ret_head;
}

static void escape(char *p1)
{
	char *p2;

	/* alphabetic escape sequences have to be done in place */
	p2 = p1;
	while (TRUE) {
		if (!*p1) {
			*p2 = *p1;
			break;
		}
		if (*p1 == '\\')
			switch(*++p1) {
			case 'a':
			     /* *p2 = '\a'; */
				*p2 = '\007';
				break;
			case 'b':
				*p2 = '\b';
				break;
			case 'f':
				*p2 = '\f';
				break;
			case 'n':
				*p2 = '\n';
				break;
			case 'r':
				*p2 = '\r';
				break;
			case 't':
				*p2 = '\t';
				break;
			case 'v':
				*p2 = '\v';
				break;
			default:
				*p2 = *p1;
				break;
			}
		++p1; ++p2;
	}
}
