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"
-/* (headers) */
+#include "linked-list.h"
+#include "file-handle-def.h"
-/* File handle private data. */
-struct private_file_handle
- {
- char *name; /* File handle identifier. */
- char *filename; /* Filename as provided by user. */
- struct file_identity *identity; /* For checking file identity. */
- struct file_locator where; /* Used for reporting error messages. */
- enum file_handle_mode mode; /* File mode. */
- size_t length; /* Length of fixed-format records. */
- size_t tab_width; /* Tab width, 0=do not expand tabs. */
- };
-
-/* Linked list of file handles. */
-struct file_handle_list
- {
- struct file_handle *handle;
- struct file_handle_list *next;
- };
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
-static struct file_handle_list *file_handles;
-struct file_handle *inline_file;
+/* (headers) */
-static struct file_handle *create_file_handle (const char *handle_name,
- const char *filename);
/* (specification)
"FILE HANDLE" (fh_):
/* (declarations) */
/* (functions) */
-static struct file_handle *
-get_handle_with_name (const char *handle_name)
-{
- struct file_handle_list *iter;
-
- for (iter = file_handles; iter != NULL; iter = iter->next)
- if (!strcmp (handle_name, iter->handle->private->name))
- return iter->handle;
- return NULL;
-}
-
-static struct file_handle *
-get_handle_for_filename (const char *filename)
-{
- struct file_identity *identity;
- struct file_handle_list *iter;
-
- /* First check for a file with the same identity. */
- identity = fn_get_identity (filename);
- if (identity != NULL)
- {
- for (iter = file_handles; iter != NULL; iter = iter->next)
- if (iter->handle->private->identity != NULL
- && !fn_compare_file_identities (identity,
- iter->handle->private->identity))
- {
- fn_free_identity (identity);
- return iter->handle;
- }
- fn_free_identity (identity);
- }
-
- /* Then check for a file with the same name. */
- for (iter = file_handles; iter != NULL; iter = iter->next)
- if (!strcmp (filename, iter->handle->private->filename))
- return iter->handle;
-
- return NULL;
-}
int
cmd_file_handle (void)
{
- char handle_name[9];
+ char handle_name[LONG_NAME_LEN + 1];
+ enum file_handle_mode mode = MODE_TEXT;
+ size_t length = 1024;
+ size_t tab_width = 4;
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->private->filename);
+ msg (SE, _("File handle %s already refers to file %s. "
+ "File handles cannot be redefined within a session."),
+ handle_name, handle_get_filename(handle));
return CMD_FAILURE;
}
goto lossage;
}
- handle = create_file_handle (handle_name, cmd.s_name);
switch (cmd.mode)
{
case FH_CHARACTER:
- handle->private->mode = MODE_TEXT;
+ mode = MODE_TEXT;
if (cmd.sbc_tabwidth)
- handle->private->tab_width = cmd.n_tabwidth;
+ tab_width = cmd.n_tabwidth[0];
else
- handle->private->tab_width = 4;
+ tab_width = 4;
break;
case FH_IMAGE:
- handle->private->mode = MODE_BINARY;
- if (cmd.n_lrecl == NOT_LONG)
+ mode = MODE_BINARY;
+ if (cmd.n_lrecl[0] == NOT_LONG)
{
msg (SE, _("Fixed-length records were specified on /RECFORM, but "
"record length was not specified on /LRECL. "
"Assuming 1024-character records."));
- handle->private->length = 1024;
+ length = 1024;
}
- else if (cmd.n_lrecl < 1)
+ 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);
- handle->private->length = 1;
+ "1-character records will be assumed."), cmd.n_lrecl[0]);
+ length = 1;
}
else
- handle->private->length = cmd.n_lrecl;
+ length = cmd.n_lrecl[0];
break;
default:
assert (0);
}
+ handle = create_file_handle (handle_name, cmd.s_name,
+ mode, length, tab_width);
+
+ free_file_handle (&cmd);
return CMD_SUCCESS;
lossage:
free_file_handle (&cmd);
return CMD_FAILURE;
}
-\f
-/* File handle functions. */
-
-/* Creates and returns a new file handle with the given values
- and defaults for other values. Adds the created file handle
- to the global list. */
-static struct file_handle *
-create_file_handle (const char *handle_name, const char *filename)
-{
- struct file_handle *handle;
- struct file_handle_list *list;
-
- /* Create and initialize file handle. */
- handle = xmalloc (sizeof *handle);
- handle->private = xmalloc (sizeof *handle->private);
- handle->private->name = xstrdup (handle_name);
- handle->private->filename = xstrdup (filename);
- handle->private->identity = fn_get_identity (filename);
- handle->private->where.filename = handle->private->filename;
- handle->private->where.line_number = 0;
- handle->private->mode = MODE_TEXT;
- handle->private->length = 1024;
- handle->private->tab_width = 4;
- handle->ext = NULL;
- handle->class = NULL;
-
- /* Add file handle to global list. */
- list = xmalloc (sizeof *list);
- list->handle = handle;
- list->next = file_handles;
- file_handles = list;
- return handle;
-}
-/* Closes the stdio FILE associated with handle H. Frees internal
- buffers associated with that file. Does *not* destroy the file
- handle H. (File handles are permanent during a session.) */
-void
-fh_close_handle (struct file_handle *h)
-{
- if (h == NULL)
- return;
- if (h->class != NULL)
- h->class->close (h);
- h->class = NULL;
- h->ext = NULL;
-}
+static struct linked_list *handle_list;
-/* Initialize the hash of file handles; inserts the "inline file"
- inline_file. */
-void
-fh_init_files (void)
-{
- if (inline_file == NULL)
- {
- inline_file = create_file_handle ("INLINE", _("<Inline File>"));
- inline_file->private->length = 80;
- }
-}
/* 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. */
struct file_handle *
-fh_parse_file_handle (void)
+fh_parse (void)
{
struct file_handle *handle;
char *filename = ds_c_str (&tokstr);
char *handle_name = xmalloc (strlen (filename) + 3);
sprintf (handle_name, "\"%s\"", filename);
- handle = create_file_handle (handle_name, filename);
+ handle = create_file_handle_with_defaults (handle_name, filename);
+ ll_push_front(handle_list, handle);
free (handle_name);
}
lex_get ();
+
return handle;
}
-/* Returns the identifier of file HANDLE. If HANDLE was created
- by referring to a filename instead of a handle name, returns
- the filename, enclosed in double quotes. Return value is
- owned by the file handle.
- Useful for printing error messages about use of file handles. */
-const char *
-handle_get_name (const struct file_handle *handle)
-{
- return handle->private->name;
-}
-
-/* Returns the name of the file associated with HANDLE. */
-const char *
-handle_get_filename (const struct file_handle *handle)
-{
- return handle->private->filename;
-}
-/* Returns the mode of HANDLE. */
-enum file_handle_mode
-handle_get_mode (const struct file_handle *handle)
+void
+fh_init(void)
{
- assert (handle != NULL);
- return handle->private->mode;
+ handle_list = ll_create(destroy_file_handle,0);
}
-/* Returns the width of a logical record on HANDLE. Applicable
- only to MODE_BINARY files. */
-size_t
-handle_get_record_width (const struct file_handle *handle)
+void
+fh_done(void)
{
- assert (handle != NULL);
- return handle->private->length;
+ if ( handle_list )
+ {
+ ll_destroy(handle_list);
+ handle_list = 0;
+ }
}
-/* Returns the number of characters per tab stop for HANDLE, or
- zero if tabs are not to be expanded. Applicable only to
- MODE_TEXT files. */
-size_t
-handle_get_tab_width (const struct file_handle *handle)
-{
- assert (handle != NULL);
- return handle->private->tab_width;
-}
/*
Local variables: