/* $Id: translate 3.2.0.1 1998/07/26 10:27:09 stoklund Exp stoklund $ */
/* translate.c: filename translation.

   Copyright (C) 1998 Jakob Stoklund Olesen

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

#include "kpathsea:config.h"

#include "kpathsea:tex-hush.h"
#include "kpathsea:absolute.h"
#include "kpathsea:riscos.h"
#include "OS:osfile.h"

/* How to write new files */
extern enum riscos_output_mode_enum
  riscos_output_mode = output_mode_unset;

/* Return true if name is a file with owner or world read access */
boolean
riscos_read_access (const_string name)
{
  os_error *erp;
  int obj_type;
  fileswitch_attr attr;

  assert (name != NULL);
  erp = xosfile_read (name, &obj_type, NULL, NULL, NULL, &attr);

#ifdef KPSE_DEBUG
  if (KPSE_DEBUG_P (KPSE_DEBUG_STAT))
    {
      char *type[] =
      {"None", "File", "Dir", "Image"};
      assert (erp != NULL || obj_type >= 0 && obj_type < 4);
      DEBUGF2 ("OS_File 5,\"%s\" => %s\n", name,
	       erp ? erp->errmess : type[obj_type]);
    }
#endif

  if (erp)
    {
      errno_swi (erp);
      return false;
    }

  /* `a file' and `owner read access' */
  if (obj_type == 1)
    {
      /* We check both public and owner read access. This may fail if a file
         is owned by the user and has public but not private read access. It
         will also fail if we can see another users private files. */
      attr &= 0x11;

      if (!attr && !kpse_tex_hush ("readable"))
	{
	  WARNING1 ("%s: no read access", name);
	}
      return attr != 0;
    }
  else
    return 0;
}

/*--------------------------------------------------------------------
 riscos_translate_input(filename, filetype)
 The csd is prepended to the path if necessary and the extension
 delimiter is swapped between '.' and '/'. The string returned is
 malloc'ed and should be freed. If no readable file could be found NULL
 is returned.
--------------------------------------------------------------------*/

string
riscos_translate_input (const_string filename)
{
  string newname = riscos_ensure_prefix (filename);	/* the string to
							   return */
  string sufpos = find_suffix (newname);	/* where is the suffix? */
  int good;

  /* First see if given filename exist */
  good = riscos_read_access (newname);
  /* else try the opposite suffix delimiter */
  if (!good && sufpos)
    {
      sufpos[-1] = sufpos[-1] == '.' ? '/' : '.';
      good = riscos_read_access (newname);
    }

  if (good)
    return newname;
  else
    {
      free (newname);
      return NULL;
    }
}

string
riscos_translate_output (const_string filename)
{
  string newname = riscos_ensure_prefix (filename);	/* the string to
							   return */
  string sufpos = find_suffix (newname);	/* where is the suffix? */
  int good = false, obj_type;
  os_error *erp;

  /* We can't do anything sensible if there's no suffix */
  if (!sufpos)
    return newname;

  /* Does a document directory exist? */
  sufpos[-1] = '\0';
  erp = xosfile_read (newname, &obj_type, NULL, NULL, NULL, NULL);
  if (erp)
    errno_swi (erp);
  else
    switch (obj_type)
      {
      case 1:			/* file */
      case 3:			/* image, we won't use that */
	/* We are forced to use '/' */
	good = true;
	sufpos[-1] = '/';
	break;
      case 2:			/* directory, use it */
	good = true;
	sufpos[-1] = '.';
	break;
      case 0:			/* no object, we can choose */
	switch (riscos_output_mode)
	  {
	  case output_mode_slash:	/* we like a '/' extension */
	  default:		/* this is also the default mode */
	    sufpos[-1] = '/';
	    good = true;
	    break;
	  case output_mode_dot:	/* we like '.' extension */
	    /* make the output directory. TeX directories have very few
	       entries, so ask for 8 in case some filesystem takes notice. */
	    erp = xosfile_create_dir (newname, 8);
	    if (erp)
	      errno_swi (erp);
	    else
	      {
		sufpos[-1] = '.';	/* restore filename */
		good = true;
	      }
	    break;
	  }
	break;
      }

  if (good)
    return newname;
  else
    {
      free (newname);
      return NULL;
    }
}

/*
   Set the output mode after the convention used by FILE
 */
void
riscos_set_output_mode (const_string file)
{
  const_string suf;

  if (riscos_output_mode == output_mode_unset)
    {
      suf = find_suffix (file);
      if (suf != NULL)
	riscos_output_mode = suf[-1] == '.'
	  ? output_mode_dot : output_mode_slash;
    }
}
