Fixed many warnings
[pspp] / src / data / spreadsheet-reader.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2007, 2009, 2010, 2011, 2013 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18
19 #include "spreadsheet-reader.h"
20
21 #include "gnumeric-reader.h"
22
23 #include <libpspp/str.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <gl/xalloc.h>
27 #include <gl/c-xvasprintf.h>
28 #include <stdlib.h>
29
30 struct spreadsheet * 
31 spreadsheet_open (const char *filename)
32 {
33   struct spreadsheet *ss = NULL;
34
35   ss = gnumeric_probe (filename);
36   
37   return ss;
38 }
39
40 void 
41 spreadsheet_close (UNUSED struct spreadsheet *spreadsheet)
42 {
43 }
44
45 #define RADIX 26
46
47 static void
48 reverse (char *s, int len)
49 {
50   int i;
51   for (i = 0; i < len / 2; ++i)
52     {
53       char tmp = s[len - i - 1];
54       s[len - i -1] = s[i];
55       s[i] = tmp;
56     }
57 }
58
59
60 /* Convert a string, which is an integer encoded in base26
61    IE, A=0, B=1, ... Z=25 to the integer it represents.
62    ... except that in this scheme, digits with an exponent
63    greater than 1 are implicitly incremented by 1, so
64    AA  = 0 + 1*26, AB = 1 + 1*26,
65    ABC = 2 + 2*26 + 1*26^2 ....
66 */
67 int
68 ps26_to_int (const char *str)
69 {
70   int i;
71   int multiplier = 1;
72   int result = 0;
73   int len = strlen (str);
74
75   for (i = len - 1 ; i >= 0; --i)
76     {
77       int mantissa = (str[i] - 'A');
78
79       assert (mantissa >= 0);
80       assert (mantissa < RADIX);
81
82       if (i != len - 1)
83         mantissa++;
84
85       result += mantissa * multiplier;
86       multiplier *= RADIX;
87     }
88
89   return result;
90 }
91
92 char *
93 int_to_ps26 (int i)
94 {
95   char *ret = NULL;
96
97   int lower = 0;
98   long long int base = RADIX;
99   int exp = 1;
100
101   assert (i >= 0);
102
103   while (i > lower + base - 1)
104     {
105       lower += base;
106       base *= RADIX;      
107       assert (base > 0);
108       exp++;
109     }
110
111   i -= lower;
112   i += base;
113
114   ret = xmalloc (exp);
115
116   exp = 0;
117   do
118     {
119       ret[exp++] = (i % RADIX) + 'A';
120       i /= RADIX;
121     }
122   while (i > 1);
123
124   ret[exp]='\0';
125
126   reverse (ret, exp);
127   return ret;
128 }
129
130 char *
131 create_cell_ref (int col0, int row0, int coli, int rowi)
132 {
133   char *cs0 ;
134   char *csi ;
135   char *s ;
136
137   if ( col0 < 0) return NULL;
138   if ( rowi < 0) return NULL;
139   if ( coli < 0) return NULL;
140   if ( row0 < 0) return NULL;
141
142   cs0 =  int_to_ps26 (col0);
143   csi =  int_to_ps26 (coli);
144   s =  c_xasprintf ("%s%d:%s%d",
145                          cs0, row0 + 1,
146                          csi, rowi + 1);
147   free (cs0);
148   free (csi);
149
150   return s;
151 }
152
153
154 /* Convert a cell reference in the form "A1:B2", to
155    integers.  A1 means column zero, row zero.
156    B1 means column 1 row 0. AA1 means column 26, row 0.
157 */
158 bool
159 convert_cell_ref (const char *ref,
160                   int *col0, int *row0,
161                   int *coli, int *rowi)
162 {
163   char startcol[5];
164   char stopcol [5];
165
166   int startrow;
167   int stoprow;
168
169   int n = sscanf (ref, "%4[a-zA-Z]%d:%4[a-zA-Z]%d",
170               startcol, &startrow,
171               stopcol, &stoprow);
172   if ( n != 4)
173     return false;
174
175   str_uppercase (startcol);
176   *col0 = ps26_to_int (startcol);
177   str_uppercase (stopcol);
178   *coli = ps26_to_int (stopcol);
179   *row0 = startrow - 1;
180   *rowi = stoprow - 1 ;
181
182   return true;
183 }
184