- case 7:
- {
- struct
- {
- int32_t subtype P;
- int32_t size P;
- int32_t count P;
- }
- data;
- unsigned long bytes;
-
- int skip = 0;
-
- assertive_buf_read (r, &data, sizeof data, 0);
- if (r->reverse_endian)
- {
- bswap_int32 (&data.subtype);
- bswap_int32 (&data.size);
- bswap_int32 (&data.count);
- }
- bytes = data.size * data.count;
-
- if (bytes < data.size || bytes < data.count)
- lose ((ME, "%s: Record type %d subtype %d too large.",
- fh_get_file_name (r->fh), rec_type, data.subtype));
-
- switch (data.subtype)
- {
- case 3:
- if (!read_machine_int32_info (r, data.size, data.count))
- goto error;
- break;
-
- case 4:
- if (!read_machine_flt64_info (r, data.size, data.count))
- goto error;
- break;
-
- case 5:
- case 6: /* ?? Used by SPSS 8.0. */
- skip = 1;
- break;
-
- case 11: /* Variable display parameters */
- {
- const int n_vars = data.count / 3 ;
- int i;
- if ( data.count % 3 || n_vars != dict_get_var_cnt(*dict) )
- {
- msg (MW, _("%s: Invalid subrecord length. "
- "Record: 7; Subrecord: 11"),
- fh_get_file_name (r->fh));
- skip = 1;
- break;
- }
-
- for ( i = 0 ; i < min(n_vars, dict_get_var_cnt(*dict)) ; ++i )
- {
- struct
- {
- int32_t measure P;
- int32_t width P;
- int32_t align P;
- }
- params;
-
- struct variable *v;
-
- assertive_buf_read (r, ¶ms, sizeof(params), 0);
-
- v = dict_get_var(*dict, i);
-
- v->measure = params.measure;
- v->display_width = params.width;
- v->alignment = params.align;
- }
- }
- break;
-
- case 13: /* SPSS 12.0 Long variable name map */
- {
- char *short_name, *save_ptr;
- int idx;
-
- r->has_vls = true;
-
- /* Read data. */
- subrec14data = xmalloc (bytes + 1);
- if (!buf_read (r, subrec14data, bytes, 0))
- {
- goto error;
- }
- subrec14data[bytes] = '\0';
-
- short_to_long = hsh_create(4,
- pair_sn_compare,
- pair_sn_hash,
- pair_sn_free,
- 0);
-
- /* Parse data. */
- for (short_name = strtok_r (subrec14data, "=", &save_ptr), idx = 0;
- short_name != NULL;
- short_name = strtok_r (NULL, "=", &save_ptr), idx++)
- {
- struct name_pair *pair ;
- char *long_name = strtok_r (NULL, "\t", &save_ptr);
- struct variable *v;
-
- /* Validate long name. */
- if (long_name == NULL)
- {
- msg (MW, _("%s: Trailing garbage in long variable "
- "name map."),
- fh_get_file_name (r->fh));
- break;
- }
- if (!var_is_valid_name (long_name, false))
- {
- msg (MW, _("%s: Long variable mapping to invalid "
- "variable name `%s'."),
- fh_get_file_name (r->fh), long_name);
- break;
- }
-
- /* Find variable using short name. */
- v = dict_lookup_var (*dict, short_name);
- if (v == NULL)
- {
- msg (MW, _("%s: Long variable mapping for "
- "nonexistent variable %s."),
- fh_get_file_name (r->fh), short_name);
- break;
- }
-
- /* Identify any duplicates. */
- if ( compare_var_names(short_name, long_name, 0) &&
- NULL != dict_lookup_var (*dict, long_name))
- lose ((ME, _("%s: Duplicate long variable name `%s' "
- "within system file."),
- fh_get_file_name (r->fh), long_name));
-
-
- /* Set long name.
- Renaming a variable may clear the short
- name, but we want to retain it, so
- re-set it explicitly. */
- dict_rename_var (*dict, v, long_name);
- var_set_short_name (v, short_name);
-
- pair = xmalloc(sizeof *pair);
- pair->shortname = short_name;
- pair->longname = long_name;
- hsh_insert(short_to_long, pair);
-#if 0
- /* This messes up the processing of subtype 14 (below).
- I'm not sure if it is needed anyway, so I'm removing it for
- now. If it's needed, then it will need to be done after all the
- records have been processed. --- JMD 27 April 2006
- */
-
- /* For compatability, make sure dictionary
- is in long variable name map order. In
- the common case, this has no effect,
- because the dictionary and the long
- variable name map are already in the
- same order. */
- dict_reorder_var (*dict, v, idx);
-#endif
- }
-
- }
- break;
-
- case 14:
- {
- int j = 0;
- bool eq_seen = false;
- int i;
-
- /* Read data. */
- char *buffer = xmalloc (bytes + 1);
- if (!buf_read (r, buffer, bytes, 0))
- {
- free (buffer);
- goto error;
- }
- buffer[bytes] = '\0';
-
-
- /* Note: SPSS v13 terminates this record with 00,
- whereas SPSS v14 terminates it with 00 09. We must
- accept either */
- for(i = 0; i < bytes ; ++i)
- {
- long int length;
- static char name[SHORT_NAME_LEN + 1] = {0};
- static char len_str[6] ={0};
-
- switch( buffer[i] )
- {
- case '=':
- eq_seen = true;
- j = 0;
- break;
- case '\0':
- length = strtol(len_str, 0, 10);
- if ( length != LONG_MAX && length != LONG_MIN)
- {
- char *lookup_name = name;
- int l;
- int idx;
- struct variable *v;
-
- if ( short_to_long )
- {
- struct name_pair pair;
- struct name_pair *p;
-
- pair.shortname = name;
- p = hsh_find(short_to_long, &pair);
- if ( p )
- lookup_name = p->longname;
- }
-
- v = dict_lookup_var(*dict, lookup_name);
- if ( !v )
- {
- corrupt_msg(MW,
- _("%s: No variable called %s but it is listed in length table."),
- fh_get_file_name (r->fh), lookup_name);
-
- goto error;
-
- }
-
- l = length;
- if ( v->width > EFFECTIVE_LONG_STRING_LENGTH )
- l -= EFFECTIVE_LONG_STRING_LENGTH;
- else
- l -= v->width;
-
- idx = v->index;
- while ( l > 0 )
- {
- struct variable *v_next;
- v_next = dict_get_var(*dict, idx + 1);
-
- if ( v_next->width > EFFECTIVE_LONG_STRING_LENGTH )
- l -= EFFECTIVE_LONG_STRING_LENGTH;
- else
- l -= v_next->width;
-
- hsh_delete(r->var_hash, v_next);
-
- dict_delete_var(*dict, v_next);
- }
-
- assert ( length > MAX_LONG_STRING );
-
- v->width = length;
- v->print.w = v->width;
- v->write.w = v->width;
- v->nv = DIV_RND_UP (length, MAX_SHORT_STRING);
- }
- eq_seen = false;
- memset(name, 0, SHORT_NAME_LEN+1);
- memset(len_str, 0, 6);
- j = 0;
- break;
- case '\t':
- break;
- default:
- if ( eq_seen )
- len_str[j] = buffer[i];
- else
- name[j] = buffer[i];
- j++;
- break;
- }
- }
- free(buffer);
- dict_compact_values(*dict);
- }
- break;
-
- default:
- msg (MW, _("%s: Unrecognized record type 7, subtype %d "
- "encountered in system file."),
- fh_get_file_name (r->fh), data.subtype);
- skip = 1;
- }
-
- if (skip)
- {
- void *x = buf_read (r, NULL, data.size * data.count, 0);
- if (x == NULL)
- goto error;
- free (x);
- }
- }
- break;