X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fflip.c;h=7b33d3dbbbb67ed207e87359a614af0e026f69b3;hb=1f8dd363d6c20d07fcca14cb948018465fa5ed8b;hp=7bf59104f7fca2fe5da4abb137c48ffa435e2a8d;hpb=37597beca4a11edba50b847932fdfeca3a648fa2;p=pspp-builds.git diff --git a/src/flip.c b/src/flip.c index 7bf59104..7b33d3db 100644 --- a/src/flip.c +++ b/src/flip.c @@ -14,37 +14,49 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ -#include -#include +#include "config.h" +#include "error.h" #include #include #include #include #include +#include "algorithm.h" #include "alloc.h" +#include "case.h" #include "command.h" +#include "dictionary.h" #include "error.h" #include "lexer.h" #include "misc.h" #include "settings.h" #include "str.h" +#include "val.h" #include "var.h" #include "vfm.h" +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#include "gettext.h" +#define _(msgid) gettext (msgid) + /* List of variable names. */ struct varname { struct varname *next; - char name[9]; + char name[SHORT_NAME_LEN + 1]; }; /* Represents a FLIP input program. */ struct flip_pgm { struct variable **var; /* Variables to transpose. */ + int *idx_to_fv; /* var[]->index to compacted sink case fv. */ int var_cnt; /* Number of elements in `var'. */ int case_cnt; /* Pre-flip case count. */ size_t case_size; /* Post-flip bytes per case. */ @@ -71,8 +83,16 @@ cmd_flip (void) { struct flip_pgm *flip; + if (temporary != 0) + { + msg (SM, _("FLIP ignores TEMPORARY. " + "Temporary transformations will be made permanent.")); + cancel_temporary (); + } + flip = xmalloc (sizeof *flip); flip->var = NULL; + flip->idx_to_fv = dict_get_compacted_idx_to_fv (default_dict); flip->var_cnt = 0; flip->case_cnt = 0; flip->new_names = NULL; @@ -80,7 +100,6 @@ cmd_flip (void) flip->new_names_tail = NULL; flip->file = NULL; - lex_match_id ("FLIP"); lex_match ('/'); if (lex_match_id ("VARIABLES")) { @@ -110,7 +129,7 @@ cmd_flip (void) for (i = 0; i < flip->var_cnt; i++) if (flip->var[i] == flip->new_names) { - memmove (&flip->var[i], &flip->var[i + 1], sizeof *flip->var * (flip->var_cnt - i - 1)); + remove_element (flip->var, flip->var_cnt, sizeof *flip->var, i); flip->var_cnt--; break; } @@ -121,7 +140,7 @@ cmd_flip (void) temp_trns = temporary = 0; vfm_sink = flip_sink_create (flip); flip->new_names_tail = NULL; - procedure (NULL, NULL, NULL, NULL); + procedure (NULL, NULL); /* Flip the data we read. */ flip_file (flip); @@ -152,6 +171,7 @@ destroy_flip_pgm (struct flip_pgm *flip) struct varname *iter, *next; free (flip->var); + free (flip->idx_to_fv); for (iter = flip->new_names_head; iter != NULL; iter = next) { next = iter->next; @@ -167,33 +187,35 @@ destroy_flip_pgm (struct flip_pgm *flip) static int make_new_var (char name[]) { + char *cp; + + /* Trim trailing spaces. */ + cp = strchr (name, '\0'); + while (cp > name && isspace ((unsigned char) cp[-1])) + *--cp = '\0'; + /* Fix invalid characters. */ - { - char *cp; - - for (cp = name; *cp && !isspace (*cp); cp++) + for (cp = name; *cp && cp < name + SHORT_NAME_LEN; cp++) + if (cp == name) { - *cp = toupper ((unsigned char) *cp); - if (!isalpha (*cp) && *cp != '@' && *cp != '#' - && (cp == name || (*cp != '.' && *cp != '$' && *cp != '_' - && !isdigit (*cp)))) - { - if (cp == name) - *cp = 'V'; /* _ not valid in first position. */ - else - *cp = '_'; - } + if (!CHAR_IS_ID1 (*cp) || *cp == '$') + *cp = 'V'; } - *cp = 0; - } + else + { + if (!CHAR_IS_IDN (*cp)) + *cp = '_'; + } + *cp = '\0'; + str_uppercase (name); if (dict_create_var (default_dict, name, 0)) return 1; /* Add numeric extensions until acceptable. */ { - int len = (int) strlen (name); - char n[9]; + const int len = (int) strlen (name); + char n[SHORT_NAME_LEN + 1]; int i; for (i = 1; i < 10000000; i++) @@ -230,7 +252,7 @@ build_dictionary (struct flip_pgm *flip) for (i = 0; i < flip->case_cnt; i++) { struct variable *v; - char s[9]; + char s[SHORT_NAME_LEN + 1]; sprintf (s, "VAR%03d", i); v = dict_create_var_assert (default_dict, s, 0); @@ -271,14 +293,15 @@ flip_sink_create (struct flip_pgm *flip) /* Write variable names as first case. */ for (i = 0; i < flip->var_cnt; i++) - st_bare_pad_copy (info->output_buf[i].s, flip->var[i]->name, 8); + buf_copy_str_rpad (info->output_buf[i].s, MAX_SHORT_STRING, + flip->var[i]->name); if (fwrite (info->output_buf, sizeof *info->output_buf, flip->var_cnt, flip->file) != (size_t) flip->var_cnt) msg (FE, _("Error writing FLIP file: %s."), strerror (errno)); flip->case_cnt = 1; - return create_case_sink (&flip_sink_class, info); + return create_case_sink (&flip_sink_class, default_dict, info); } /* Writes case C to the FLIP sink. */ @@ -297,7 +320,7 @@ flip_sink_write (struct case_sink *sink, const struct ccase *c) v->next = NULL; if (flip->new_names->type == NUMERIC) { - double f = c->data[flip->new_names->fv].f; + double f = case_num (c, flip->idx_to_fv[flip->new_names->index]); if (f == SYSMIS) strcpy (v->name, "VSYSMIS"); @@ -309,14 +332,14 @@ flip_sink_write (struct case_sink *sink, const struct ccase *c) { char name[INT_DIGITS + 2]; sprintf (name, "V%d", (int) f); - strncpy (v->name, name, 8); - name[8] = 0; + str_copy_trunc (v->name, sizeof v->name, name); } } else { - int width = min (flip->new_names->width, 8); - memcpy (v->name, c->data[flip->new_names->fv].s, width); + int width = min (flip->new_names->width, MAX_SHORT_STRING); + memcpy (v->name, case_str (c, flip->idx_to_fv[flip->new_names->index]), + width); v->name[width] = 0; } @@ -329,10 +352,15 @@ flip_sink_write (struct case_sink *sink, const struct ccase *c) /* Write to external file. */ for (i = 0; i < flip->var_cnt; i++) - if (flip->var[i]->type == NUMERIC) - info->output_buf[i].f = c->data[flip->var[i]->fv].f; - else - info->output_buf[i].f = SYSMIS; + { + double out; + + if (flip->var[i]->type == NUMERIC) + out = case_num (c, flip->idx_to_fv[flip->var[i]->index]); + else + out = SYSMIS; + info->output_buf[i].f = out; + } if (fwrite (info->output_buf, sizeof *info->output_buf, flip->var_cnt, flip->file) != (size_t) flip->var_cnt) @@ -351,7 +379,7 @@ flip_file (struct flip_pgm *flip) /* Allocate memory for many cases. */ case_bytes = flip->var_cnt * sizeof *input_buf; - case_capacity = set_max_workspace / case_bytes; + case_capacity = get_max_workspace() / case_bytes; if (case_capacity > flip->case_cnt * 2) case_capacity = flip->case_cnt * 2; if (case_capacity < 2) @@ -400,9 +428,18 @@ flip_file (struct flip_pgm *flip) for (j = 0; j < read_cases; j++) output_buf[j] = input_buf[i + j * flip->var_cnt]; - if (fseek (output_file, - sizeof *input_buf * (case_idx + i * flip->case_cnt), - SEEK_SET) != 0) +#ifndef HAVE_FSEEKO +#define fseeko fseek +#endif + +#ifndef HAVE_OFF_T +#define off_t long int +#endif + + if (fseeko (output_file, + sizeof *input_buf * (case_idx + + (off_t) i * flip->case_cnt), + SEEK_SET) != 0) msg (FE, _("Error seeking FLIP source file: %s."), strerror (errno)); @@ -448,7 +485,7 @@ static const struct case_sink_class flip_sink_class = static struct case_source * flip_source_create (struct flip_pgm *pgm) { - return create_case_source (&flip_source_class, default_dict, pgm); + return create_case_source (&flip_source_class, pgm); } /* Reads the FLIP stream. Copies each case into C and calls @@ -459,11 +496,15 @@ flip_source_read (struct case_source *source, write_case_func *write_case, write_case_data wc_data) { struct flip_pgm *flip = source->aux; + union value *input_buf; int i; + input_buf = xmalloc (sizeof *input_buf * flip->case_cnt); for (i = 0; i < flip->var_cnt; i++) { - if (fread (c->data, sizeof *c->data, flip->case_cnt, + size_t j; + + if (fread (input_buf, sizeof *input_buf, flip->case_cnt, flip->file) != flip->case_cnt) { if (ferror (flip->file)) @@ -476,9 +517,12 @@ flip_source_read (struct case_source *source, break; } + for (j = 0; j < flip->case_cnt; j++) + case_data_rw (c, j)->f = input_buf[j].f; if (!write_case (wc_data)) break; } + free (input_buf); } /* Destroy internal data in SOURCE. */