LCOV - code coverage report
Current view: top level - bash-4.4.23/lib/sh - fmtulong.c (source / functions) Hit Total Coverage
Test: cov-bash.info Lines: 23 58 39.7 %
Date: 2020-10-29 14:49:28 Functions: 1 2 50.0 %

          Line data    Source code
       1             : /* fmtulong.c -- Convert unsigned long int to string. */
       2             : 
       3             : /* Copyright (C) 1998-2011 Free Software Foundation, Inc.
       4             : 
       5             :    This file is part of GNU Bash, the Bourne Again SHell.
       6             : 
       7             :    Bash is free software: you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation, either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    Bash is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #ifdef HAVE_CONFIG_H
      22             : #  include <config.h>
      23             : #endif
      24             : 
      25             : #if defined (HAVE_UNISTD_H)
      26             : #  include <unistd.h>
      27             : #endif
      28             : 
      29             : #if defined (HAVE_LIMITS_H)
      30             : #  include <limits.h>
      31             : #endif
      32             : 
      33             : #include <bashansi.h>
      34             : #ifdef HAVE_STDDEF_H
      35             : #  include <stddef.h>
      36             : #endif
      37             : 
      38             : #ifdef HAVE_STDINT_H
      39             : #  include <stdint.h>
      40             : #endif
      41             : #ifdef HAVE_INTTYPES_H
      42             : #  include <inttypes.h>
      43             : #endif
      44             : #include <chartypes.h>
      45             : #include <errno.h>
      46             : 
      47             : #include <bashintl.h>
      48             : 
      49             : #include "stdc.h"
      50             : 
      51             : #include <typemax.h>
      52             : 
      53             : #ifndef errno
      54             : extern int errno;
      55             : #endif
      56             : 
      57             : #define x_digs  "0123456789abcdef"
      58             : #define X_digs  "0123456789ABCDEF"
      59             : 
      60             : /* XXX -- assumes uppercase letters, lowercase letters, and digits are
      61             :    contiguous */
      62             : #define FMTCHAR(x) \
      63             :   ((x) < 10) ? (x) + '0' \
      64             :              : (((x) < 36) ? (x) - 10 + 'a' \
      65             :                            : (((x) < 62) ? (x) - 36 + 'A' \
      66             :                                          : (((x) == 62) ? '@' : '_')))
      67             : 
      68             : #ifndef FL_PREFIX
      69             : #  define FL_PREFIX     0x01    /* add 0x, 0X, or 0 prefix as appropriate */
      70             : #  define FL_ADDBASE    0x02    /* add base# prefix to converted value */
      71             : #  define FL_HEXUPPER   0x04    /* use uppercase when converting to hex */
      72             : #  define FL_UNSIGNED   0x08    /* don't add any sign */
      73             : #endif
      74             : 
      75             : #ifndef LONG
      76             : #  define LONG  long
      77             : #  define UNSIGNED_LONG unsigned long
      78             : #endif
      79             : 
      80             : /* `unsigned long' (or unsigned long long) to string conversion for a given
      81             :    base.  The caller passes the output buffer and the size.  This should
      82             :    check for buffer underflow, but currently does not. */
      83             : char *
      84   128171030 : fmtulong (ui, base, buf, len, flags)
      85             :      UNSIGNED_LONG ui;
      86             :      int base;
      87             :      char *buf;
      88             :      size_t len;
      89             :      int flags;
      90             : {
      91   128171030 :   char *p;
      92   128171030 :   int sign;
      93   128171030 :   LONG si;
      94             : 
      95   128171030 :   if (base == 0)
      96           0 :     base = 10;
      97             : 
      98   128171030 :   if (base < 2 || base > 64)
      99             :     {
     100             : #if 1
     101             :       /* XXX - truncation possible with long translation */
     102           0 :       strncpy (buf, _("invalid base"), len - 1);
     103           0 :       buf[len-1] = '\0';
     104           0 :       errno = EINVAL;
     105           0 :       return (p = buf);
     106             : #else
     107             :       base = 10;
     108             : #endif
     109             :     }
     110             : 
     111   128171030 :   sign = 0;
     112   128171030 :   if ((flags & FL_UNSIGNED) == 0 && (LONG)ui < 0)
     113             :     {
     114           0 :       ui = -ui;
     115           0 :       sign = '-';
     116             :     }
     117             : 
     118   128171030 :   p = buf + len - 2;
     119   128171030 :   p[1] = '\0';
     120             : 
     121             :   /* handle common cases explicitly */
     122   128171030 :   switch (base)
     123             :     {
     124   128171030 :     case 10:
     125   128171030 :       if (ui < 10)
     126             :         {
     127    95271150 :           *p-- = TOCHAR (ui);
     128    95271150 :           break;
     129             :         }
     130             :       /* Favor signed arithmetic over unsigned arithmetic; it is faster on
     131             :          many machines. */
     132    32899880 :       if ((LONG)ui < 0)
     133             :         {
     134           0 :           *p-- = TOCHAR (ui % 10);
     135           0 :           si = ui / 10;
     136             :         }
     137             :       else
     138             :         si = ui;
     139   126127833 :       do
     140   126127833 :         *p-- = TOCHAR (si % 10);
     141   126127833 :       while (si /= 10);
     142             :       break;
     143             : 
     144           0 :     case 8:
     145           0 :       do
     146           0 :         *p-- = TOCHAR (ui & 7);
     147           0 :       while (ui >>= 3);
     148             :       break;
     149             : 
     150           0 :     case 16:
     151           0 :       do
     152           0 :         *p-- = (flags & FL_HEXUPPER) ? X_digs[ui & 15] : x_digs[ui & 15];
     153           0 :       while (ui >>= 4);
     154             :       break;
     155             : 
     156           0 :     case 2:
     157           0 :       do
     158           0 :         *p-- = TOCHAR (ui & 1);
     159           0 :       while (ui >>= 1);
     160             :       break;
     161             : 
     162           0 :     default:
     163           0 :       do
     164           0 :         *p-- = FMTCHAR (ui % base);
     165           0 :       while (ui /= base);
     166             :       break;
     167             :     }
     168             : 
     169   128171030 :   if ((flags & FL_PREFIX) && (base == 8 || base == 16))
     170             :     {
     171           0 :       if (base == 16)
     172             :         {
     173           0 :           *p-- = (flags & FL_HEXUPPER) ? 'X' : 'x';
     174           0 :           *p-- = '0';
     175             :         }
     176           0 :       else if (p[1] != '0')
     177           0 :         *p-- = '0';
     178             :     }
     179   128171030 :   else if ((flags & FL_ADDBASE) && base != 10)
     180             :     {
     181           0 :       *p-- = '#';
     182           0 :       *p-- = TOCHAR (base % 10);
     183           0 :       if (base > 10)
     184           0 :         *p-- = TOCHAR (base / 10);
     185             :     }
     186             : 
     187   128171030 :   if (sign)
     188           0 :     *p-- = '-';
     189             : 
     190   128171030 :   return (p + 1);
     191             : }

Generated by: LCOV version 1.14.0.6.4058