Changed all the licence notices in all the files.
[pspp-builds.git] / src / sfm-read.c
index 9c0cc6d3115b1b37cc411471856e3f0ac35be844..59fc1840d370c43130549892099333f7dd9bd89e 100644 (file)
@@ -14,8 +14,8 @@
 
    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 <config.h>
 #include "sfm-read.h"
@@ -122,26 +122,16 @@ corrupt_msg (int class, const char *format,...)
 static void
 corrupt_msg (int class, const char *format,...)
 {
-  char buf[1024];
-  
-  {
-    va_list args;
+  struct error e;
+  va_list args;
 
-    va_start (args, format);
-    vsnprintf (buf, 1024, format, args);
-    va_end (args);
-  }
-  
-  {
-    struct error e;
-
-    e.class = class;
-    getl_location (&e.where.filename, &e.where.line_number);
-    e.title = _("corrupt system file: ");
-    e.text = buf;
+  e.class = class;
+  getl_location (&e.where.filename, &e.where.line_number);
+  e.title = _("corrupt system file: ");
 
-    err_vmsg (&e);
-  }
+  va_start (args, format);
+  err_vmsg (&e, format, args);
+  va_end (args);
 }
 
 /* Closes a system file after we're done with it. */
@@ -153,9 +143,13 @@ sfm_close_reader (struct sfm_reader *r)
 
   if (r->fh != NULL)
     fh_close (r->fh, "system file", "rs");
-  if (fn_close (handle_get_filename (r->fh), r->file) == EOF)
-    msg (ME, _("%s: Closing system file: %s."),
-         handle_get_filename (r->fh), strerror (errno));
+  
+  if ( r->file ) {
+    if (fn_close (handle_get_filename (r->fh), r->file) == EOF)
+      msg (ME, _("%s: Closing system file: %s."),
+          handle_get_filename (r->fh), strerror (errno));
+    r->file = NULL;
+  }
   free (r->vars);
   free (r->buf);
   free (r);
@@ -326,10 +320,69 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
                break;
 
              case 5:
-             case 6:
-             case 11: /* ?? Used by SPSS 8.0. */
+             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 ) 
+                   {
+                     msg (MW, _("%s: Invalid subrecord length. "
+                                "Record: 7; Subrecord: 11"), 
+                          handle_get_filename (r->fh));
+                     skip = 1;
+                   }
+
+                 for ( i = 0 ; i < n_vars ; ++i ) 
+                   {
+                     struct
+                     {
+                       int32 measure P;
+                       int32 width P;
+                       int32 align P;
+                     }
+                     params;
+
+                     struct variable *v;
+
+                     assertive_buf_read (r, &params, 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 *s;
+                 char *buf = xmalloc(data.size * data.count + 1);
+                 char *tbuf ;
+                 assertive_buf_read (r, buf, data.size * data.count, 0);
+                 buf[data.size * data.count]='\0';
+
+                 s = strtok_r(buf, "\t", &tbuf);
+                 while ( s ) 
+                   {
+                     char *shortname, *longname;
+                     shortname = strsep(&s,"=");
+                     longname = strsep(&s,"=");
+                     
+                     dict_add_longvar_entry(*dict, shortname, longname);
+
+                     s = strtok_r(0,"\t", &tbuf);
+                   }
+                 
+                 free (buf);
+               }
+               break;
 
              default:
                msg (MW, _("%s: Unrecognized record type 7, subtype %d "
@@ -634,6 +687,8 @@ read_variables (struct sfm_reader *r,
   int next_value = 0;          /* Index to next `value' structure. */
   size_t var_cap = 0;
 
+  assert(r);
+
   /* Allocate variables. */
   *var_by_idx = xmalloc (sizeof **var_by_idx * r->value_cnt);
 
@@ -712,7 +767,7 @@ read_variables (struct sfm_reader *r,
       name[0] = toupper ((unsigned char) (sv.name[0]));
 
       /* Copy remaining characters of variable name. */
-      for (j = 1; j < 8; j++)
+      for (j = 1; j < SHORT_NAME_LEN; j++)
        {
          int c = (unsigned char) sv.name[j];
 
@@ -736,7 +791,7 @@ read_variables (struct sfm_reader *r,
       name[j] = 0;
 
       /* Create variable. */
-      vv = (*var_by_idx)[i] = dict_create_var (dict, name, sv.type);
+      vv = (*var_by_idx)[i] = dict_create_var_from_short (dict, name, sv.type);
       if (vv == NULL) 
         lose ((ME, _("%s: Duplicate variable name `%s' within system file."),
                handle_get_filename (r->fh), name));
@@ -763,11 +818,14 @@ read_variables (struct sfm_reader *r,
                          "length %d."),
                    handle_get_filename (r->fh), vv->name, len));
 
-         /* Read label into variable structure. */
-         vv->label = buf_read (r, NULL, ROUND_UP (len, sizeof (int32)), len + 1);
-         if (vv->label == NULL)
-           goto error;
-         vv->label[len] = '\0';
+         if ( len != 0 ) 
+           {
+             /* Read label into variable structure. */
+             vv->label = buf_read (r, NULL, ROUND_UP (len, sizeof (int32)), len + 1);
+             if (vv->label == NULL)
+               goto error;
+             vv->label[len] = '\0';
+           }
        }
 
       /* Set missing values. */
@@ -1085,8 +1143,15 @@ error:
 static void *
 buf_read (struct sfm_reader *r, void *buf, size_t byte_cnt, size_t min_alloc)
 {
-  if (buf == NULL)
+  assert (r);
+
+  if (buf == NULL && byte_cnt > 0 )
     buf = xmalloc (max (byte_cnt, min_alloc));
+
+  if ( byte_cnt == 0 )
+    return buf;
+
+  
   if (1 != fread (buf, byte_cnt, 1, r->file))
     {
       if (ferror (r->file))