Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:19

0001 /*
0002  * Copyright (c) 1989, 1993
0003  *  The Regents of the University of California.  All rights reserved.
0004  *
0005  * Redistribution and use in source and binary forms, with or without
0006  * modification, are permitted provided that the following conditions
0007  * are met:
0008  * 1. Redistributions of source code must retain the above copyright
0009  *    notice, this list of conditions and the following disclaimer.
0010  * 2. Redistributions in binary form must reproduce the above copyright
0011  *    notice, this list of conditions and the following disclaimer in the
0012  *    documentation and/or other materials provided with the distribution.
0013  * 3. All advertising materials mentioning features or use of this software
0014  *    must display the following acknowledgement:
0015  *  This product includes software developed by the University of
0016  *  California, Berkeley and its contributors.
0017  * 4. Neither the name of the University nor the names of its contributors
0018  *    may be used to endorse or promote products derived from this software
0019  *    without specific prior written permission.
0020  *
0021  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
0022  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0024  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
0025  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0026  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
0027  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0028  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
0029  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
0030  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0031  * SUCH DAMAGE.
0032  */
0033 
0034 #ifdef __rtems__
0035 /* For wcwidth() visibility */
0036 #define _GNU_SOURCE
0037 #endif /* __rtems__ */
0038 #ifdef HAVE_CONFIG_H
0039 #include "config.h"
0040 #endif
0041 
0042 #ifndef __rtems__
0043 #ifndef lint
0044 static const char sccsid[] = "@(#)conv.c    8.1 (Berkeley) 6/6/93";
0045 #endif /* not lint */
0046 #endif /* __rtems__ */
0047 #include <sys/cdefs.h>
0048 __FBSDID("$FreeBSD: src/usr.bin/hexdump/conv.c,v 1.9 2006/07/31 14:17:04 jkoshy Exp $");
0049 
0050 #include <sys/types.h>
0051 
0052 #include <assert.h>
0053 #include <ctype.h>
0054 #include <limits.h>
0055 #include <stdio.h>
0056 #include <stdlib.h>
0057 #include <string.h>
0058 #include <wchar.h>
0059 #include <wctype.h>
0060 #include "hexdump.h"
0061 
0062 void
0063 conv_c(rtems_shell_hexdump_globals* globals, PR *pr, u_char *p, size_t bufsize)
0064 {
0065     char buf[10];
0066     char const *str;
0067     wchar_t wc;
0068     size_t clen, oclen;
0069     int converr, pad, width;
0070     char peekbuf[MB_LEN_MAX];
0071 
0072     if (pr->mbleft > 0) {
0073         str = "**";
0074         pr->mbleft--;
0075         goto strpr;
0076     }
0077 
0078     switch(*p) {
0079     case '\0':
0080         str = "\\0";
0081         goto strpr;
0082     /* case '\a': */
0083     case '\007':
0084         str = "\\a";
0085         goto strpr;
0086     case '\b':
0087         str = "\\b";
0088         goto strpr;
0089     case '\f':
0090         str = "\\f";
0091         goto strpr;
0092     case '\n':
0093         str = "\\n";
0094         goto strpr;
0095     case '\r':
0096         str = "\\r";
0097         goto strpr;
0098     case '\t':
0099         str = "\\t";
0100         goto strpr;
0101     case '\v':
0102         str = "\\v";
0103         goto strpr;
0104     default:
0105         break;
0106     }
0107     /*
0108      * Multibyte characters are disabled for hexdump(1) for backwards
0109      * compatibility and consistency (none of its other output formats
0110      * recognize them correctly).
0111      */
0112     converr = 0;
0113     if (odmode && MB_CUR_MAX > 1) {
0114         oclen = 0;
0115 retry:
0116         clen = mbrtowc(&wc, (char*)p, bufsize, &pr->mbstate);
0117         if (clen == 0)
0118             clen = 1;
0119         else if (clen == (size_t)-1 || (clen == (size_t)-2 &&
0120 #ifndef __rtems__
0121             buf == peekbuf)) {
0122 #else /* __rtems__ */
0123             &buf[0] == &peekbuf[0])) {
0124 #endif /* __rtems__ */
0125             memset(&pr->mbstate, 0, sizeof(pr->mbstate));
0126             wc = *p;
0127             clen = 1;
0128             converr = 1;
0129         } else if (clen == (size_t)-2) {
0130             /*
0131              * Incomplete character; peek ahead and see if we
0132              * can complete it.
0133              */
0134             oclen = bufsize;
0135             bufsize = peek(globals, p = (u_char*)peekbuf, MB_CUR_MAX);
0136             goto retry;
0137         }
0138         clen += oclen;
0139     } else {
0140         wc = *p;
0141         clen = 1;
0142     }
0143     if (!converr && iswprint(wc)) {
0144         if (!odmode) {
0145             *pr->cchar = 'c';
0146             (void)printf(pr->fmt, (int)wc);
0147         } else {
0148             *pr->cchar = 'C';
0149             assert(strcmp(pr->fmt, "%3C") == 0);
0150             width = wcwidth(wc);
0151             assert(width >= 0);
0152             pad = 3 - width;
0153             if (pad < 0)
0154                 pad = 0;
0155               #if defined(__rtems__)
0156                 (void)printf("%*s%lc", pad, "", (wint_t)wc);
0157               #else
0158                 (void)printf("%*s%lc", pad, "", wc);
0159               #endif
0160             pr->mbleft = clen - 1;
0161         }
0162     } else {
0163         (void)sprintf(buf, "%03o", (int)*p);
0164         str = buf;
0165 strpr:      *pr->cchar = 's';
0166         (void)printf(pr->fmt, str);
0167     }
0168 }
0169 
0170 void
0171 conv_u(rtems_shell_hexdump_globals* globals, PR *pr, u_char *p)
0172 {
0173     static char const * list[] = {
0174         "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
0175          "bs",  "ht",  "lf",  "vt",  "ff",  "cr",  "so",  "si",
0176         "dle", "dcl", "dc2", "dc3", "dc4", "nak", "syn", "etb",
0177         "can",  "em", "sub", "esc",  "fs",  "gs",  "rs",  "us",
0178     };
0179 
0180                         /* od used nl, not lf */
0181     if (*p <= 0x1f) {
0182         *pr->cchar = 's';
0183         if (odmode && *p == 0x0a)
0184             (void)printf(pr->fmt, "nl");
0185         else
0186             (void)printf(pr->fmt, list[*p]);
0187     } else if (*p == 0x7f) {
0188         *pr->cchar = 's';
0189         (void)printf(pr->fmt, "del");
0190     } else if (odmode && *p == 0x20) {  /* od replaced space with sp */
0191         *pr->cchar = 's';
0192         (void)printf(pr->fmt, " sp");
0193     } else if (isprint(*p)) {
0194         *pr->cchar = 'c';
0195         (void)printf(pr->fmt, *p);
0196     } else {
0197         *pr->cchar = 'x';
0198         (void)printf(pr->fmt, (int)*p);
0199     }
0200 }