Use the gnumeric_reopen function
[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 <libpspp/str.h>
22 #include <stdio.h>
23 #include <string.h>
24
25
26 struct spreadsheet * 
27 spreadsheet_open (const char *filename)
28 {
29   struct spreadsheet *ss = NULL;
30
31   ss = gnumeric_probe (filename);
32   
33   return ss;
34 }
35
36 void 
37 spreadsheet_close (struct spreadsheet *spreadsheet)
38 {
39 }
40
41 #define RADIX 26
42
43 static void
44 reverse (char *s, int len)
45 {
46   int i;
47   for (i = 0; i < len / 2; ++i)
48     {
49       char tmp = s[len - i - 1];
50       s[len - i -1] = s[i];
51       s[i] = tmp;
52     }
53 }
54
55
56 /* Convert a string, which is an integer encoded in base26
57    IE, A=0, B=1, ... Z=25 to the integer it represents.
58    ... except that in this scheme, digits with an exponent
59    greater than 1 are implicitly incremented by 1, so
60    AA  = 0 + 1*26, AB = 1 + 1*26,
61    ABC = 2 + 2*26 + 1*26^2 ....
62 */
63 int
64 ps26_to_int (const char *str)
65 {
66   int i;
67   int multiplier = 1;
68   int result = 0;
69   int len = strlen (str);
70
71   for (i = len - 1 ; i >= 0; --i)
72     {
73       int mantissa = (str[i] - 'A');
74
75       assert (mantissa >= 0);
76       assert (mantissa < RADIX);
77
78       if (i != len - 1)
79         mantissa++;
80
81       result += mantissa * multiplier;
82       multiplier *= RADIX;
83     }
84
85   return result;
86 }
87
88 char *
89 int_to_ps26 (int i)
90 {
91   char *ret = NULL;
92
93   int lower = 0;
94   long long int base = RADIX;
95   int exp = 1;
96
97   assert (i >= 0);
98
99   while (i > lower + base - 1)
100     {
101       lower += base;
102       base *= RADIX;      
103       assert (base > 0);
104       exp++;
105     }
106
107   i -= lower;
108   i += base;
109
110   ret = malloc (exp);
111
112   exp = 0;
113   do
114     {
115       ret[exp++] = (i % RADIX) + 'A';
116       i /= RADIX;
117     }
118   while (i > 1);
119
120   ret[exp]='\0';
121
122   reverse (ret, exp);
123   return ret;
124 }
125
126 char *
127 create_cell_ref (int col0, int row0, int coli, int rowi)
128 {
129   char *cs0 ;
130   char *csi ;
131   char *s ;
132
133   if ( col0 < 0) return NULL;
134   if ( rowi < 0) return NULL;
135   if ( coli < 0) return NULL;
136   if ( row0 < 0) return NULL;
137
138   cs0 =  int_to_ps26 (col0);
139   csi =  int_to_ps26 (coli);
140   s =  c_xasprintf ("%s%d:%s%ld",
141                          cs0, row0 + 1,
142                          csi, rowi + 1);
143   free (cs0);
144   free (csi);
145
146   return s;
147 }
148
149
150 /* Convert a cell reference in the form "A1:B2", to
151    integers.  A1 means column zero, row zero.
152    B1 means column 1 row 0. AA1 means column 26, row 0.
153 */
154 bool
155 convert_cell_ref (const char *ref,
156                   int *col0, int *row0,
157                   int *coli, int *rowi)
158 {
159   char startcol[5];
160   char stopcol [5];
161
162   int startrow;
163   int stoprow;
164
165   int n = sscanf (ref, "%4[a-zA-Z]%d:%4[a-zA-Z]%d",
166               startcol, &startrow,
167               stopcol, &stoprow);
168   if ( n != 4)
169     return false;
170
171   str_uppercase (startcol);
172   *col0 = ps26_to_int (startcol);
173   str_uppercase (stopcol);
174   *coli = ps26_to_int (stopcol);
175   *row0 = startrow - 1;
176   *rowi = stoprow - 1 ;
177
178   return true;
179 }
180