X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fspreadsheet-reader.c;h=a16b430a52367fd9a670516f04b8eb0e4457e9e0;hb=ff47c7eb6e8335ef6042e3a437f3d30ef27600a7;hp=3572a03ce49bdac5e27fc320d3afa980dba89601;hpb=7f8a1592964567db640915d3019af0e25e30bbb6;p=pspp diff --git a/src/data/spreadsheet-reader.c b/src/data/spreadsheet-reader.c index 3572a03ce4..a16b430a52 100644 --- a/src/data/spreadsheet-reader.c +++ b/src/data/spreadsheet-reader.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2007, 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 2007, 2009, 2010, 2011, 2013, 2020 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,27 +18,91 @@ #include "spreadsheet-reader.h" +#include +#include "gnumeric-reader.h" +#include "ods-reader.h" + #include #include #include +#include +#include +#include + +struct spreadsheet * +spreadsheet_ref (struct spreadsheet *s) +{ + s->ref_cnt++; + return s; +} + +void +spreadsheet_unref (struct spreadsheet *s) +{ + if (--s->ref_cnt == 0) + s->destroy (s); +} + + +struct casereader * +spreadsheet_make_reader (struct spreadsheet *s, + const struct spreadsheet_read_options *opts) +{ + return s->make_reader (s, opts); +} + +const char * +spreadsheet_get_sheet_name (struct spreadsheet *s, int n) +{ + return s->get_sheet_name (s, n); +} + + +char * +spreadsheet_get_sheet_range (struct spreadsheet *s, int n) +{ + return s->get_sheet_range (s, n); +} +int +spreadsheet_get_sheet_n_sheets (struct spreadsheet *s) +{ + return s->get_sheet_n_sheets (s); +} -struct spreadsheet * -spreadsheet_open (const char *filename) +unsigned int +spreadsheet_get_sheet_n_rows (struct spreadsheet *s, int n) { - struct spreadsheet *ss = NULL; + return s->get_sheet_n_rows (s, n); +} - ss = gnumeric_probe (filename); - - return ss; +unsigned int +spreadsheet_get_sheet_n_columns (struct spreadsheet *s, int n) +{ + return s->get_sheet_n_columns (s, n); } -void -spreadsheet_close (struct spreadsheet *spreadsheet) +char * +spreadsheet_get_cell (struct spreadsheet *s, int n, int row, int column) { + return s->get_sheet_cell (s, n, row, column); } +#define RADIX 26 + +static void +reverse (char *s, int len) +{ + int i; + for (i = 0; i < len / 2; ++i) + { + char tmp = s[len - i - 1]; + s[len - i -1] = s[i]; + s[i] = tmp; + } +} + /* Convert a string, which is an integer encoded in base26 IE, A=0, B=1, ... Z=25 to the integer it represents. @@ -46,33 +110,110 @@ spreadsheet_close (struct spreadsheet *spreadsheet) greater than 1 are implicitly incremented by 1, so AA = 0 + 1*26, AB = 1 + 1*26, ABC = 2 + 2*26 + 1*26^2 .... + On error, this function returns -1 */ int -pseudo_base26 (const char *str) +ps26_to_int (const char *str) { int i; int multiplier = 1; int result = 0; int len = strlen (str); - for ( i = len - 1 ; i >= 0; --i) + for (i = len - 1 ; i >= 0; --i) { - int mantissa = (str[i] - 'A'); - - if ( mantissa < 0 || mantissa > 25 ) + char c = str[i]; + if (c < 'A' || c > 'Z') return -1; + int mantissa = (c - 'A'); + + assert (mantissa >= 0); + assert (mantissa < RADIX); - if ( i != len - 1) + if (i != len - 1) mantissa++; result += mantissa * multiplier; - - multiplier *= 26; + multiplier *= RADIX; } return result; } +/* Convert an integer, which must be non-negative, + to pseudo base 26. + The caller must free the return value when no longer required. */ +char * +int_to_ps26 (int i) +{ + char *ret = NULL; + + int lower = 0; + long long int base = RADIX; + int exp = 1; + + if (i < 0) + return NULL; + + while (i > lower + base - 1) + { + lower += base; + base *= RADIX; + assert (base > 0); + exp++; + } + + i -= lower; + i += base; + + ret = xmalloc (exp + 1); + + exp = 0; + do + { + ret[exp++] = (i % RADIX) + 'A'; + i /= RADIX; + } + while (i > 1); + + ret[exp]='\0'; + + reverse (ret, exp); + return ret; +} + + +char * +create_cell_ref (int col0, int row0) +{ + char *cs0 ; + char *s ; + + if (col0 < 0) return NULL; + if (row0 < 0) return NULL; + + cs0 = int_to_ps26 (col0); + s = c_xasprintf ("%s%d", cs0, row0 + 1); + + free (cs0); + + return s; +} + +char * +create_cell_range (int col0, int row0, int coli, int rowi) +{ + char *s0 = create_cell_ref (col0, row0); + char *si = create_cell_ref (coli, rowi); + + char *s = c_xasprintf ("%s:%s", s0, si); + + free (s0); + free (si); + + return s; +} + /* Convert a cell reference in the form "A1:B2", to integers. A1 means column zero, row zero. @@ -92,16 +233,15 @@ convert_cell_ref (const char *ref, int n = sscanf (ref, "%4[a-zA-Z]%d:%4[a-zA-Z]%d", startcol, &startrow, stopcol, &stoprow); - if ( n != 4) + if (n != 4) return false; str_uppercase (startcol); - *col0 = pseudo_base26 (startcol); + *col0 = ps26_to_int (startcol); str_uppercase (stopcol); - *coli = pseudo_base26 (stopcol); + *coli = ps26_to_int (stopcol); *row0 = startrow - 1; *rowi = stoprow - 1 ; return true; } -