[core] getmemory('') error refered to funcprot
[scilab.git] / scilab / modules / elementary_functions / src / c / convertbase.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2011 - DIGITEO - Allan CORNET
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15 /*--------------------------------------------------------------------------*/
16 #include <string.h>
17 #include <math.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include "machine.h" /* bsiz */
21 #include "convertbase.h"
22 #include "sci_malloc.h"
23 #include "freeArrayOfString.h"
24 /*--------------------------------------------------------------------------*/
25 #define char_a 'a'
26 #define char_A 'A'
27 #define char_z 'z'
28 #define char_Z 'Z'
29 #define char_zero '0'
30 #define char_nine '9'
31 /*--------------------------------------------------------------------------*/
32 static char *convertDec2Base(double dValue, int numberbase,
33                              unsigned int nbDigits, error_convertbase *err);
34 /*--------------------------------------------------------------------------*/
35 double convertBase2Dec(const char *pStr, int numberbase, error_convertbase *err)
36 {
37     double result = 0.;
38     *err = ERROR_CONVERTBASE_NOK;
39
40     if (pStr)
41     {
42         size_t i = 0;
43         size_t len = strlen(pStr);
44         for (i = 0; i < len; i++)
45         {
46             if ((pStr[i] >= char_zero) && (pStr[i] <= char_nine))
47             {
48                 result = (numberbase * result) + (int)pStr[i] - char_zero;
49             }
50             else if ((pStr[i] >= char_A) && (pStr[i] <= char_Z))
51             {
52                 int vTmp = (int)pStr[i] - char_A + 10;
53                 if (vTmp > numberbase)
54                 {
55                     *err = ERROR_CONVERTBASE_INVALID_REPRESENTATION;
56                     return 0;
57                 }
58                 else
59                 {
60                     result = (numberbase * result) + vTmp;
61                 }
62             }
63             else if ((pStr[i] >= char_a) && (pStr[i] <= char_z))
64             {
65                 int vTmp = (int)pStr[i] - char_a + 10;
66                 if ( vTmp > numberbase)
67                 {
68                     *err = ERROR_CONVERTBASE_INVALID_REPRESENTATION;
69                     return 0;
70                 }
71                 else
72                 {
73                     result = (numberbase * result) + vTmp;
74                 }
75             }
76             else
77             {
78                 return 0;
79             }
80         }
81         *err = ERROR_CONVERTBASE_OK;
82     }
83     return result;
84 }
85 /*--------------------------------------------------------------------------*/
86 static char *convertDec2Base(double dValue, int numberbase,
87                              unsigned int nbDigits, error_convertbase *err)
88 {
89     char symbols[37] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
90     long long int iDec = (long long int) dValue;
91     char *convertedValue = NULL;
92
93     *err = ERROR_CONVERTBASE_NOK;
94     if (iDec == 0)
95     {
96         convertedValue = (char*)MALLOC(sizeof(char) * 2);
97         if (convertedValue)
98         {
99             strcpy(convertedValue, "0");
100             *err = ERROR_CONVERTBASE_OK;
101         }
102         else
103         {
104             *err = ERROR_CONVERTBASE_ALLOCATION;
105             return NULL;
106         }
107     }
108     else
109     {
110         int count = 0;
111         char chResult[bsiz] = "";
112         char *pChResult = chResult;
113         while (iDec > 0 && count++ < bsiz)
114         {
115             *pChResult = symbols[iDec % numberbase];
116             pChResult++;
117             iDec = iDec / numberbase;
118         }
119
120         convertedValue = (char*)MALLOC(sizeof(char) * (strlen(chResult) + 1));
121         if (convertedValue)
122         {
123             size_t j = 0;
124             size_t i = strlen(chResult);
125             int t = !(i % 2) ? 1 : 0;
126             int k = 0;
127             strcpy(convertedValue, chResult);
128             for (j = i - 1; j > (i / 2 - t); j--)
129             {
130                 char ch  = chResult[j];
131                 chResult[j] = chResult[k];
132                 chResult[k++] = ch;
133             }
134             strcpy(convertedValue, chResult);
135             *err = ERROR_CONVERTBASE_OK;
136         }
137         else
138         {
139             *err = ERROR_CONVERTBASE_ALLOCATION;
140             return NULL;
141         }
142     }
143
144     if (*err == ERROR_CONVERTBASE_OK)
145     {
146         size_t lenConvertedValue = strlen(convertedValue);
147         if ((nbDigits > lenConvertedValue) && (nbDigits > 0))
148         {
149             size_t i = 0;
150             char *tmp = (char*)MALLOC(sizeof(char) * (nbDigits + 1));
151             if (tmp)
152             {
153                 for (i = 0; i < nbDigits - lenConvertedValue; i++)
154                 {
155                     tmp[i] = '0';
156                 }
157                 tmp[i] = 0;
158                 strcat(tmp, convertedValue);
159                 FREE(convertedValue);
160                 convertedValue = tmp;
161             }
162         }
163     }
164
165     return convertedValue;
166 }
167 /*--------------------------------------------------------------------------*/
168 char **convertMatrixOfDec2Base(const double* dValues, int mn,
169                                int numberbase, unsigned int nbDigits,
170                                error_convertbase *err)
171 {
172     char **convertedValues = NULL;
173     int i = 0;
174     double maxVal = 0.;
175
176     for (i = 0; i < mn; i++)
177     {
178         long long int iValue = (long long int) dValues[i];
179
180         /* search max value */
181         if (dValues[i] > maxVal)
182         {
183             maxVal = dValues[i];
184         }
185
186         /* check if it is an integer value */
187         if (dValues[i] != (double)iValue)
188         {
189             *err = ERROR_CONVERTBASE_NOT_INTEGER_VALUE;
190             return NULL;
191         }
192
193         /* check if it is in the good interval */
194         if ((dValues[i] < 0) || (dValues[i] > pow(2, 52)))
195         {
196             *err = ERROR_CONVERTBASE_NOT_IN_INTERVAL;
197             return NULL;
198         }
199     }
200
201     if ((mn > 1) && (numberbase == 2)) /* Only binary base is uniformed about number of digits */
202     {
203         size_t maxDigits = 0;
204         char *maxBaseString = convertDec2Base(maxVal, numberbase, nbDigits, err);
205         if (maxBaseString)
206         {
207             maxDigits = strlen(maxBaseString);
208             FREE(maxBaseString);
209             if (maxDigits > nbDigits)
210             {
211                 nbDigits = (unsigned int)maxDigits;
212             }
213         }
214     }
215
216     convertedValues = (char **)MALLOC(sizeof(char*) * (mn));
217     if (convertedValues)
218     {
219         for (i = 0; i < mn; i++)
220         {
221             convertedValues[i] = convertDec2Base(dValues[i], numberbase, nbDigits, err);
222             if (*err)
223             {
224                 freeArrayOfString(convertedValues, mn);
225                 return NULL;
226             }
227         }
228     }
229     else
230     {
231         *err = ERROR_CONVERTBASE_ALLOCATION;
232     }
233     return convertedValues;
234 }
235 /*--------------------------------------------------------------------------*/