LTP GCOV extension - code coverage report
Current view: directory - and-httpd/src - hexdump.c
Test: And-httpd coverage
Date: 2006-09-11 Instrumented lines: 59
Code covered: 88.1 % Executed lines: 52

       1                 : /*
       2                 :  *  Copyright (C) 2003, 2004, 2005  James Antill
       3                 :  *
       4                 :  *  This library is free software; you can redistribute it and/or
       5                 :  *  modify it under the terms of the GNU Lesser General Public
       6                 :  *  License as published by the Free Software Foundation; either
       7                 :  *  version 2 of the License, or (at your option) any later version.
       8                 :  *
       9                 :  *  This library is distributed in the hope that it will be useful,
      10                 :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      11                 :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12                 :  *  Lesser General Public License for more details.
      13                 :  *
      14                 :  *  You should have received a copy of the GNU Lesser General Public
      15                 :  *  License along with this library; if not, write to the Free Software
      16                 :  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      17                 :  *
      18                 :  *  email: james@and.org
      19                 :  */
      20                 : /* hexdump in "readable" format ... note this is a bit more fleshed out than
      21                 :  * some of the other examples mainly because I actually use it */
      22                 : 
      23                 : /* this is roughly equiv. to the Linux hexdump command...
      24                 : % rpm -qf /usr/bin/hexdump
      25                 : util-linux-2.11r-10
      26                 : % hexdump -e '"%08_ax:"
      27                 :             " " 2/1 "%02X"
      28                 :             " " 2/1 "%02X"
      29                 :             " " 2/1 "%02X"
      30                 :             " " 2/1 "%02X"
      31                 :             " " 2/1 "%02X"
      32                 :             " " 2/1 "%02X"
      33                 :             " " 2/1 "%02X"
      34                 :             " " 2/1 "%02X"'
      35                 :         -e '"  " 16 "%_p" "\n"'
      36                 : 
      37                 :        
      38                 :  * ...except that it prints the address in big hex digits, and it doesn't take
      39                 :  * you 30 minutes to remember how to type it out.
      40                 :  *  It also acts differently in that seperate files aren't merged
      41                 :  * into one output line (Ie. in this version each file starts on a new line,
      42                 :  * however the addresses are continuious).
      43                 : 
      44                 :  * It's also similar to "xxd" in vim, and "od -tx1z -Ax".
      45                 :  */
      46                 : #define EX_UTILS_NO_FUNCS 1
      47                 : #include "ex_utils.h"
      48                 : 
      49                 : #include "hexdump.h"
      50                 : 
      51                 : /* number of characters we output per line (assumes 80 char width screen)... */
      52                 : #define CHRS_PER_LINE 16
      53                 : 
      54                 : #ifndef CONF_USE_FAST_NUM_PRINT
      55                 : #define CONF_USE_FAST_NUM_PRINT 1
      56                 : #endif
      57                 : 
      58                 : #define APOS() (apos + ((s1)->len - orig_len))
      59                 : 
      60                 : #if !CONF_USE_FAST_NUM_PRINT
      61                 : /* simple print of a number */
      62                 : 
      63                 : /* print the address */
      64                 : # define EX_HEXDUMP_X8(s1, num) \
      65                 :     vstr_add_fmt(s1, APOS(), "0x%08X:", (num))
      66                 : /* print a set of two bytes */
      67                 : # define EX_HEXDUMP_X2X2(s1, num1, num2) \
      68                 :     vstr_add_fmt(s1, APOS(), " %02X%02X", (num1), (num2))
      69                 : /* print a byte and spaces for the missing byte */
      70                 : # define EX_HEXDUMP_X2__(s1, num1) \
      71                 :     vstr_add_fmt(s1, APOS(), " %02X  ",   (num1))
      72                 : #else
      73                 : /* fast print of a number */
      74                 : static const char *hexnums = "0123456789ABCDEF";
      75                 : 
      76                 : # define EX_HEXDUMP_BYTE(buf, b) do {           \
      77                 :       (buf)[1] = hexnums[((b) >> 0) & 0xf];     \
      78                 :       (buf)[0] = hexnums[((b) >> 4) & 0xf];     \
      79                 :     } while (FALSE)
      80                 : 
      81                 : # define EX_HEXDUMP_UINT(buf, i) do {           \
      82                 :       EX_HEXDUMP_BYTE((buf) + 6, (i) >>  0);    \
      83                 :       EX_HEXDUMP_BYTE((buf) + 4, (i) >>  8);    \
      84                 :       EX_HEXDUMP_BYTE((buf) + 2, (i) >> 16);    \
      85                 :       EX_HEXDUMP_BYTE((buf) + 0, (i) >> 24);    \
      86                 :     } while (FALSE)
      87                 : 
      88                 : /* print the address */
      89                 : # define EX_HEXDUMP_X8(s1, num) do {                                    \
      90                 :       unsigned char xbuf[9];                                            \
      91                 :                                                                         \
      92                 :       xbuf[8] = ':';                                                    \
      93                 :       EX_HEXDUMP_UINT(xbuf, num);                                       \
      94                 :       vstr_add_buf(s1, APOS(), xbuf, sizeof(xbuf));                     \
      95                 :     } while (FALSE)
      96                 : /* print a set of two bytes */
      97                 : # define EX_HEXDUMP_X2X2(s1, num1, num2) do {                        \
      98                 :       unsigned char xbuf[5];                                         \
      99                 :                                                                      \
     100                 :       xbuf[0] = ' ';                                                 \
     101                 :       EX_HEXDUMP_BYTE(xbuf + 3, num2);                               \
     102                 :       EX_HEXDUMP_BYTE(xbuf + 1, num1);                               \
     103                 :       vstr_add_buf(s1, APOS(), xbuf, sizeof(xbuf));                  \
     104                 :     } while (FALSE)
     105                 : /* print a byte and spaces for the missing byte */
     106                 : # define EX_HEXDUMP_X2__(s1, num1) do {                                 \
     107                 :       unsigned char xbuf[5];                                            \
     108                 :                                                                         \
     109                 :       xbuf[4] = ' ';                                                    \
     110                 :       xbuf[3] = ' ';                                                    \
     111                 :       EX_HEXDUMP_BYTE(xbuf + 1, num1);                                  \
     112                 :       xbuf[0] = ' ';                                                    \
     113                 :       vstr_add_buf(s1, APOS(), xbuf, sizeof(xbuf));                     \
     114                 :     } while (FALSE)
     115                 : #endif
     116                 : 
     117                 : static unsigned int addr = 0;
     118                 : 
     119                 : void ex_hexdump_reset(void)
     120             128 : {
     121             128 :   addr = 0;
     122             128 : }
     123                 : 
     124                 : int ex_hexdump_process(Vstr_base *s1, size_t apos,
     125                 :                        Vstr_base *s2, size_t fpos, size_t flen,
     126                 :                        unsigned int prnt_type, size_t max_sz, int del, int last)
     127             128 : {
     128             128 :   size_t orig_len = s1->len;
     129                 :   /* normal ASCII chars, just allow COMMA and DOT flags */
     130             128 :   unsigned int flags = VSTR_FLAG02(CONV_UNPRINTABLE_ALLOW, COMMA, DOT);
     131                 :   /* allow spaces, allow COMMA, DOT, underbar _, and space */
     132             128 :   unsigned int flags_sp = VSTR_FLAG04(CONV_UNPRINTABLE_ALLOW,
     133                 :                                       COMMA, DOT, _, SP);
     134                 :   /* high ascii too, allow
     135                 :    * COMMA, DOT, underbar _, space, high space and other high characters */
     136             128 :   unsigned int flags_hsp = VSTR_FLAG06(CONV_UNPRINTABLE_ALLOW,
     137                 :                                        COMMA, DOT, _, SP, HSP, HIGH);
     138                 :   unsigned char buf[CHRS_PER_LINE];
     139                 : 
     140             128 :   switch (prnt_type)
     141                 :   {
     142               0 :     case PRNT_HIGH: flags = flags_hsp; break;
     143               0 :     case PRNT_SPAC: flags = flags_sp;  break;
     144                 :     case PRNT_NONE:                    break;
     145               0 :     default: ASSERT(FALSE);            break;
     146                 :   }
     147                 : 
     148                 :   /* we don't want to create more data, if we are over our limit */
     149             128 :   if (s1->len > max_sz)
     150               0 :     return (FALSE);
     151                 : 
     152                 :   /* while we have a hexdump line ... */
     153             848 :   while (flen >= CHRS_PER_LINE)
     154                 :   {
     155             592 :     unsigned int count = 0;
     156             592 :     size_t tmp = 0;
     157                 :     
     158                 :     /* get a hexdump line from the vstr */
     159             592 :     vstr_export_buf(s2, fpos, CHRS_PER_LINE, buf, sizeof(buf));
     160                 : 
     161                 :     /* write out a hexdump line address */
     162             592 :     EX_HEXDUMP_X8(s1, addr);
     163                 : 
     164                 :     /* write out hex values */
     165            5920 :     while (count < CHRS_PER_LINE)
     166                 :     {
     167            4736 :       EX_HEXDUMP_X2X2(s1, buf[count], buf[count + 1]);
     168            4736 :       count += 2;
     169                 :     }
     170                 : 
     171             592 :     vstr_add_rep_chr(s1, APOS(), ' ', 2);
     172                 : 
     173                 :     /* write out characters, converting reference and pointer nodes to
     174                 :      * _BUF nodes */
     175             592 :     tmp = APOS();
     176             592 :     if (vstr_add_vstr(s1, tmp, s2, fpos, CHRS_PER_LINE,
     177                 :                       VSTR_TYPE_ADD_ALL_BUF))
     178                 :       /* convert unprintable characters to the '.' character */
     179             592 :       vstr_conv_unprintable_chr(s1, tmp + 1, CHRS_PER_LINE, flags, '.');
     180                 : 
     181             592 :     vstr_add_rep_chr(s1, APOS(), '\n', 1);
     182                 : 
     183             592 :     addr += CHRS_PER_LINE;
     184                 :     
     185             592 :     flen -= CHRS_PER_LINE;
     186             592 :     if (del) /* delete the set of characters just processed */
     187               0 :       vstr_del(s2, fpos, CHRS_PER_LINE);
     188                 :     else
     189             592 :       fpos += CHRS_PER_LINE;
     190                 : 
     191                 :     /* note that we don't want to create data indefinitely, so stop
     192                 :      * according to in core configuration */
     193             592 :     if (s1->len > max_sz)
     194               0 :       return (TRUE);
     195                 :   }
     196                 : 
     197             128 :   if (last && flen)
     198                 :   { /* do the same as above, but print the partial line for
     199                 :      * the end of a file */
     200             120 :     size_t got = flen;
     201             120 :     size_t missing = CHRS_PER_LINE - flen;
     202             120 :     const unsigned char *ptr = buf;
     203             120 :     size_t tmp = 0;
     204                 :     
     205             120 :     missing -= (missing % 2);
     206             120 :     vstr_export_buf(s2, fpos, flen, buf, sizeof(buf));
     207                 : 
     208             120 :     EX_HEXDUMP_X8(s1, addr);
     209                 : 
     210             592 :     while (got >= 2)
     211                 :     {
     212             352 :       EX_HEXDUMP_X2X2(s1, ptr[0], ptr[1]);
     213             352 :       got -= 2;
     214             352 :       ptr += 2;
     215                 :     }
     216             120 :     if (got)
     217                 :     {
     218              48 :       EX_HEXDUMP_X2__(s1, ptr[0]);
     219              48 :       got -= 2;
     220                 :     }
     221                 : 
     222                 :     /* Add spaces until the point where the characters should start */
     223             120 :     vstr_add_rep_chr(s1, APOS(), ' ', (missing * 2) + (missing / 2) + 2);
     224                 : 
     225             120 :     tmp = APOS();
     226             120 :     if (vstr_add_vstr(s1, tmp, s2, fpos, flen, VSTR_TYPE_ADD_ALL_BUF))
     227             120 :       vstr_conv_unprintable_chr(s1, tmp + 1, flen, flags, '.');
     228                 : 
     229             120 :     vstr_add_cstr_buf(s1, APOS(), "\n");
     230                 : 
     231             120 :     addr += flen;
     232             120 :     if (del)
     233               0 :       vstr_del(s2, fpos, flen);
     234                 : 
     235             120 :     return (TRUE);
     236                 :   }
     237                 : 
     238               8 :   return (FALSE);
     239                 : }

Generated by: LTP GCOV extension version 1.4