-\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;
-
- /* Create and initialize file handle. */
- handle = xmalloc (sizeof *handle);
- handle->next = file_handles;
- handle->name = xstrdup (handle_name);
- handle->filename = xstrdup (filename);
- handle->identity = fn_get_identity (filename);
- handle->where.filename = handle->filename;
- handle->where.line_number = 0;
- handle->mode = MODE_TEXT;
- handle->length = 1024;
- handle->tab_width = 4;
- handle->open_cnt = 0;
- handle->type = NULL;
- handle->open_mode = NULL;
- handle->aux = NULL;
- file_handles = handle;
-
- return handle;
-}
-
-void
-destroy_file_handle(struct file_handle *fh, void *aux UNUSED)
-{
- free (fh->name);
- free (fh->filename);
- fn_free_identity (fh->identity);
- free (fh);
-}
-
-static const char *
-mode_name (const char *mode)
-{
- assert (mode != NULL);
- assert (mode[0] == 'r' || mode[0] == 'w');
-
- return mode[0] == 'r' ? "reading" : "writing";
-}
-
-
-/* Tries to open FILE 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.
-
- MODE combines the read or write mode with the sharing mode.
- The first character is 'r' for read, 'w' for write. The
- second character is 's' to permit sharing, 'e' to require
- exclusive access.
-
- Returns the address of a void * that the caller can use for
- data specific to the file handle if successful, or a null
- pointer on failure. For exclusive access modes the void *
- will always be a null pointer at return. In shared access
- 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. */
-void **
-fh_open (struct file_handle *h, const char *type, const char *mode)
-{
- assert (h != NULL);
- assert (type != NULL);
- assert (mode != NULL);
- assert (mode[0] == 'r' || mode[0] == 'w');
- assert (mode[1] == 's' || mode[1] == 'e');
- assert (mode[2] == '\0');
-
- 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));
- 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));
- }
- else
- {
- h->type = type;
- h->open_mode = mode;
- assert (h->aux == NULL);
- }
- h->open_cnt++;
-
- return &h->aux;
-}
-
-/* Closes file handle H, which must have been open for the
- specified TYPE and MODE of access provided to fh_open().
- Returns zero if the file is now closed, nonzero if it is still
- open due to another reference. */
-int
-fh_close (struct file_handle *h, const char *type, const char *mode)
-{
- assert (h != NULL);
- assert (h->open_cnt > 0);
- assert (type != NULL);
- assert (!strcmp (type, h->type));
- assert (mode != NULL);
- assert (!strcmp (mode, h->open_mode));
-
- h->open_cnt--;
- 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;
-