/* Configuration for GNU C-compiler for Commodore Amiga, running AmigaOS.
   Copyright (C) 1992 Free Software Foundation, Inc.
   Contributed by Markus M. Wild (wild@amiga.physik.unizh.ch).

This file is part of GNU CC.

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

GNU CC 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING.  If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */

/* first include the generic header, then modify some parts.. */

#include "m68k/xm-m68k.h"

/* Amiga specific headers, such as from the Native Developer Update kits,
   go in SYSTEM_INCLUDE_DIR.  STANDARD_INCLUDE_DIR is the equivalent of
   Unix "/usr/include".  All other include paths are set in Makefile. */

#define SYSTEM_INCLUDE_DIR	"/ade/os-include"
#define STANDARD_INCLUDE_DIR	"/ade/include"

/* Fork one piped subcommand.  SEARCH_FLAG is the system call to use
   (either execv or execvp).  ARGV is the arg vector to use.
   NOT_LAST is nonzero if this is not the last subcommand
   (i.e. its output should be piped to the next one.)  */

#define PEXECUTE(SEARCH_FLAG,PROGRAM,ARGV,NOT_LAST) \
({int (*_func)() = (SEARCH_FLAG ? execv : execvp);			\
  int _pid;								\
  int _pdes[2];								\
  int _input_desc = last_pipe_input;					\
  int _output_desc = STDOUT_FILE_NO;					\
  int _retries, _sleep_interval, _result;				\
									\
  /* If this isn't the last process, make a pipe for its output,	\
     and record it as waiting to be the input to the next process.  */	\
									\
  if (NOT_LAST)								\
    {									\
      if (pipe (_pdes) < 0)						\
	pfatal_with_name ("pipe");					\
      _output_desc = _pdes[WRITE_PORT];					\
      last_pipe_input = _pdes[READ_PORT];				\
    }									\
  else									\
    last_pipe_input = STDIN_FILE_NO;					\
									\
  /* Fork a subprocess; wait and retry if it fails.  */			\
  _sleep_interval = 1;							\
  for (_retries = 0; _retries < 4; _retries++)				\
    {									\
      _pid = vfork ();							\
      if (_pid >= 0)							\
	break;								\
      sleep (_sleep_interval);						\
      _sleep_interval *= 2;						\
    }									\
									\
  switch (_pid)								\
    {									\
    case -1:								\
      pfatal_with_name ("vfork");					\
      /* NOTREACHED */							\
      _result = 0;							\
      break;								\
									\
    case 0: /* child */							\
      /* Move the input and output pipes into place, if nec.  */	\
      if (_input_desc != STDIN_FILE_NO)					\
	{								\
	  close (STDIN_FILE_NO);					\
	  dup (_input_desc);						\
	  close (_input_desc);						\
	}								\
      if (_output_desc != STDOUT_FILE_NO)				\
	{								\
	  close (STDOUT_FILE_NO);					\
	  dup (_output_desc);						\
	  close (_output_desc);						\
	}								\
									\
      /* Close the parent's descs that aren't wanted here.  */		\
      if (last_pipe_input != STDIN_FILE_NO)				\
	close (last_pipe_input);					\
									\
      /* Exec the program.  */						\
      (*_func) (PROGRAM, ARGV);						\
      perror_exec (PROGRAM);						\
      exit (-1);							\
      /* NOTREACHED */							\
      _result = 0;							\
      break;								\
									\
    default:								\
      /* In the parent, after forking.					\
	 Close the descriptors that we made for this child.  */		\
      if (_input_desc != STDIN_FILE_NO)					\
	close (_input_desc);						\
      if (_output_desc != STDOUT_FILE_NO)				\
	close (_output_desc);						\
									\
      /* Return child's process number.  */				\
      _result = _pid;							\
      break;								\
    } 									\
_result; })								\

#define PEXECUTE_RESULT(STATUS, COMMAND) \
  ({ wait (& STATUS); })

/* the following macros are stolen more or less from xm-vms.h ... */

/* This macro is used to help compare filenames in cp-lex.c.  */

#define FILE_NAME_NONDIRECTORY(C)				\
({								\
   extern char *rindex();					\
   char * pnt_ = (C), * pnt1_;					\
   pnt1_ = rindex (pnt_, '/'); 					\
   pnt1_ = (pnt1_ == 0 ? rindex (pnt_, ':') : pnt1_);		\
   (pnt1_ == 0 ? pnt_ : pnt1_ + 1);				\
 })

/* Macro to generate the name of the cross reference file.  The standard
   one does not work, since it was written assuming that the conventions
   of a unix style filesystem will work on the host system.
 
   Contrary to VMS, I'm using the original unix filename, there's no reason
   not to use this under AmigaOS. */

#define XREF_FILE_NAME(BUFF, NAME)	\
  s = FILE_NAME_NONDIRECTORY (NAME);			\
  if (s == NAME) sprintf(BUFF, ".%s.gxref", NAME);	\
  else {						\
    unsigned char ch = *s; /* could be Latin1 char.. */	\
    /* temporary: cut the filename from the directory */\
    *s = 0;						\
    sprintf (BUFF, "%s.%c%s.gxref", NAME, ch, s+1);	\
    /* and restore the filename */			\
    *s = ch;						\
  }							\

/* Macro that is used in cp-xref.c to determine whether a file name is
   absolute or not.

   This checks for both, '/' as first character, since we're running under
   ixemul.library which provides for this unix'ism, and for the usual 
   logical-terminator, ':', somewhere in the filename. */

#define FILE_NAME_ABSOLUTE_P(NAME) (NAME[0] == '/' || index(NAME, ':'))

/* the colon conflicts with the name space of logicals */

#define PATH_SEPARATOR ','

/* AmigaOS handles rename(2) *much* better than any link(2)/unlink(2)
   hacks. It's actually the inverse case as on Unix. rename(2) was always
   there, link(2) is new with OS 2.0 */

#define HAVE_rename 1
