~drizzle-trunk/drizzle/development

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