xref: /csrg-svn/usr.bin/hexdump/bpad.c (revision 38853)
1*38853Sbostic /*
2*38853Sbostic  * Copyright (c) 1989 The Regents of the University of California.
3*38853Sbostic  * All rights reserved.
4*38853Sbostic  *
5*38853Sbostic  * Redistribution and use in source and binary forms are permitted
6*38853Sbostic  * provided that the above copyright notice and this paragraph are
7*38853Sbostic  * duplicated in all such forms and that any documentation,
8*38853Sbostic  * advertising materials, and other materials related to such
9*38853Sbostic  * distribution and use acknowledge that the software was developed
10*38853Sbostic  * by the University of California, Berkeley.  The name of the
11*38853Sbostic  * University may not be used to endorse or promote products derived
12*38853Sbostic  * from this software without specific prior written permission.
13*38853Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*38853Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*38853Sbostic  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16*38853Sbostic  */
17*38853Sbostic 
18*38853Sbostic #ifndef lint
19*38853Sbostic static char sccsid[] = "@(#)bpad.c	5.1 (Berkeley) 08/29/89";
20*38853Sbostic #endif /* not lint */
21*38853Sbostic 
22*38853Sbostic #include <sys/types.h>
23*38853Sbostic #include <stdio.h>
24*38853Sbostic #include <ctype.h>
25*38853Sbostic #include "hexdump.h"
26*38853Sbostic 
27*38853Sbostic bpad(fu, pr, bp)
28*38853Sbostic 	FU *fu;
29*38853Sbostic 	PR *pr;
30*38853Sbostic 	u_char *bp;
31*38853Sbostic {
32*38853Sbostic 	static char *spec1 = "-0+ #";
33*38853Sbostic 	static char *spec2 = ".0123456789";
34*38853Sbostic 	enum { NONE, ZEROPAD, NOTSET } fw;
35*38853Sbostic 	register char *p1, *p2;
36*38853Sbostic 	FU *s_fu;
37*38853Sbostic 	PR *cur_pr, *s_pr, *txt_pr;
38*38853Sbostic 	int newlinecnt;
39*38853Sbostic 	char *txt_p1;
40*38853Sbostic 
41*38853Sbostic 	/*
42*38853Sbostic 	 * the format string has no more data to print out.  Go through
43*38853Sbostic 	 * the rest of the format string, and, for all non-%s conversions,
44*38853Sbostic 	 * replace with %s and remove any conversion flags that don't
45*38853Sbostic 	 * apply to %s.  This should replace any output with an equivalent
46*38853Sbostic 	 * number of spaces.  At the same time, keep track of any text
47*38853Sbostic 	 * that must be printed, i.e. constant text from the user.  Use
48*38853Sbostic 	 * this to trim any trailing spaces and tabs, possibly interspersed
49*38853Sbostic 	 * by newlines, leaving only the newlines.
50*38853Sbostic 	 */
51*38853Sbostic 	s_fu = fu;
52*38853Sbostic 	cur_pr = pr;
53*38853Sbostic 	s_pr = pr = pr->nextpr;
54*38853Sbostic 	txt_pr = NULL;
55*38853Sbostic 	newlinecnt = 0;
56*38853Sbostic 	for (;;) {
57*38853Sbostic 		if (fu->flags&F_IGNORE)
58*38853Sbostic 			continue;
59*38853Sbostic 		for (; pr; pr = pr->nextpr) {
60*38853Sbostic 			if (pr->flags != F_TEXT)
61*38853Sbostic 				*pr->cchar = 's';
62*38853Sbostic 			for (p1 = p2 = pr->fmt; *p1; *p2++ = *p1++)
63*38853Sbostic 				switch (*p1) {
64*38853Sbostic 				/* remove conversion flags %s can't handle. */
65*38853Sbostic 				case '%':
66*38853Sbostic 					*p2++ = *p1;
67*38853Sbostic 					while (index(spec1, *++p1))
68*38853Sbostic 						if (*p1 == '-')
69*38853Sbostic 							*p2++ = '-';
70*38853Sbostic 					while (index(spec2, *p2++ = *p1++));
71*38853Sbostic 					break;
72*38853Sbostic 				/* ignore spaces and tabs */
73*38853Sbostic 				case ' ': case '\t':
74*38853Sbostic 					break;
75*38853Sbostic 				/* count newlines */
76*38853Sbostic 				case '\n':
77*38853Sbostic 					++newlinecnt;
78*38853Sbostic 					break;
79*38853Sbostic 				/*
80*38853Sbostic 				 * anything else has to be printed; keep track
81*38853Sbostic 				 * of it, and reset newline counter.
82*38853Sbostic 				 */
83*38853Sbostic 				default:
84*38853Sbostic 					txt_pr = pr;
85*38853Sbostic 					txt_p1 = p1 + 1;
86*38853Sbostic 					newlinecnt = 0;
87*38853Sbostic 					break;
88*38853Sbostic 				}
89*38853Sbostic 			*p2 = '\0';
90*38853Sbostic 		}
91*38853Sbostic 		if (!(fu = fu->nextfu))
92*38853Sbostic 			break;
93*38853Sbostic 		pr = fu->nextpr;
94*38853Sbostic 	}
95*38853Sbostic 	if (txt_pr) {
96*38853Sbostic 		/*
97*38853Sbostic 		 * if anything else has to be printed, print out the current
98*38853Sbostic 		 * item then the rest of the formats up to the one which has
99*38853Sbostic 		 * to be displayed.
100*38853Sbostic 		 */
101*38853Sbostic 		print(cur_pr, bp);
102*38853Sbostic 		*txt_p1 = '\0';
103*38853Sbostic 		for (fu = s_fu, pr = s_pr;;) {
104*38853Sbostic 			if (fu->flags&F_IGNORE)
105*38853Sbostic 				continue;
106*38853Sbostic 			for (; pr; pr = pr->nextpr) {
107*38853Sbostic 				(void)printf(pr->fmt, "");
108*38853Sbostic 				if (pr == txt_pr)
109*38853Sbostic 					goto done;
110*38853Sbostic 			}
111*38853Sbostic 			if (!(fu = fu->nextfu))
112*38853Sbostic 				break;
113*38853Sbostic 			pr = fu->nextpr;
114*38853Sbostic 		}
115*38853Sbostic 	} else {
116*38853Sbostic 		/*
117*38853Sbostic 		 * nothing else has to be printed -- serious special case.
118*38853Sbostic 		 * If current item is left justified and zero-pad flag not
119*38853Sbostic 		 * set, printf will space pad it.
120*38853Sbostic 		 */
121*38853Sbostic 		for (p1 = p2 = cur_pr->fmt; *p1; *p2++ = *p1++)
122*38853Sbostic 			if (*p1 == '%') {
123*38853Sbostic 				*p2++ = *p1++;
124*38853Sbostic 				for (fw = NOTSET; *p1; ++p1) {
125*38853Sbostic 					while (index(spec1 + 2, *p1))
126*38853Sbostic 						*p2++ = *p1++;
127*38853Sbostic 					if (*p1 == '-') {
128*38853Sbostic 						if (fw == NOTSET)
129*38853Sbostic 							fw = NONE;
130*38853Sbostic 						else if (fw == ZEROPAD)
131*38853Sbostic 							*p2++ = '-';
132*38853Sbostic 						continue;
133*38853Sbostic 					}
134*38853Sbostic 					if (*p1 == '0') {
135*38853Sbostic 						if (fw == NONE)
136*38853Sbostic 							*p2++ = '-';
137*38853Sbostic 						fw = ZEROPAD;
138*38853Sbostic 						*p2++ = '0';
139*38853Sbostic 						continue;
140*38853Sbostic 					}
141*38853Sbostic 					break;
142*38853Sbostic 				}
143*38853Sbostic 				if (fw == NONE)
144*38853Sbostic 					while (isdigit(*++p1));
145*38853Sbostic 				while (index(spec2, *p1))
146*38853Sbostic 					*p2++ = *p1++;
147*38853Sbostic 			}
148*38853Sbostic 		*p2 = '\0';
149*38853Sbostic 	}
150*38853Sbostic 	/* print out any trailing newlines */
151*38853Sbostic done:	while(newlinecnt--)
152*38853Sbostic 		(void)printf("\n");
153*38853Sbostic }
154