Adopt use of gnulib for portability.
[pspp-builds.git] / src / file-handle.q
index 9c3a81a366a4bf5de31e657ba27e6a8ee6a8ae3b..6ea731ef13311ec2217ddebc37fcf9502eb450b7 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 "file-handle.h"
 #include "filename.h"
 #include "command.h"
 #include "lexer.h"
-#include "getline.h"
+#include "getl.h"
 #include "error.h"
 #include "magic.h"
 #include "var.h"
+#include "linked-list.h"
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
 /* (headers) */
 
 /* File handle. */
@@ -46,7 +51,7 @@ struct file_handle
 
     int open_cnt;               /* 0=not open, otherwise # of openers. */
     const char *type;           /* If open, type of file. */
-    const char *open_mode;      /* "[rw][se]". */
+    char open_mode[3];          /* "[rw][se]". */
     void *aux;                  /* Aux data pointer for owner if any. */
   };
 
@@ -71,7 +76,7 @@ get_handle_with_name (const char *handle_name)
   struct file_handle *iter;
 
   for (iter = file_handles; iter != NULL; iter = iter->next)
-    if (!strcmp (handle_name, iter->name))
+    if (!strcasecmp (handle_name, iter->name))
       return iter;
   return NULL;
 }
@@ -107,22 +112,21 @@ get_handle_for_filename (const char *filename)
 int
 cmd_file_handle (void)
 {
-  char handle_name[9];
+  char handle_name[LONG_NAME_LEN + 1];
 
   struct cmd_file_handle cmd;
   struct file_handle *handle;
 
   if (!lex_force_id ())
     return CMD_FAILURE;
-  strcpy (handle_name, tokid);
+  str_copy_trunc (handle_name, sizeof handle_name, tokid);
 
   handle = get_handle_with_name (handle_name);
   if (handle != NULL)
     {
-      msg (SE, _("File handle %s already refers to "
-                "file %s.  File handle cannot be redefined within a "
-                 "session."),
-          tokid, handle->filename);
+      msg (SE, _("File handle %s already refers to file %s.  "
+                 "File handles cannot be redefined within a session."),
+          handle_name, handle->filename);
       return CMD_FAILURE;
     }
 
@@ -168,7 +172,7 @@ cmd_file_handle (void)
       else if (cmd.n_lrecl[0] < 1)
        {
          msg (SE, _("Record length (%ld) must be at least one byte.  "
-                    "1-character records will be assumed."), cmd.n_lrecl);
+                    "1-character records will be assumed."), cmd.n_lrecl[0]);
           handle->length = 1;
        }
       else
@@ -208,13 +212,22 @@ create_file_handle (const char *handle_name, const char *filename)
   handle->tab_width = 4;
   handle->open_cnt = 0;
   handle->type = NULL;
-  handle->open_mode = NULL;
   handle->aux = NULL;
   file_handles = handle;
 
   return handle;
 }
 
+static void
+destroy_file_handle(void *fh_, void *aux UNUSED)
+{
+  struct file_handle *fh = fh_;
+  free (fh->name);
+  free (fh->filename);
+  fn_free_identity (fh->identity);
+  free (fh);
+}
+
 static const char *
 mode_name (const char *mode) 
 {
@@ -225,7 +238,7 @@ mode_name (const char *mode)
 }
 
 
-/* Tries to open FILE with the given TYPE and MODE.
+/* Tries to open handle H with the given TYPE and MODE.
 
    TYPE is the sort of file, e.g. "system file".  Only one given
    type of access is allowed on a given file handle at once.
@@ -242,8 +255,8 @@ mode_name (const char *mode)
    modes the void * will necessarily be null only if no other
    sharers are active.
 
-   If successful, references to type and mode are retained, so
-   they should probably be string literals. */
+   If successful, a reference to type is retained, so it should
+   probably be a string literal. */
 void **
 fh_open (struct file_handle *h, const char *type, const char *mode) 
 {
@@ -256,23 +269,32 @@ fh_open (struct file_handle *h, const char *type, const char *mode)
 
   if (h->open_cnt != 0) 
     {
-      if (strcmp (h->type, type))
-        msg (SE, _("Can't open %s as a %s because it is "
-                   "already open as a %s"),
-             handle_get_name (h), type, h->type);
-      else if (strcmp (h->open_mode, mode))
-        msg (SE, _("Can't open %s as a %s for %s because it is "
-                   "already open for %s"),
-             handle_get_name (h), type,
-             mode_name (mode), mode_name (h->open_mode));
+      if (strcmp (h->type, type)) 
+        {
+          msg (SE, _("Can't open %s as a %s because it is "
+                     "already open as a %s"),
+               handle_get_name (h), type, h->type);
+          return NULL; 
+        }
+      else if (strcmp (h->open_mode, mode)) 
+        {
+          msg (SE, _("Can't open %s as a %s for %s because it is "
+                     "already open for %s"),
+               handle_get_name (h), type,
+               mode_name (mode), mode_name (h->open_mode));
+          return NULL;
+        }
       else if (h->open_mode[1] == 'e')
-        msg (SE, _("Can't re-open %s as a %s for %s"),
-             handle_get_name (h), type, mode_name (mode));
+        {
+          msg (SE, _("Can't re-open %s as a %s for %s"),
+               handle_get_name (h), type, mode_name (mode));
+          return NULL;
+        }
     }
   else 
     {
       h->type = type;
-      h->open_mode = mode;
+      strcpy (h->open_mode, mode);
       assert (h->aux == NULL);
     }
   h->open_cnt++;
@@ -298,12 +320,15 @@ fh_close (struct file_handle *h, const char *type, const char *mode)
   if (h->open_cnt == 0) 
     {
       h->type = NULL;
-      h->open_mode = NULL;
       h->aux = NULL;
     }
   return h->open_cnt;
 }
 
+
+static struct linked_list *handle_list;
+
+
 /* Parses a file handle name, which may be a filename as a string or
    a file handle name as an identifier.  Returns the file handle or
    NULL on failure. */
@@ -330,11 +355,13 @@ fh_parse (void)
       char *handle_name = xmalloc (strlen (filename) + 3);
       sprintf (handle_name, "\"%s\"", filename);
       handle = create_file_handle (handle_name, filename);
+      ll_push_front(handle_list, handle);
       free (handle_name);
     }
 
   lex_get ();
 
+
   return handle;
 }
 
@@ -367,8 +394,7 @@ handle_get_mode (const struct file_handle *handle)
   return handle->mode;
 }
 
-/* Returns the width of a logical record on HANDLE.  Applicable
-   only to MODE_BINARY files.  */
+/* Returns the width of a logical record on HANDLE. */
 size_t
 handle_get_record_width (const struct file_handle *handle)
 {
@@ -386,6 +412,24 @@ handle_get_tab_width (const struct file_handle *handle)
   return handle->tab_width;
 }
 
+
+void 
+fh_init(void)
+{
+  handle_list = ll_create(destroy_file_handle,0);
+}
+
+void 
+fh_done(void)
+{
+  if ( handle_list )  
+  {
+    ll_destroy(handle_list);
+    handle_list = 0;
+  }
+}
+
+
 /*
    Local variables:
    mode: c