~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to strings/int2str.c

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2000 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
#include <my_global.h>
 
17
#include "m_string.h"
 
18
 
 
19
/*
 
20
  _dig_vec arrays are public because they are used in several outer places.
 
21
*/
 
22
char _dig_vec_upper[] =
 
23
  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
24
char _dig_vec_lower[] =
 
25
  "0123456789abcdefghijklmnopqrstuvwxyz";
 
26
 
 
27
 
 
28
/*
 
29
  Convert integer to its string representation in given scale of notation.
 
30
   
 
31
  SYNOPSIS
 
32
    int2str()
 
33
      val     - value to convert
 
34
      dst     - points to buffer where string representation should be stored
 
35
      radix   - radix of scale of notation
 
36
      upcase  - set to 1 if we should use upper-case digits
 
37
 
 
38
  DESCRIPTION
 
39
    Converts the (long) integer value to its character form and moves it to 
 
40
    the destination buffer followed by a terminating NUL. 
 
41
    If radix is -2..-36, val is taken to be SIGNED, if radix is  2..36, val is
 
42
    taken to be UNSIGNED. That is, val is signed if and only if radix is. 
 
43
    All other radixes treated as bad and nothing will be changed in this case.
 
44
 
 
45
    For conversion to decimal representation (radix is -10 or 10) one can use
 
46
    optimized int10_to_str() function.
 
47
 
 
48
  RETURN VALUE
 
49
    Pointer to ending NUL character or NullS if radix is bad.
 
50
*/
 
51
  
 
52
char *
 
53
int2str(register long int val, register char *dst, register int radix, 
 
54
        int upcase)
 
55
{
 
56
  char buffer[65];
 
57
  register char *p;
 
58
  long int new_val;
 
59
  char *dig_vec= upcase ? _dig_vec_upper : _dig_vec_lower;
 
60
  ulong uval= (ulong) val;
 
61
 
 
62
  if (radix < 0)
 
63
  {
 
64
    if (radix < -36 || radix > -2)
 
65
      return NullS;
 
66
    if (val < 0)
 
67
    {
 
68
      *dst++ = '-';
 
69
      /* Avoid integer overflow in (-val) for LONGLONG_MIN (BUG#31799). */
 
70
      uval = (ulong)0 - uval;
 
71
    }
 
72
    radix = -radix;
 
73
  }
 
74
  else if (radix > 36 || radix < 2)
 
75
    return NullS;
 
76
 
 
77
  /*
 
78
    The slightly contorted code which follows is due to the fact that
 
79
    few machines directly support unsigned long / and %.  Certainly
 
80
    the VAX C compiler generates a subroutine call.  In the interests
 
81
    of efficiency (hollow laugh) I let this happen for the first digit
 
82
    only; after that "val" will be in range so that signed integer
 
83
    division will do.  Sorry 'bout that.  CHECK THE CODE PRODUCED BY
 
84
    YOUR C COMPILER.  The first % and / should be unsigned, the second
 
85
    % and / signed, but C compilers tend to be extraordinarily
 
86
    sensitive to minor details of style.  This works on a VAX, that's
 
87
    all I claim for it.
 
88
  */
 
89
  p = &buffer[sizeof(buffer)-1];
 
90
  *p = '\0';
 
91
  new_val= uval / (ulong) radix;
 
92
  *--p = dig_vec[(uchar) (uval- (ulong) new_val*(ulong) radix)];
 
93
  val = new_val;
 
94
#ifdef HAVE_LDIV
 
95
  while (val != 0)
 
96
  {
 
97
    ldiv_t res;
 
98
    res=ldiv(val,radix);
 
99
    *--p = dig_vec[res.rem];
 
100
    val= res.quot;
 
101
  }
 
102
#else
 
103
  while (val != 0)
 
104
  {
 
105
    new_val=val/radix;
 
106
    *--p = dig_vec[(uchar) (val-new_val*radix)];
 
107
    val= new_val;
 
108
  }
 
109
#endif
 
110
  while ((*dst++ = *p++) != 0) ;
 
111
  return dst-1;
 
112
}
 
113
 
 
114
 
 
115
/*
 
116
  Converts integer to its string representation in decimal notation.
 
117
   
 
118
  SYNOPSIS
 
119
    int10_to_str()
 
120
      val     - value to convert
 
121
      dst     - points to buffer where string representation should be stored
 
122
      radix   - flag that shows whenever val should be taken as signed or not
 
123
 
 
124
  DESCRIPTION
 
125
    This is version of int2str() function which is optimized for normal case
 
126
    of radix 10/-10. It takes only sign of radix parameter into account and 
 
127
    not its absolute value.
 
128
 
 
129
  RETURN VALUE
 
130
    Pointer to ending NUL character.
 
131
*/
 
132
 
 
133
char *int10_to_str(long int val,char *dst,int radix)
 
134
{
 
135
  char buffer[65];
 
136
  register char *p;
 
137
  long int new_val;
 
138
  unsigned long int uval = (unsigned long int) val;
 
139
 
 
140
  if (radix < 0)                                /* -10 */
 
141
  {
 
142
    if (val < 0)
 
143
    {
 
144
      *dst++ = '-';
 
145
      /* Avoid integer overflow in (-val) for LONGLONG_MIN (BUG#31799). */
 
146
      uval = (unsigned long int)0 - uval;
 
147
    }
 
148
  }
 
149
 
 
150
  p = &buffer[sizeof(buffer)-1];
 
151
  *p = '\0';
 
152
  new_val= (long) (uval / 10);
 
153
  *--p = '0'+ (char) (uval - (unsigned long) new_val * 10);
 
154
  val = new_val;
 
155
 
 
156
  while (val != 0)
 
157
  {
 
158
    new_val=val/10;
 
159
    *--p = '0' + (char) (val-new_val*10);
 
160
    val= new_val;
 
161
  }
 
162
  while ((*dst++ = *p++) != 0) ;
 
163
  return dst-1;
 
164
}