~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mystrings/int2str.c

Moved sql_common.h and my_time.h to libdrizzle.

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 "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
48
 
    Pointer to ending NUL character or (char *)0 if radix is bad.
49
 
*/
50
 
  
51
 
char *
52
 
int2str(register int32_t 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;
59
 
  unsigned long uval= (unsigned long) val;
60
 
 
61
 
  if (radix < 0)
62
 
  {
63
 
    if (radix < -36 || radix > -2)
64
 
      return (char *)0;
65
 
    if (val < 0)
66
 
    {
67
 
      *dst++ = '-';
68
 
      /* Avoid integer overflow in (-val) for LONGLONG_MIN (BUG#31799). */
69
 
      uval = (unsigned long)0 - uval;
70
 
    }
71
 
    radix = -radix;
72
 
  }
73
 
  else if (radix > 36 || radix < 2)
74
 
    return (char *)0;
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';
90
 
  new_val= uval / (unsigned long) radix;
91
 
  *--p = dig_vec[(unsigned char) (uval- (unsigned long) new_val*(unsigned long) radix)];
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;
105
 
    *--p = dig_vec[(unsigned char) (val-new_val*radix)];
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(int32_t val,char *dst,int radix)
133
 
{
134
 
  char buffer[65];
135
 
  register char *p;
136
 
  int32_t new_val;
137
 
  uint32_t uval = (uint32_t) val;
138
 
 
139
 
  if (radix < 0)                                /* -10 */
140
 
  {
141
 
    if (val < 0)
142
 
    {
143
 
      *dst++ = '-';
144
 
      /* Avoid integer overflow in (-val) for INT32_MIN (BUG#31799). */
145
 
      uval = (uint32_t)0 - uval;
146
 
    }
147
 
  }
148
 
 
149
 
  p = &buffer[sizeof(buffer)-1];
150
 
  *p = '\0';
151
 
  new_val= (int32_t) (uval / 10);
152
 
  *--p = '0'+ (char) (uval - (uint32_t) 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
 
}