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