Remove files that are not part of GCC distribution anymore.

This commit is contained in:
Alexander Kabaev 2007-05-19 02:34:18 +00:00
parent 096b39c236
commit 8902467bb7
9 changed files with 0 additions and 19712 deletions

View File

@ -1,74 +0,0 @@
/* Utility to pick a temporary filename prefix.
Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the libiberty library.
Libiberty 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.
Libiberty 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 libiberty; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* $FreeBSD$ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> /* May get P_tmpdir. */
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include "libiberty.h"
extern char *choose_tmpdir PARAMS ((void));
/* Name of temporary file.
mktemp requires 6 trailing X's. */
#define TEMP_FILE "ccXXXXXX"
#define TEMP_FILE_LEN (sizeof(TEMP_FILE) - 1)
/*
@deftypefn Extension char* choose_temp_base (void)
Return a prefix for temporary file names or @code{NULL} if unable to
find one. The current directory is chosen if all else fails so the
program is exited if a temporary directory can't be found (@code{mktemp}
fails). The buffer for the result is obtained with @code{xmalloc}.
This function is provided for backwards compatability only. Its use is
not recommended.
@end deftypefn
*/
char *
choose_temp_base ()
{
const char *base = choose_tmpdir ();
char *temp_filename;
int len;
len = strlen (base);
temp_filename = xmalloc (len + TEMP_FILE_LEN + 1);
strcpy (temp_filename, base);
strcpy (temp_filename + len, TEMP_FILE);
mktemp (temp_filename);
if (strlen (temp_filename) == 0)
abort ();
return temp_filename;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,459 +0,0 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha w/ELF.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Contributed by Richard Henderson (rth@tamu.edu).
This file is part of GCC.
GCC 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.
GCC 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 GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* $FreeBSD$ */
#undef OBJECT_FORMAT_COFF
#undef EXTENDED_COFF
#define OBJECT_FORMAT_ELF 1
/* ??? Move all SDB stuff from alpha.h to osf.h. */
#undef SDB_DEBUGGING_INFO
#define DBX_DEBUGGING_INFO 1
#define DWARF2_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
#undef ASM_FINAL_SPEC
/* alpha/ doesn't use elfos.h for some reason. */
#define TARGET_OBJFMT_CPP_BUILTINS() \
do \
{ \
builtin_define ("__ELF__"); \
} \
while (0)
#undef CC1_SPEC
#define CC1_SPEC "%{G*}"
#undef ASM_SPEC
#define ASM_SPEC "%{G*} %{relax:-relax} %{!gstabs*:-no-mdebug}%{gstabs*:-mdebug}"
#undef IDENT_ASM_OP
#define IDENT_ASM_OP "\t.ident\t"
/* Output #ident as a .ident. */
#undef ASM_OUTPUT_IDENT
#define ASM_OUTPUT_IDENT(FILE, NAME) \
fprintf (FILE, "%s\"%s\"\n", IDENT_ASM_OP, NAME);
/* This is how to allocate empty space in some section. The .zero
pseudo-op is used for this on most svr4 assemblers. */
#undef SKIP_ASM_OP
#define SKIP_ASM_OP "\t.zero\t"
#undef ASM_OUTPUT_SKIP
#define ASM_OUTPUT_SKIP(FILE, SIZE) \
fprintf (FILE, "%s"HOST_WIDE_INT_PRINT_UNSIGNED"\n", SKIP_ASM_OP, (SIZE))
/* Output the label which precedes a jumptable. Note that for all svr4
systems where we actually generate jumptables (which is to say every
svr4 target except i386, where we use casesi instead) we put the jump-
tables into the .rodata section and since other stuff could have been
put into the .rodata section prior to any given jumptable, we have to
make sure that the location counter for the .rodata section gets pro-
perly re-aligned prior to the actual beginning of the jump table. */
#undef ALIGN_ASM_OP
#define ALIGN_ASM_OP "\t.align\t"
#ifndef ASM_OUTPUT_BEFORE_CASE_LABEL
#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE, PREFIX, NUM, TABLE) \
ASM_OUTPUT_ALIGN ((FILE), 2);
#endif
#undef ASM_OUTPUT_CASE_LABEL
#define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, JUMPTABLE) \
do { \
ASM_OUTPUT_BEFORE_CASE_LABEL (FILE, PREFIX, NUM, JUMPTABLE) \
(*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); \
} while (0)
/* The standard SVR4 assembler seems to require that certain builtin
library routines (e.g. .udiv) be explicitly declared as .globl
in each assembly file where they are referenced. */
#undef ASM_OUTPUT_EXTERNAL_LIBCALL
#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
(*targetm.asm_out.globalize_label) (FILE, XSTR (FUN, 0))
/* This says how to output assembler code to declare an
uninitialized external linkage data object. Under SVR4,
the linker seems to want the alignment of data objects
to depend on their types. We do exactly that here. */
#undef COMMON_ASM_OP
#define COMMON_ASM_OP "\t.comm\t"
#undef ASM_OUTPUT_ALIGNED_COMMON
#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
do { \
fprintf ((FILE), "%s", COMMON_ASM_OP); \
assemble_name ((FILE), (NAME)); \
fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
} while (0)
/* This says how to output assembler code to declare an
uninitialized internal linkage data object. Under SVR4,
the linker seems to want the alignment of data objects
to depend on their types. We do exactly that here. */
#undef ASM_OUTPUT_ALIGNED_LOCAL
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
do { \
if ((SIZE) <= g_switch_value) \
sbss_section(); \
else \
bss_section(); \
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
if (!flag_inhibit_size_directive) \
ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE); \
ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT)); \
ASM_OUTPUT_LABEL(FILE, NAME); \
ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1); \
} while (0)
/* This says how to output assembler code to declare an
uninitialized external linkage data object. */
#undef ASM_OUTPUT_ALIGNED_BSS
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
do { \
ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \
} while (0)
/* Biggest alignment supported by the object file format of this
machine. Use this macro to limit the alignment which can be
specified using the `__attribute__ ((aligned (N)))' construct. If
not defined, the default value is `BIGGEST_ALIGNMENT'.
This value is really 2^63. Since gcc figures the alignment in bits,
we could only potentially get to 2^60 on suitable hosts. Due to other
considerations in varasm, we must restrict this to what fits in an int. */
#undef MAX_OFILE_ALIGNMENT
#define MAX_OFILE_ALIGNMENT \
(1 << (HOST_BITS_PER_INT < 64 ? HOST_BITS_PER_INT - 2 : 62))
/* This is the pseudo-op used to generate a contiguous sequence of byte
values from a double-quoted string WITHOUT HAVING A TERMINATING NUL
AUTOMATICALLY APPENDED. This is the same for most svr4 assemblers. */
#undef ASCII_DATA_ASM_OP
#define ASCII_DATA_ASM_OP "\t.ascii\t"
#undef READONLY_DATA_SECTION_ASM_OP
#define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rodata"
#undef BSS_SECTION_ASM_OP
#define BSS_SECTION_ASM_OP "\t.section\t.bss"
#undef SBSS_SECTION_ASM_OP
#define SBSS_SECTION_ASM_OP "\t.section\t.sbss,\"aw\""
#undef SDATA_SECTION_ASM_OP
#define SDATA_SECTION_ASM_OP "\t.section\t.sdata,\"aw\""
/* On svr4, we *do* have support for the .init and .fini sections, and we
can put stuff in there to be executed before and after `main'. We let
crtstuff.c and other files know this by defining the following symbols.
The definitions say how to change sections to the .init and .fini
sections. This is the same for all known svr4 assemblers. */
#undef INIT_SECTION_ASM_OP
#define INIT_SECTION_ASM_OP "\t.section\t.init"
#undef FINI_SECTION_ASM_OP
#define FINI_SECTION_ASM_OP "\t.section\t.fini"
#ifdef HAVE_GAS_SUBSECTION_ORDERING
#define ASM_SECTION_START_OP "\t.subsection\t-1"
/* Output assembly directive to move to the beginning of current section. */
#define ASM_OUTPUT_SECTION_START(FILE) \
fprintf ((FILE), "%s\n", ASM_SECTION_START_OP)
#endif
/* A default list of other sections which we might be "in" at any given
time. For targets that use additional sections (e.g. .tdesc) you
should override this definition in the target-specific file which
includes this file. */
#undef EXTRA_SECTIONS
#define EXTRA_SECTIONS in_sbss, in_sdata
/* A default list of extra section function definitions. For targets
that use additional sections (e.g. .tdesc) you should override this
definition in the target-specific file which includes this file. */
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
SECTION_FUNCTION_TEMPLATE(sbss_section, in_sbss, SBSS_SECTION_ASM_OP) \
SECTION_FUNCTION_TEMPLATE(sdata_section, in_sdata, SDATA_SECTION_ASM_OP)
extern void sbss_section (void);
extern void sdata_section (void);
#undef SECTION_FUNCTION_TEMPLATE
#define SECTION_FUNCTION_TEMPLATE(FN, ENUM, OP) \
void FN (void) \
{ \
if (in_section != ENUM) \
{ \
fprintf (asm_out_file, "%s\n", OP); \
in_section = ENUM; \
} \
}
/* Switch into a generic section. */
#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
#define TARGET_ASM_SELECT_SECTION default_elf_select_section
#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
/* Define the strings used for the special svr4 .type and .size directives.
These strings generally do not vary from one system running svr4 to
another, but if a given system (e.g. m88k running svr) needs to use
different pseudo-op names for these, they may be overridden in the
file which includes this one. */
#undef TYPE_ASM_OP
#define TYPE_ASM_OP "\t.type\t"
#undef SIZE_ASM_OP
#define SIZE_ASM_OP "\t.size\t"
/* This is how we tell the assembler that a symbol is weak. */
#undef ASM_WEAKEN_LABEL
#define ASM_WEAKEN_LABEL(FILE, NAME) \
do { fputs ("\t.weak\t", FILE); assemble_name (FILE, NAME); \
fputc ('\n', FILE); } while (0)
/* This is how we tell the assembler that two symbols have the same value. */
#undef ASM_OUTPUT_DEF
#define ASM_OUTPUT_DEF(FILE, ALIAS, NAME) \
do { \
assemble_name(FILE, ALIAS); \
fputs(" = ", FILE); \
assemble_name(FILE, NAME); \
fputc('\n', FILE); \
} while (0)
#undef ASM_OUTPUT_DEF_FROM_DECLS
#define ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL, TARGET) \
do { \
const char *alias = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
const char *name = IDENTIFIER_POINTER (TARGET); \
if (TREE_CODE (DECL) == FUNCTION_DECL) \
{ \
fputc ('$', FILE); \
assemble_name (FILE, alias); \
fputs ("..ng = $", FILE); \
assemble_name (FILE, name); \
fputs ("..ng\n", FILE); \
} \
assemble_name(FILE, alias); \
fputs(" = ", FILE); \
assemble_name(FILE, name); \
fputc('\n', FILE); \
} while (0)
/* The following macro defines the format used to output the second
operand of the .type assembler directive. Different svr4 assemblers
expect various different forms for this operand. The one given here
is just a default. You may need to override it in your machine-
specific tm.h file (depending upon the particulars of your assembler). */
#undef TYPE_OPERAND_FMT
#define TYPE_OPERAND_FMT "@%s"
/* Write the extra assembler code needed to declare a function's result.
Most svr4 assemblers don't require any special declaration of the
result value, but there are exceptions. */
#ifndef ASM_DECLARE_RESULT
#define ASM_DECLARE_RESULT(FILE, RESULT)
#endif
/* These macros generate the special .type and .size directives which
are used to set the corresponding fields of the linker symbol table
entries in an ELF object file under SVR4. These macros also output
the starting labels for the relevant functions/objects. */
/* Write the extra assembler code needed to declare an object properly. */
#undef ASM_DECLARE_OBJECT_NAME
#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
do { \
HOST_WIDE_INT size; \
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
size_directive_output = 0; \
if (!flag_inhibit_size_directive \
&& DECL_SIZE (DECL) \
&& (size = int_size_in_bytes (TREE_TYPE (DECL))) > 0) \
{ \
size_directive_output = 1; \
ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, size); \
} \
ASM_OUTPUT_LABEL(FILE, NAME); \
} while (0)
/* Output the size directive for a decl in rest_of_decl_compilation
in the case where we did not do so before the initializer.
Once we find the error_mark_node, we know that the value of
size_directive_output was set
by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */
#undef ASM_FINISH_DECLARE_OBJECT
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \
do { \
const char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
HOST_WIDE_INT size; \
if (!flag_inhibit_size_directive \
&& DECL_SIZE (DECL) \
&& ! AT_END && TOP_LEVEL \
&& DECL_INITIAL (DECL) == error_mark_node \
&& !size_directive_output \
&& (size = int_size_in_bytes (TREE_TYPE (DECL))) > 0) \
{ \
size_directive_output = 1; \
ASM_OUTPUT_SIZE_DIRECTIVE (FILE, name, size); \
} \
} while (0)
/* A table of bytes codes used by the ASM_OUTPUT_ASCII and
ASM_OUTPUT_LIMITED_STRING macros. Each byte in the table
corresponds to a particular byte value [0..255]. For any
given byte value, if the value in the corresponding table
position is zero, the given character can be output directly.
If the table value is 1, the byte must be output as a \ooo
octal escape. If the tables value is anything else, then the
byte value should be output as a \ followed by the value
in the table. Note that we can use standard UN*X escape
sequences for many control characters, but we don't use
\a to represent BEL because some svr4 assemblers (e.g. on
the i386) don't know about that. Also, we don't use \v
since some versions of gas, such as 2.2 did not accept it. */
#undef ESCAPES
#define ESCAPES \
"\1\1\1\1\1\1\1\1btn\1fr\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0\
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"
/* Some svr4 assemblers have a limit on the number of characters which
can appear in the operand of a .string directive. If your assembler
has such a limitation, you should define STRING_LIMIT to reflect that
limit. Note that at least some svr4 assemblers have a limit on the
actual number of bytes in the double-quoted string, and that they
count each character in an escape sequence as one byte. Thus, an
escape sequence like \377 would count as four bytes.
If your target assembler doesn't support the .string directive, you
should define this to zero. */
#undef STRING_LIMIT
#define STRING_LIMIT ((unsigned) 256)
#undef STRING_ASM_OP
#define STRING_ASM_OP "\t.string\t"
/* GAS is the only Alpha/ELF assembler. */
#undef TARGET_GAS
#define TARGET_GAS (1)
/* Provide a STARTFILE_SPEC appropriate for ELF. Here we add the
(even more) magical crtbegin.o file which provides part of the
support for getting C++ file-scope static object constructed
before entering `main'. */
#undef STARTFILE_SPEC
#ifdef HAVE_LD_PIE
#define STARTFILE_SPEC \
"%{!shared: %{pg|p:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}}\
crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
#else
#define STARTFILE_SPEC \
"%{!shared: %{pg|p:gcrt1.o%s;:crt1.o%s}}\
crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
#endif
/* Provide a ENDFILE_SPEC appropriate for ELF. Here we tack on the
magical crtend.o file which provides part of the support for
getting C++ file-scope static object constructed before entering
`main', followed by a normal ELF "finalizer" file, `crtn.o'. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC \
"%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
/* We support #pragma. */
#define HANDLE_SYSV_PRAGMA 1
/* Select a format to encode pointers in exception handling data. CODE
is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
true if the symbol may be affected by dynamic relocations.
Since application size is already constrained to <2GB by the form of
the ldgp relocation, we can use a 32-bit pc-relative relocation to
static data. Dynamic data is accessed indirectly to allow for read
only EH sections. */
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
(((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4)
/* If defined, a C statement to be executed just prior to the output of
assembler code for INSN. */
#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
(alpha_this_literal_sequence_number = 0, \
alpha_this_gpdisp_sequence_number = 0)
extern int alpha_this_literal_sequence_number;
extern int alpha_this_gpdisp_sequence_number;
/* Since the bits of the _init and _fini function is spread across
many object files, each potentially with its own GP, we must assume
we need to load our GP. Further, the .init/.fini section can
easily be more than 4MB away from the function to call so we can't
use bsr. */
#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
asm (SECTION_OP "\n" \
" br $29,1f\n" \
"1: ldgp $29,0($29)\n" \
" unop\n" \
" jsr $26," USER_LABEL_PREFIX #FUNC "\n" \
" .align 3\n" \
" .previous");
/* If we have the capability create headers for efficient EH lookup.
As of Jan 2002, only glibc 2.2.4 can actually make use of this, but
I imagine that other systems will catch up. In the meantime, it
doesn't harm to make sure that the data exists to be used later. */
#if defined(HAVE_LD_EH_FRAME_HDR)
#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
#endif

View File

@ -1,133 +0,0 @@
/* Definitions for DEC Alpha/AXP running FreeBSD using the ELF format
Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc.
Contributed by David E. O'Brien <obrien@FreeBSD.org> and BSDi.
This file is part of GCC.
GCC 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.
GCC 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 GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* $FreeBSD$ */
#undef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS \
{ "fbsd_dynamic_linker", FBSD_DYNAMIC_LINKER }
/* Provide a FBSD_TARGET_CPU_CPP_BUILTINS and CPP_SPEC appropriate for
FreeBSD/alpha. Besides the dealing with
the GCC option `-posix', and PIC issues as on all FreeBSD platforms, we must
deal with the Alpha's FP issues. */
#undef FBSD_TARGET_CPU_CPP_BUILTINS
#define FBSD_TARGET_CPU_CPP_BUILTINS() \
do \
{ \
builtin_define ("__LP64__"); \
if (flag_pic) \
{ \
builtin_define ("__PIC__"); \
builtin_define ("__pic__"); \
} \
} \
while (0)
#undef CPP_SPEC
#define CPP_SPEC "%(cpp_subtarget) %{posix:-D_POSIX_SOURCE}"
#define LINK_SPEC "%{G*} %{relax:-relax} \
%{p:%nconsider using `-pg' instead of `-p' with gprof(1)} \
%{Wl,*:%*} \
%{assert*} %{R*} %{rpath*} %{defsym*} \
%{shared:-Bshareable %{h*} %{soname*}} \
%{!shared: \
%{!static: \
%{rdynamic:-export-dynamic} \
%{!dynamic-linker:-dynamic-linker %(fbsd_dynamic_linker) }} \
%{static:-Bstatic}} \
%{symbolic:-Bsymbolic}"
/* Reset our STARTFILE_SPEC because of a moronic pigheaded
Linuxism(glibc'ism) that was added to alpha/elf.h. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC FBSD_STARTFILE_SPEC
/************************[ Target stuff ]***********************************/
/* Define the actual types of some ANSI-mandated types.
Needs to agree with <machine/ansi.h>. GCC defaults come from c-decl.c,
c-common.c, and config/<arch>/<arch>.h. */
/* alpha.h gets this wrong for FreeBSD. We use the GCC defaults instead. */
#undef WCHAR_TYPE
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32
/* Handle cross-compilation on 32-bits machines (such as i386) for 64-bits
machines (Alpha in this case). */
#if defined(__i386__)
#undef HOST_BITS_PER_LONG
#define HOST_BITS_PER_LONG 32
#undef HOST_WIDE_INT
#define HOST_WIDE_INT long long
#undef HOST_BITS_PER_WIDE_INT
#define HOST_BITS_PER_WIDE_INT 64
#endif
/* This is the pseudo-op used to generate a 64-bit word of data with a
specific value in some section. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (FreeBSD/Alpha ELF)");
#define TARGET_ELF 1
#undef OBJECT_FORMAT_COFF
#undef EXTENDED_COFF
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_FP | MASK_FPREGS | MASK_GAS)
#undef HAS_INIT_SECTION
/* Show that we need a GP when profiling. */
#undef TARGET_PROFILING_NEEDS_GP
#define TARGET_PROFILING_NEEDS_GP 1
/* We always use gas here, so we don't worry about ECOFF assembler problems. */
#undef TARGET_GAS
#define TARGET_GAS 1
/************************[ Assembler stuff ]********************************/
/************************[ Debugger stuff ]*********************************/
/* This is the char to use for continuation (in case we need to turn
continuation back on). */
#undef DBX_CONTIN_CHAR
#define DBX_CONTIN_CHAR '?'
/* Don't default to pcc-struct-return, we want to retain compatibility with
older FreeBSD releases AND pcc-struct-return may not be reentrant. */
#undef DEFAULT_PCC_STRUCT_RETURN
#define DEFAULT_PCC_STRUCT_RETURN 0

View File

@ -1,634 +0,0 @@
/* CPP Library.
Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Per Bothner, 1994-95.
Based on CCCP program by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
This program 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.
This program 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 this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* $FreeBSD$ */
#include "config.h"
#include "system.h"
#include "cpplib.h"
#include "cpphash.h"
#include "mkdeps.h"
static void init_library (void);
static void mark_named_operators (cpp_reader *);
static void read_original_filename (cpp_reader *);
static void read_original_directory (cpp_reader *);
static void post_options (cpp_reader *);
/* If we have designated initializers (GCC >2.7) these tables can be
initialized, constant data. Otherwise, they have to be filled in at
runtime. */
#if HAVE_DESIGNATED_INITIALIZERS
#define init_trigraph_map() /* Nothing. */
#define TRIGRAPH_MAP \
__extension__ const uchar _cpp_trigraph_map[UCHAR_MAX + 1] = {
#define END };
#define s(p, v) [p] = v,
#else
#define TRIGRAPH_MAP uchar _cpp_trigraph_map[UCHAR_MAX + 1] = { 0 }; \
static void init_trigraph_map (void) { \
unsigned char *x = _cpp_trigraph_map;
#define END }
#define s(p, v) x[p] = v;
#endif
TRIGRAPH_MAP
s('=', '#') s(')', ']') s('!', '|')
s('(', '[') s('\'', '^') s('>', '}')
s('/', '\\') s('<', '{') s('-', '~')
END
#undef s
#undef END
#undef TRIGRAPH_MAP
/* A set of booleans indicating what CPP features each source language
requires. */
struct lang_flags
{
char c99;
char cplusplus;
char extended_numbers;
char std;
char cplusplus_comments;
char digraphs;
};
static const struct lang_flags lang_defaults[] =
{ /* c99 c++ xnum std // digr */
/* GNUC89 */ { 0, 0, 1, 0, 1, 1 },
/* GNUC99 */ { 1, 0, 1, 0, 1, 1 },
/* STDC89 */ { 0, 0, 0, 1, 0, 0 },
/* STDC94 */ { 0, 0, 0, 1, 0, 1 },
/* STDC99 */ { 1, 0, 1, 1, 1, 1 },
/* GNUCXX */ { 0, 1, 1, 0, 1, 1 },
/* CXX98 */ { 0, 1, 1, 1, 1, 1 },
/* ASM */ { 0, 0, 1, 0, 1, 0 }
};
/* Sets internal flags correctly for a given language. */
void
cpp_set_lang (cpp_reader *pfile, enum c_lang lang)
{
const struct lang_flags *l = &lang_defaults[(int) lang];
CPP_OPTION (pfile, lang) = lang;
CPP_OPTION (pfile, c99) = l->c99;
CPP_OPTION (pfile, cplusplus) = l->cplusplus;
CPP_OPTION (pfile, extended_numbers) = l->extended_numbers;
CPP_OPTION (pfile, std) = l->std;
CPP_OPTION (pfile, trigraphs) = l->std;
CPP_OPTION (pfile, cplusplus_comments) = l->cplusplus_comments;
CPP_OPTION (pfile, digraphs) = l->digraphs;
}
/* Initialize library global state. */
static void
init_library (void)
{
static int initialized = 0;
if (! initialized)
{
initialized = 1;
/* Set up the trigraph map. This doesn't need to do anything if
we were compiled with a compiler that supports C99 designated
initializers. */
init_trigraph_map ();
}
}
/* Initialize a cpp_reader structure. */
cpp_reader *
cpp_create_reader (enum c_lang lang, hash_table *table)
{
cpp_reader *pfile;
/* Initialize this instance of the library if it hasn't been already. */
init_library ();
pfile = xcalloc (1, sizeof (cpp_reader));
cpp_set_lang (pfile, lang);
CPP_OPTION (pfile, warn_multichar) = 1;
CPP_OPTION (pfile, discard_comments) = 1;
CPP_OPTION (pfile, discard_comments_in_macro_exp) = 1;
CPP_OPTION (pfile, show_column) = 1;
CPP_OPTION (pfile, tabstop) = 8;
CPP_OPTION (pfile, operator_names) = 1;
CPP_OPTION (pfile, warn_trigraphs) = 2;
CPP_OPTION (pfile, warn_endif_labels) = 1;
CPP_OPTION (pfile, warn_deprecated) = 1;
CPP_OPTION (pfile, warn_long_long) = !CPP_OPTION (pfile, c99);
CPP_OPTION (pfile, dollars_in_ident) = 1;
CPP_OPTION (pfile, warn_dollars) = 1;
/* Default CPP arithmetic to something sensible for the host for the
benefit of dumb users like fix-header. */
CPP_OPTION (pfile, precision) = CHAR_BIT * sizeof (long);
CPP_OPTION (pfile, char_precision) = CHAR_BIT;
CPP_OPTION (pfile, wchar_precision) = CHAR_BIT * sizeof (int);
CPP_OPTION (pfile, int_precision) = CHAR_BIT * sizeof (int);
CPP_OPTION (pfile, unsigned_char) = 0;
CPP_OPTION (pfile, unsigned_wchar) = 1;
CPP_OPTION (pfile, bytes_big_endian) = 1; /* does not matter */
/* Default to locale/UTF-8. */
CPP_OPTION (pfile, narrow_charset) = _cpp_default_encoding ();
CPP_OPTION (pfile, wide_charset) = 0;
CPP_OPTION (pfile, input_charset) = _cpp_default_encoding ();
/* A fake empty "directory" used as the starting point for files
looked up without a search path. Name cannot be '/' because we
don't want to prepend anything at all to filenames using it. All
other entries are correct zero-initialized. */
pfile->no_search_path.name = (char *) "";
/* Initialize the line map. Start at logical line 1, so we can use
a line number of zero for special states. */
linemap_init (&pfile->line_maps);
pfile->line = 1;
/* Initialize lexer state. */
pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
/* Set up static tokens. */
pfile->avoid_paste.type = CPP_PADDING;
pfile->avoid_paste.val.source = NULL;
pfile->eof.type = CPP_EOF;
pfile->eof.flags = 0;
/* Create a token buffer for the lexer. */
_cpp_init_tokenrun (&pfile->base_run, 250);
pfile->cur_run = &pfile->base_run;
pfile->cur_token = pfile->base_run.base;
/* Initialize the base context. */
pfile->context = &pfile->base_context;
pfile->base_context.macro = 0;
pfile->base_context.prev = pfile->base_context.next = 0;
/* Aligned and unaligned storage. */
pfile->a_buff = _cpp_get_buff (pfile, 0);
pfile->u_buff = _cpp_get_buff (pfile, 0);
/* The expression parser stack. */
_cpp_expand_op_stack (pfile);
/* Initialize the buffer obstack. */
_obstack_begin (&pfile->buffer_ob, 0, 0,
(void *(*) (long)) xmalloc,
(void (*) (void *)) free);
_cpp_init_files (pfile);
_cpp_init_hashtable (pfile, table);
return pfile;
}
/* Free resources used by PFILE. Accessing PFILE after this function
returns leads to undefined behavior. Returns the error count. */
void
cpp_destroy (cpp_reader *pfile)
{
cpp_context *context, *contextn;
tokenrun *run, *runn;
free (pfile->op_stack);
while (CPP_BUFFER (pfile) != NULL)
_cpp_pop_buffer (pfile);
if (pfile->out.base)
free (pfile->out.base);
if (pfile->macro_buffer)
{
free (pfile->macro_buffer);
pfile->macro_buffer = NULL;
pfile->macro_buffer_len = 0;
}
if (pfile->deps)
deps_free (pfile->deps);
obstack_free (&pfile->buffer_ob, 0);
_cpp_destroy_hashtable (pfile);
_cpp_cleanup_files (pfile);
_cpp_destroy_iconv (pfile);
_cpp_free_buff (pfile->a_buff);
_cpp_free_buff (pfile->u_buff);
_cpp_free_buff (pfile->free_buffs);
for (run = &pfile->base_run; run; run = runn)
{
runn = run->next;
free (run->base);
if (run != &pfile->base_run)
free (run);
}
for (context = pfile->base_context.next; context; context = contextn)
{
contextn = context->next;
free (context);
}
linemap_free (&pfile->line_maps);
free (pfile);
}
/* This structure defines one built-in identifier. A node will be
entered in the hash table under the name NAME, with value VALUE.
There are two tables of these. builtin_array holds all the
"builtin" macros: these are handled by builtin_macro() in
cppmacro.c. Builtin is somewhat of a misnomer -- the property of
interest is that these macros require special code to compute their
expansions. The value is a "builtin_type" enumerator.
operator_array holds the C++ named operators. These are keywords
which act as aliases for punctuators. In C++, they cannot be
altered through #define, and #if recognizes them as operators. In
C, these are not entered into the hash table at all (but see
<iso646.h>). The value is a token-type enumerator. */
struct builtin
{
const uchar *name;
unsigned short len;
unsigned short value;
};
#define B(n, t) { DSC(n), t }
static const struct builtin builtin_array[] =
{
B("__TIME__", BT_TIME),
B("__DATE__", BT_DATE),
B("__FILE__", BT_FILE),
B("__BASE_FILE__", BT_BASE_FILE),
B("__LINE__", BT_SPECLINE),
B("__INCLUDE_LEVEL__", BT_INCLUDE_LEVEL),
/* Keep builtins not used for -traditional-cpp at the end, and
update init_builtins() if any more are added. */
B("_Pragma", BT_PRAGMA),
B("__STDC__", BT_STDC),
};
static const struct builtin operator_array[] =
{
B("and", CPP_AND_AND),
B("and_eq", CPP_AND_EQ),
B("bitand", CPP_AND),
B("bitor", CPP_OR),
B("compl", CPP_COMPL),
B("not", CPP_NOT),
B("not_eq", CPP_NOT_EQ),
B("or", CPP_OR_OR),
B("or_eq", CPP_OR_EQ),
B("xor", CPP_XOR),
B("xor_eq", CPP_XOR_EQ)
};
#undef B
/* Mark the C++ named operators in the hash table. */
static void
mark_named_operators (cpp_reader *pfile)
{
const struct builtin *b;
for (b = operator_array;
b < (operator_array + ARRAY_SIZE (operator_array));
b++)
{
cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len);
hp->flags |= NODE_OPERATOR;
hp->is_directive = 0;
hp->directive_index = b->value;
}
}
/* Read the builtins table above and enter them, and language-specific
macros, into the hash table. HOSTED is true if this is a hosted
environment. */
void
cpp_init_builtins (cpp_reader *pfile, int hosted)
{
const struct builtin *b;
size_t n = ARRAY_SIZE (builtin_array);
if (CPP_OPTION (pfile, traditional))
n -= 2;
for(b = builtin_array; b < builtin_array + n; b++)
{
cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len);
hp->type = NT_MACRO;
hp->flags |= NODE_BUILTIN | NODE_WARN;
hp->value.builtin = b->value;
}
if (CPP_OPTION (pfile, cplusplus))
_cpp_define_builtin (pfile, "__cplusplus 1");
else if (CPP_OPTION (pfile, lang) == CLK_ASM)
_cpp_define_builtin (pfile, "__ASSEMBLER__ 1");
else if (CPP_OPTION (pfile, lang) == CLK_STDC94)
_cpp_define_builtin (pfile, "__STDC_VERSION__ 199409L");
else if (CPP_OPTION (pfile, c99))
_cpp_define_builtin (pfile, "__STDC_VERSION__ 199901L");
if (hosted)
_cpp_define_builtin (pfile, "__STDC_HOSTED__ 1");
else
_cpp_define_builtin (pfile, "__STDC_HOSTED__ 0");
if (CPP_OPTION (pfile, objc))
_cpp_define_builtin (pfile, "__OBJC__ 1");
}
/* Sanity-checks are dependent on command-line options, so it is
called as a subroutine of cpp_read_main_file (). */
#if ENABLE_CHECKING
static void sanity_checks (cpp_reader *);
static void sanity_checks (cpp_reader *pfile)
{
cppchar_t test = 0;
size_t max_precision = 2 * CHAR_BIT * sizeof (cpp_num_part);
/* Sanity checks for assumptions about CPP arithmetic and target
type precisions made by cpplib. */
test--;
if (test < 1)
cpp_error (pfile, CPP_DL_ICE, "cppchar_t must be an unsigned type");
if (CPP_OPTION (pfile, precision) > max_precision)
cpp_error (pfile, CPP_DL_ICE,
"preprocessor arithmetic has maximum precision of %lu bits;"
" target requires %lu bits",
(unsigned long) max_precision,
(unsigned long) CPP_OPTION (pfile, precision));
if (CPP_OPTION (pfile, precision) < CPP_OPTION (pfile, int_precision))
cpp_error (pfile, CPP_DL_ICE,
"CPP arithmetic must be at least as precise as a target int");
if (CPP_OPTION (pfile, char_precision) < 8)
cpp_error (pfile, CPP_DL_ICE, "target char is less than 8 bits wide");
if (CPP_OPTION (pfile, wchar_precision) < CPP_OPTION (pfile, char_precision))
cpp_error (pfile, CPP_DL_ICE,
"target wchar_t is narrower than target char");
if (CPP_OPTION (pfile, int_precision) < CPP_OPTION (pfile, char_precision))
cpp_error (pfile, CPP_DL_ICE,
"target int is narrower than target char");
/* This is assumed in eval_token() and could be fixed if necessary. */
if (sizeof (cppchar_t) > sizeof (cpp_num_part))
cpp_error (pfile, CPP_DL_ICE,
"CPP half-integer narrower than CPP character");
if (CPP_OPTION (pfile, wchar_precision) > BITS_PER_CPPCHAR_T)
cpp_error (pfile, CPP_DL_ICE,
"CPP on this host cannot handle wide character constants over"
" %lu bits, but the target requires %lu bits",
(unsigned long) BITS_PER_CPPCHAR_T,
(unsigned long) CPP_OPTION (pfile, wchar_precision));
}
#else
# define sanity_checks(PFILE)
#endif
/* Add a dependency target. Can be called any number of times before
cpp_read_main_file(). If no targets have been added before
cpp_read_main_file(), then the default target is used. */
void
cpp_add_dependency_target (cpp_reader *pfile, const char *target, int quote)
{
if (!pfile->deps)
pfile->deps = deps_init ();
deps_add_target (pfile->deps, target, quote);
}
/* This is called after options have been parsed, and partially
processed. */
void
cpp_post_options (cpp_reader *pfile)
{
sanity_checks (pfile);
post_options (pfile);
/* Mark named operators before handling command line macros. */
if (CPP_OPTION (pfile, cplusplus) && CPP_OPTION (pfile, operator_names))
mark_named_operators (pfile);
}
/* Setup for processing input from the file named FNAME, or stdin if
it is the empty string. Return the original filename
on success (e.g. foo.i->foo.c), or NULL on failure. */
const char *
cpp_read_main_file (cpp_reader *pfile, const char *fname)
{
if (CPP_OPTION (pfile, deps.style) != DEPS_NONE)
{
if (!pfile->deps)
pfile->deps = deps_init ();
/* Set the default target (if there is none already). */
deps_add_default_target (pfile->deps, fname);
}
pfile->main_file
= _cpp_find_file (pfile, fname, &pfile->no_search_path, false, 0);
if (_cpp_find_failed (pfile->main_file))
return NULL;
_cpp_stack_file (pfile, pfile->main_file, false);
/* For foo.i, read the original filename foo.c now, for the benefit
of the front ends. */
if (CPP_OPTION (pfile, preprocessed))
{
read_original_filename (pfile);
if (!pfile->map)
return NULL;
fname = pfile->map->to_file;
}
return fname;
}
/* For preprocessed files, if the first tokens are of the form # NUM.
handle the directive so we know the original file name. This will
generate file_change callbacks, which the front ends must handle
appropriately given their state of initialization. */
static void
read_original_filename (cpp_reader *pfile)
{
const cpp_token *token, *token1;
/* Lex ahead; if the first tokens are of the form # NUM, then
process the directive, otherwise back up. */
token = _cpp_lex_direct (pfile);
if (token->type == CPP_HASH)
{
pfile->state.in_directive = 1;
token1 = _cpp_lex_direct (pfile);
_cpp_backup_tokens (pfile, 1);
pfile->state.in_directive = 0;
/* If it's a #line directive, handle it. */
if (token1->type == CPP_NUMBER)
{
_cpp_handle_directive (pfile, token->flags & PREV_WHITE);
read_original_directory (pfile);
return;
}
}
/* Backup as if nothing happened. */
_cpp_backup_tokens (pfile, 1);
}
/* For preprocessed files, if the tokens following the first filename
line is of the form # <line> "/path/name//", handle the
directive so we know the original current directory. */
static void
read_original_directory (cpp_reader *pfile)
{
const cpp_token *hash, *token;
/* Lex ahead; if the first tokens are of the form # NUM, then
process the directive, otherwise back up. */
hash = _cpp_lex_direct (pfile);
if (hash->type != CPP_HASH)
{
_cpp_backup_tokens (pfile, 1);
return;
}
token = _cpp_lex_direct (pfile);
if (token->type != CPP_NUMBER)
{
_cpp_backup_tokens (pfile, 2);
return;
}
token = _cpp_lex_direct (pfile);
if (token->type != CPP_STRING
|| ! (token->val.str.len >= 5
&& token->val.str.text[token->val.str.len-2] == '/'
&& token->val.str.text[token->val.str.len-3] == '/'))
{
_cpp_backup_tokens (pfile, 3);
return;
}
if (pfile->cb.dir_change)
{
char *debugdir = alloca (token->val.str.len - 3);
memcpy (debugdir, (const char *) token->val.str.text + 1,
token->val.str.len - 4);
debugdir[token->val.str.len - 4] = '\0';
pfile->cb.dir_change (pfile, debugdir);
}
}
/* This is called at the end of preprocessing. It pops the last
buffer and writes dependency output, and returns the number of
errors.
Maybe it should also reset state, such that you could call
cpp_start_read with a new filename to restart processing. */
int
cpp_finish (cpp_reader *pfile, FILE *deps_stream)
{
/* Warn about unused macros before popping the final buffer. */
if (CPP_OPTION (pfile, warn_unused_macros))
cpp_forall_identifiers (pfile, _cpp_warn_if_unused_macro, NULL);
/* cpplex.c leaves the final buffer on the stack. This it so that
it returns an unending stream of CPP_EOFs to the client. If we
popped the buffer, we'd dereference a NULL buffer pointer and
segfault. It's nice to allow the client to do worry-free excess
cpp_get_token calls. */
while (pfile->buffer)
_cpp_pop_buffer (pfile);
/* Don't write the deps file if there are errors. */
if (CPP_OPTION (pfile, deps.style) != DEPS_NONE
&& deps_stream && pfile->errors == 0)
{
deps_write (pfile->deps, deps_stream, 72);
if (CPP_OPTION (pfile, deps.phony_targets))
deps_phony_targets (pfile->deps, deps_stream);
}
/* Report on headers that could use multiple include guards. */
if (CPP_OPTION (pfile, print_include_names))
_cpp_report_missing_guards (pfile);
return pfile->errors;
}
static void
post_options (cpp_reader *pfile)
{
/* -Wtraditional is not useful in C++ mode. */
if (CPP_OPTION (pfile, cplusplus))
CPP_OPTION (pfile, warn_traditional) = 0;
/* Permanently disable macro expansion if we are rescanning
preprocessed text. Read preprocesed source in ISO mode. */
if (CPP_OPTION (pfile, preprocessed))
{
pfile->state.prevent_expansion = 1;
CPP_OPTION (pfile, traditional) = 0;
}
if (CPP_OPTION (pfile, warn_trigraphs) == 2)
CPP_OPTION (pfile, warn_trigraphs) = !CPP_OPTION (pfile, trigraphs);
if (CPP_OPTION (pfile, traditional))
{
CPP_OPTION (pfile, cplusplus_comments) = 0;
/* Traditional CPP does not accurately track column information. */
CPP_OPTION (pfile, show_column) = 0;
CPP_OPTION (pfile, trigraphs) = 0;
CPP_OPTION (pfile, warn_trigraphs) = 0;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,568 +0,0 @@
/* Specific flags and argument handling of the Fortran front-end.
Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2006
Free Software Foundation, Inc.
This file is part of GCC.
GCC 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.
GCC 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 GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* $FreeBSD$ */
/* This file contains a filter for the main `gcc' driver, which is
replicated for the `g77' driver by adding this filter. The purpose
of this filter is to be basically identical to gcc (in that
it faithfully passes all of the original arguments to gcc) but,
unless explicitly overridden by the user in certain ways, ensure
that the needs of the language supported by this wrapper are met.
For GNU Fortran (g77), we do the following to the argument list
before passing it to `gcc':
1. Make sure `-lg2c -lm' is at the end of the list.
2. Make sure each time `-lg2c' or `-lm' is seen, it forms
part of the series `-lg2c -lm'.
#1 and #2 are not done if `-nostdlib' or any option that disables
the linking phase is present, or if `-xfoo' is in effect. Note that
a lack of source files or -l options disables linking.
This program was originally made out of gcc/cp/g++spec.c, but the
way it builds the new argument list was rewritten so it is much
easier to maintain, improve the way it decides to add or not add
extra arguments, etc. And several improvements were made in the
handling of arguments, primarily to make it more consistent with
`gcc' itself. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "gcc.h"
#include "intl.h"
#ifndef MATH_LIBRARY
#define MATH_LIBRARY "-lm"
#endif
#ifndef MATH_LIBRARY_PROFILE
#define MATH_LIBRARY_PROFILE "-lm"
#endif
#ifndef FORTRAN_INIT
#define FORTRAN_INIT "-lfrtbegin"
#endif
#ifndef FORTRAN_INIT_PROFILE
#define FORTRAN_INIT_PROFILE "-lfrtbegin"
#endif
#ifndef FORTRAN_LIBRARY
#define FORTRAN_LIBRARY "-lg2c"
#endif
#ifndef FORTRAN_LIBRARY_PROFILE
#define FORTRAN_LIBRARY_PROFILE "-lg2c"
#endif
/* Options this driver needs to recognize, not just know how to
skip over. */
typedef enum
{
OPTION_b, /* Aka --prefix. */
OPTION_B, /* Aka --target. */
OPTION_c, /* Aka --compile. */
OPTION_driver, /* Wrapper-specific option. */
OPTION_E, /* Aka --preprocess. */
OPTION_help, /* --help. */
OPTION_i, /* -imacros, -include, -include-*. */
OPTION_l,
OPTION_L, /* Aka --library-directory. */
OPTION_M, /* Aka --dependencies. */
OPTION_MM, /* Aka --user-dependencies. */
OPTION_nostdlib, /* Aka --no-standard-libraries, or
-nodefaultlibs. */
OPTION_o, /* Aka --output. */
OPTION_p, /* Aka --profile. */
OPTION_S, /* Aka --assemble. */
OPTION_syntax_only, /* -fsyntax-only. */
OPTION_v, /* Aka --verbose. */
OPTION_version, /* --version. */
OPTION_V, /* Aka --use-version. */
OPTION_x, /* Aka --language. */
OPTION_ /* Unrecognized or unimportant. */
} Option;
/* The original argument list and related info is copied here. */
static int g77_xargc;
static const char *const *g77_xargv;
static void lookup_option (Option *, int *, const char **, const char *);
static void append_arg (const char *);
/* The new argument list will be built here. */
static int g77_newargc;
static const char **g77_newargv;
#ifndef SWITCH_TAKES_ARG
#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
#endif
#ifndef WORD_SWITCH_TAKES_ARG
#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
#endif
/* Assumes text[0] == '-'. Returns number of argv items that belong to
(and follow) this one, an option id for options important to the
caller, and a pointer to the first char of the arg, if embedded (else
returns NULL, meaning no arg or it's the next argv).
Note that this also assumes gcc.c's pass converting long options
to short ones, where available, has already been run. */
static void
lookup_option (Option *xopt, int *xskip, const char **xarg, const char *text)
{
Option opt = OPTION_;
int skip;
const char *arg = NULL;
if ((skip = SWITCH_TAKES_ARG (text[1])))
skip -= (text[2] != '\0'); /* See gcc.c. */
if (text[1] == 'B')
opt = OPTION_B, skip = (text[2] == '\0'), arg = text + 2;
else if (text[1] == 'b')
opt = OPTION_b, skip = (text[2] == '\0'), arg = text + 2;
else if ((text[1] == 'c') && (text[2] == '\0'))
opt = OPTION_c, skip = 0;
else if ((text[1] == 'E') && (text[2] == '\0'))
opt = OPTION_E, skip = 0;
else if (text[1] == 'i')
opt = OPTION_i, skip = 0;
else if (text[1] == 'l')
opt = OPTION_l;
else if (text[1] == 'L')
opt = OPTION_L, arg = text + 2;
else if (text[1] == 'o')
opt = OPTION_o;
else if ((text[1] == 'p') && (text[2] == '\0')
|| (text[1] == 'p') && (text[2] == 'g') && (text[3] == '\0'))
opt = OPTION_p;
else if ((text[1] == 'S') && (text[2] == '\0'))
opt = OPTION_S, skip = 0;
else if (text[1] == 'V')
opt = OPTION_V, skip = (text[2] == '\0');
else if ((text[1] == 'v') && (text[2] == '\0'))
opt = OPTION_v, skip = 0;
else if (text[1] == 'x')
opt = OPTION_x, arg = text + 2;
else
{
if ((skip = WORD_SWITCH_TAKES_ARG (text + 1)) != 0) /* See gcc.c. */
;
else if (! strncmp (text, "-fdriver", 8)) /* Really --driver!! */
opt = OPTION_driver; /* Never mind arg, this is unsupported. */
else if (! strcmp (text, "-fhelp")) /* Really --help!! */
opt = OPTION_help;
else if (! strcmp (text, "-M"))
opt = OPTION_M;
else if (! strcmp (text, "-MM"))
opt = OPTION_MM;
else if (! strcmp (text, "-nostdlib")
|| ! strcmp (text, "-nodefaultlibs"))
opt = OPTION_nostdlib;
else if (! strcmp (text, "-fsyntax-only"))
opt = OPTION_syntax_only;
else if (! strcmp (text, "-dumpversion"))
opt = OPTION_version;
else if (! strcmp (text, "-fversion")) /* Really --version!! */
opt = OPTION_version;
else if (! strcmp (text, "-Xlinker")
|| ! strcmp (text, "-specs"))
skip = 1;
else
skip = 0;
}
if (xopt != NULL)
*xopt = opt;
if (xskip != NULL)
*xskip = skip;
if (xarg != NULL)
{
if ((arg != NULL)
&& (arg[0] == '\0'))
*xarg = NULL;
else
*xarg = arg;
}
}
/* Append another argument to the list being built. As long as it is
identical to the corresponding arg in the original list, just increment
the new arg count. Otherwise allocate a new list, etc. */
static void
append_arg (const char *arg)
{
static int newargsize;
#if 0
fprintf (stderr, "`%s'\n", arg);
#endif
if (g77_newargv == g77_xargv
&& g77_newargc < g77_xargc
&& (arg == g77_xargv[g77_newargc]
|| ! strcmp (arg, g77_xargv[g77_newargc])))
{
++g77_newargc;
return; /* Nothing new here. */
}
if (g77_newargv == g77_xargv)
{ /* Make new arglist. */
int i;
newargsize = (g77_xargc << 2) + 20; /* This should handle all. */
g77_newargv = xmalloc (newargsize * sizeof (char *));
/* Copy what has been done so far. */
for (i = 0; i < g77_newargc; ++i)
g77_newargv[i] = g77_xargv[i];
}
if (g77_newargc == newargsize)
fatal ("overflowed output arg list for `%s'", arg);
g77_newargv[g77_newargc++] = arg;
}
void
lang_specific_driver (int *in_argc, const char *const **in_argv,
int *in_added_libraries ATTRIBUTE_UNUSED)
{
int argc = *in_argc;
const char *const *argv = *in_argv;
int i;
int verbose = 0;
Option opt;
int skip;
const char *arg;
/* This will be NULL if we encounter a situation where we should not
link in libf2c. */
const char *library = FORTRAN_LIBRARY;
/* 0 => -xnone in effect.
1 => -xfoo in effect. */
int saw_speclang = 0;
/* 0 => initial/reset state
1 => last arg was -l<library>
2 => last two args were -l<library> -lm. */
int saw_library = 0;
/* 0 => initial/reset state
1 => FORTRAN_INIT linked in */
int use_init = 0;
/* By default, we throw on the math library if we have one. */
int need_math = (MATH_LIBRARY[0] != '\0');
/* If non-zero, the user gave us the `-p' or `-pg' flag. */
int saw_profile_flag = 0;
/* The number of input and output files in the incoming arg list. */
int n_infiles = 0;
int n_outfiles = 0;
#if 0
fprintf (stderr, "Incoming:");
for (i = 0; i < argc; i++)
fprintf (stderr, " %s", argv[i]);
fprintf (stderr, "\n");
#endif
g77_xargc = argc;
g77_xargv = argv;
g77_newargc = 0;
g77_newargv = (const char **) argv;
/* First pass through arglist.
If -nostdlib or a "turn-off-linking" option is anywhere in the
command line, don't do any library-option processing (except
relating to -x). Also, if -v is specified, but no other options
that do anything special (allowing -V version, etc.), remember
to add special stuff to make gcc command actually invoke all
the different phases of the compilation process so all the version
numbers can be seen.
Also, here is where all problems with missing arguments to options
are caught. If this loop is exited normally, it means all options
have the appropriate number of arguments as far as the rest of this
program is concerned. */
for (i = 1; i < argc; ++i)
{
if ((argv[i][0] == '+') && (argv[i][1] == 'e'))
{
continue;
}
if ((argv[i][0] != '-') || (argv[i][1] == '\0'))
{
++n_infiles;
continue;
}
lookup_option (&opt, &skip, NULL, argv[i]);
switch (opt)
{
case OPTION_nostdlib:
case OPTION_c:
case OPTION_S:
case OPTION_syntax_only:
case OPTION_E:
case OPTION_M:
case OPTION_MM:
/* These options disable linking entirely or linking of the
standard libraries. */
library = 0;
break;
case OPTION_l:
++n_infiles;
break;
case OPTION_o:
++n_outfiles;
break;
case OPTION_p:
saw_profile_flag = 1;
library = FORTRAN_LIBRARY_PROFILE;
break;
case OPTION_v:
verbose = 1;
break;
case OPTION_b:
case OPTION_B:
case OPTION_L:
case OPTION_i:
case OPTION_V:
/* These options are useful in conjunction with -v to get
appropriate version info. */
break;
case OPTION_version:
printf ("GNU Fortran (GCC) %s\n", version_string);
printf ("Copyright %s 2006 Free Software Foundation, Inc.\n",
_("(C)"));
printf ("\n");
printf (_("\
GNU Fortran comes with NO WARRANTY, to the extent permitted by law.\n\
You may redistribute copies of GNU Fortran\n\
under the terms of the GNU General Public License.\n\
For more information about these matters, see the file named COPYING\n\
or type the command `info -f g77 Copying'.\n\
"));
exit (0);
break;
case OPTION_help:
/* Let gcc.c handle this, as it has a really
cool facility for handling --help and --verbose --help. */
return;
case OPTION_driver:
fatal ("--driver no longer supported");
break;
default:
break;
}
/* This is the one place we check for missing arguments in the
program. */
if (i + skip < argc)
i += skip;
else
fatal ("argument to `%s' missing", argv[i]);
}
if ((n_outfiles != 0) && (n_infiles == 0))
fatal ("no input files; unwilling to write output files");
/* If there are no input files, no need for the library. */
if (n_infiles == 0)
library = 0;
/* Second pass through arglist, transforming arguments as appropriate. */
append_arg (argv[0]); /* Start with command name, of course. */
for (i = 1; i < argc; ++i)
{
if (argv[i][0] == '\0')
{
append_arg (argv[i]); /* Interesting. Just append as is. */
continue;
}
if ((argv[i][0] == '-') && (argv[i][1] != 'l'))
{
/* Not a filename or library. */
if (saw_library == 1 && need_math) /* -l<library>. */
append_arg (saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY);
saw_library = 0;
lookup_option (&opt, &skip, &arg, argv[i]);
if (argv[i][1] == '\0')
{
append_arg (argv[i]); /* "-" == Standard input. */
continue;
}
if (opt == OPTION_x)
{
/* Track input language. */
const char *lang;
if (arg == NULL)
lang = argv[i+1];
else
lang = arg;
saw_speclang = (strcmp (lang, "none") != 0);
}
append_arg (argv[i]);
for (; skip != 0; --skip)
append_arg (argv[++i]);
continue;
}
/* A filename/library, not an option. */
if (saw_speclang)
saw_library = 0; /* -xfoo currently active. */
else
{ /* -lfoo or filename. */
if (strcmp (argv[i], MATH_LIBRARY) == 0)
{
if (saw_library == 1)
saw_library = 2; /* -l<library> -lm. */
else
{
if (0 == use_init)
{
append_arg (saw_profile_flag ? FORTRAN_INIT_PROFILE
: FORTRAN_INIT);
use_init = 1;
}
append_arg (saw_profile_flag ? FORTRAN_LIBRARY_PROFILE
: FORTRAN_LIBRARY);
}
}
else if (strcmp (argv[i], FORTRAN_LIBRARY) == 0)
saw_library = 1; /* -l<library>. */
else
{ /* Other library, or filename. */
if (saw_library == 1 && need_math)
append_arg (saw_profile_flag ? MATH_LIBRARY_PROFILE
: MATH_LIBRARY);
saw_library = 0;
}
}
append_arg (argv[i]);
}
/* Append `-lg2c -lm' as necessary. */
if (library)
{ /* Doing a link and no -nostdlib. */
if (saw_speclang)
append_arg ("-xnone");
switch (saw_library)
{
case 0:
if (0 == use_init)
{
append_arg (saw_profile_flag ? FORTRAN_INIT_PROFILE
: FORTRAN_INIT);
use_init = 1;
}
append_arg (library);
case 1:
if (need_math)
append_arg (saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY);
default:
break;
}
}
#ifdef ENABLE_SHARED_LIBGCC
if (library)
{
int i;
for (i = 1; i < g77_newargc; i++)
if (g77_newargv[i][0] == '-')
if (strcmp (g77_newargv[i], "-static-libgcc") == 0
|| strcmp (g77_newargv[i], "-static") == 0)
break;
if (i == g77_newargc)
append_arg ("-shared-libgcc");
}
#endif
if (verbose
&& g77_newargv != g77_xargv)
{
fprintf (stderr, "Driving:");
for (i = 0; i < g77_newargc; i++)
fprintf (stderr, " %s", g77_newargv[i]);
fprintf (stderr, "\n");
}
*in_argc = g77_newargc;
*in_argv = g77_newargv;
}
/* Called before linking. Returns 0 on success and -1 on failure. */
int lang_specific_pre_link (void) /* Not used for F77. */
{
return 0;
}
/* Number of extra output files that lang_specific_pre_link may generate. */
int lang_specific_extra_outfiles = 0; /* Not used for F77. */
/* Table of language-specific spec functions. */
const struct spec_function lang_specific_spec_functions[] =
{
{ 0, 0 }
};

View File

@ -1,181 +0,0 @@
/* Utility to pick a temporary filename prefix.
Copyright (C) 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
This file is part of the libiberty library.
Libiberty 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.
Libiberty 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 libiberty; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* $FreeBSD$ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> /* May get P_tmpdir. */
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_SYS_FILE_H
#include <sys/file.h> /* May get R_OK, etc. on some systems. */
#endif
#ifndef R_OK
#define R_OK 4
#define W_OK 2
#define X_OK 1
#endif
#include "libiberty.h"
extern int mkstemps PARAMS ((char *, int));
/* '/' works just fine on MS-DOS based systems. */
#ifndef DIR_SEPARATOR
#define DIR_SEPARATOR '/'
#endif
/* Name of temporary file.
mktemp requires 6 trailing X's. */
#define TEMP_FILE "ccXXXXXX"
#define TEMP_FILE_LEN (sizeof(TEMP_FILE) - 1)
/* Subroutine of choose_tmpdir.
If BASE is non-NULL, return it.
Otherwise it checks if DIR is a usable directory.
If success, DIR is returned.
Otherwise NULL is returned. */
static inline const char *try PARAMS ((const char *, const char *));
static inline const char *
try (dir, base)
const char *dir, *base;
{
if (base != 0)
return base;
if (dir != 0
&& access (dir, R_OK | W_OK | X_OK) == 0)
return dir;
return 0;
}
static const char tmp[] = { DIR_SEPARATOR, 't', 'm', 'p', 0 };
static const char usrtmp[] =
{ DIR_SEPARATOR, 'u', 's', 'r', DIR_SEPARATOR, 't', 'm', 'p', 0 };
static const char vartmp[] =
{ DIR_SEPARATOR, 'v', 'a', 'r', DIR_SEPARATOR, 't', 'm', 'p', 0 };
static char *memoized_tmpdir;
/*
@deftypefn Replacement char* choose_tmpdir ()
Returns a pointer to a directory path suitable for creating temporary
files in.
@end deftypefn
*/
char *
choose_tmpdir ()
{
const char *base = 0;
char *tmpdir;
unsigned int len;
if (memoized_tmpdir)
return memoized_tmpdir;
base = try (getenv ("TMPDIR"), base);
base = try (getenv ("TMP"), base);
base = try (getenv ("TEMP"), base);
#ifdef P_tmpdir
base = try (P_tmpdir, base);
#endif
/* Try /tmp, /var/tmp, then /usr/tmp. */
base = try (tmp, base);
base = try (vartmp, base);
base = try (usrtmp, base);
/* If all else fails, use the current directory! */
if (base == 0)
base = ".";
/* Append DIR_SEPARATOR to the directory we've chosen
and return it. */
len = strlen (base);
tmpdir = xmalloc (len + 2);
strcpy (tmpdir, base);
tmpdir[len] = DIR_SEPARATOR;
tmpdir[len+1] = '\0';
memoized_tmpdir = tmpdir;
return tmpdir;
}
/*
@deftypefn Replacement char* make_temp_file (const char *@var{suffix})
Return a temporary file name (as a string) or @code{NULL} if unable to
create one. @var{suffix} is a suffix to append to the file name. The
string is @code{malloc}ed, and the temporary file has been created.
@end deftypefn
*/
char *
make_temp_file (suffix)
const char *suffix;
{
const char *base = choose_tmpdir ();
char *temp_filename;
int base_len, suffix_len;
int fd;
if (suffix == 0)
suffix = "";
base_len = strlen (base);
suffix_len = strlen (suffix);
temp_filename = xmalloc (base_len
+ TEMP_FILE_LEN
+ suffix_len + 1);
strcpy (temp_filename, base);
strcpy (temp_filename + base_len, TEMP_FILE);
strcpy (temp_filename + base_len + TEMP_FILE_LEN, suffix);
fd = mkstemps (temp_filename, suffix_len);
/* If mkstemps failed, then something bad is happening. Maybe we should
issue a message about a possible security attack in progress? */
if (fd == -1)
abort ();
/* Similarly if we can not close the file. */
if (close (fd))
abort ();
return temp_filename;
}

View File

@ -1,794 +0,0 @@
/* Utilities to execute a program in a subprocess (possibly linked by pipes
with other subprocesses), and wait for it.
Copyright (C) 1996-2000 Free Software Foundation, Inc.
This file is part of the libiberty library.
Libiberty 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.
Libiberty 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 libiberty; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* $FreeBSD$ */
/* This file exports two functions: pexecute and pwait. */
/* This file lives in at least two places: libiberty and gcc.
Don't change one without the other. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <errno.h>
#ifdef NEED_DECLARATION_ERRNO
extern int errno;
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#include "libiberty.h"
#include "safe-ctype.h"
/* stdin file number. */
#define STDIN_FILE_NO 0
/* stdout file number. */
#define STDOUT_FILE_NO 1
/* value of `pipe': port index for reading. */
#define READ_PORT 0
/* value of `pipe': port index for writing. */
#define WRITE_PORT 1
static char *install_error_msg = "installation problem, cannot exec `%s'";
/* pexecute: execute a program.
@deftypefn Extension int pexecute (const char *@var{program}, char * const *@var{argv}, const char *@var{this_pname}, const char *@var{temp_base}, char **@var{errmsg_fmt}, char **@var{errmsg_arg}, int flags)
Executes a program.
@var{program} and @var{argv} are the arguments to
@code{execv}/@code{execvp}.
@var{this_pname} is name of the calling program (i.e., @code{argv[0]}).
@var{temp_base} is the path name, sans suffix, of a temporary file to
use if needed. This is currently only needed for MS-DOS ports that
don't use @code{go32} (do any still exist?). Ports that don't need it
can pass @code{NULL}.
(@code{@var{flags} & PEXECUTE_SEARCH}) is non-zero if @env{PATH} should be searched
(??? It's not clear that GCC passes this flag correctly). (@code{@var{flags} &
PEXECUTE_FIRST}) is nonzero for the first process in chain.
(@code{@var{flags} & PEXECUTE_FIRST}) is nonzero for the last process
in chain. The first/last flags could be simplified to only mark the
last of a chain of processes but that requires the caller to always
mark the last one (and not give up early if some error occurs).
It's more robust to require the caller to mark both ends of the chain.
The result is the pid on systems like Unix where we
@code{fork}/@code{exec} and on systems like WIN32 and OS/2 where we
use @code{spawn}. It is up to the caller to wait for the child.
The result is the @code{WEXITSTATUS} on systems like MS-DOS where we
@code{spawn} and wait for the child here.
Upon failure, @var{errmsg_fmt} and @var{errmsg_arg} are set to the
text of the error message with an optional argument (if not needed,
@var{errmsg_arg} is set to @code{NULL}), and @minus{}1 is returned.
@code{errno} is available to the caller to use.
@end deftypefn
@deftypefn Extension int pwait (int @var{pid}, int *@var{status}, int @var{flags})
Waits for a program started by @code{pexecute} to finish.
@var{pid} is the process id of the task to wait for. @var{status} is
the `status' argument to wait. @var{flags} is currently unused (allows
future enhancement without breaking upward compatibility). Pass 0 for now.
The result is the pid of the child reaped, or -1 for failure
(@code{errno} says why).
On systems that don't support waiting for a particular child, @var{pid} is
ignored. On systems like MS-DOS that don't really multitask @code{pwait}
is just a mechanism to provide a consistent interface for the caller.
@end deftypefn
@undocumented pfinish
pfinish: finish generation of script
pfinish is necessary for systems like MPW where a script is generated that
runs the requested programs. */
#ifdef __MSDOS__
/* MSDOS doesn't multitask, but for the sake of a consistent interface
the code behaves like it does. pexecute runs the program, tucks the
exit code away, and returns a "pid". pwait must be called to fetch the
exit code. */
#include <process.h>
/* For communicating information from pexecute to pwait. */
static int last_pid = 0;
static int last_status = 0;
static int last_reaped = 0;
int
pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
const char *program;
char * const *argv;
const char *this_pname;
const char *temp_base;
char **errmsg_fmt, **errmsg_arg;
int flags;
{
int rc;
last_pid++;
if (last_pid < 0)
last_pid = 1;
if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE)
abort ();
#ifdef __DJGPP__
/* ??? What are the possible return values from spawnv? */
rc = (flags & PEXECUTE_SEARCH ? spawnvp : spawnv) (P_WAIT, program, argv);
#else
char *scmd, *rf;
FILE *argfile;
int i, el = flags & PEXECUTE_SEARCH ? 4 : 0;
if (temp_base == 0)
temp_base = choose_temp_base ();
scmd = (char *) xmalloc (strlen (program) + strlen (temp_base) + 6 + el);
rf = scmd + strlen(program) + 2 + el;
sprintf (scmd, "%s%s @%s.gp", program,
(flags & PEXECUTE_SEARCH ? ".exe" : ""), temp_base);
argfile = fopen (rf, "w");
if (argfile == 0)
{
int errno_save = errno;
free (scmd);
errno = errno_save;
*errmsg_fmt = "cannot open `%s.gp'";
*errmsg_arg = temp_base;
return -1;
}
for (i=1; argv[i]; i++)
{
char *cp;
for (cp = argv[i]; *cp; cp++)
{
if (*cp == '"' || *cp == '\'' || *cp == '\\' || ISSPACE (*cp))
fputc ('\\', argfile);
fputc (*cp, argfile);
}
fputc ('\n', argfile);
}
fclose (argfile);
rc = system (scmd);
{
int errno_save = errno;
remove (rf);
free (scmd);
errno = errno_save;
}
#endif
if (rc == -1)
{
*errmsg_fmt = install_error_msg;
*errmsg_arg = (char *)program;
return -1;
}
/* Tuck the status away for pwait, and return a "pid". */
last_status = rc << 8;
return last_pid;
}
/* Use ECHILD if available, otherwise use EINVAL. */
#ifdef ECHILD
#define PWAIT_ERROR ECHILD
#else
#define PWAIT_ERROR EINVAL
#endif
int
pwait (pid, status, flags)
int pid;
int *status;
int flags;
{
/* On MSDOS each pexecute must be followed by it's associated pwait. */
if (pid != last_pid
/* Called twice for the same child? */
|| pid == last_reaped)
{
errno = PWAIT_ERROR;
return -1;
}
/* ??? Here's an opportunity to canonicalize the values in STATUS.
Needed? */
#ifdef __DJGPP__
*status = (last_status >> 8);
#else
*status = last_status;
#endif
last_reaped = last_pid;
return last_pid;
}
#endif /* MSDOS */
#if defined (_WIN32) && ! defined (_UWIN)
#include <process.h>
#ifdef __CYGWIN__
#define fix_argv(argvec) (argvec)
extern int _spawnv ();
extern int _spawnvp ();
#else /* ! __CYGWIN__ */
/* This is a kludge to get around the Microsoft C spawn functions' propensity
to remove the outermost set of double quotes from all arguments. */
static const char * const *
fix_argv (argvec)
char **argvec;
{
int i;
for (i = 1; argvec[i] != 0; i++)
{
int len, j;
char *temp, *newtemp;
temp = argvec[i];
len = strlen (temp);
for (j = 0; j < len; j++)
{
if (temp[j] == '"')
{
newtemp = xmalloc (len + 2);
strncpy (newtemp, temp, j);
newtemp [j] = '\\';
strncpy (&newtemp [j+1], &temp [j], len-j);
newtemp [len+1] = 0;
temp = newtemp;
len++;
j++;
}
}
argvec[i] = temp;
}
for (i = 0; argvec[i] != 0; i++)
{
if (strpbrk (argvec[i], " \t"))
{
int len, trailing_backslash;
char *temp;
len = strlen (argvec[i]);
trailing_backslash = 0;
/* There is an added complication when an arg with embedded white
space ends in a backslash (such as in the case of -iprefix arg
passed to cpp). The resulting quoted strings gets misinterpreted
by the command interpreter -- it thinks that the ending quote
is escaped by the trailing backslash and things get confused.
We handle this case by escaping the trailing backslash, provided
it was not escaped in the first place. */
if (len > 1
&& argvec[i][len-1] == '\\'
&& argvec[i][len-2] != '\\')
{
trailing_backslash = 1;
++len; /* to escape the final backslash. */
}
len += 2; /* and for the enclosing quotes. */
temp = xmalloc (len + 1);
temp[0] = '"';
strcpy (temp + 1, argvec[i]);
if (trailing_backslash)
temp[len-2] = '\\';
temp[len-1] = '"';
temp[len] = '\0';
argvec[i] = temp;
}
}
return (const char * const *) argvec;
}
#endif /* __CYGWIN__ */
#include <io.h>
#include <fcntl.h>
#include <signal.h>
/* mingw32 headers may not define the following. */
#ifndef _P_WAIT
# define _P_WAIT 0
# define _P_NOWAIT 1
# define _P_OVERLAY 2
# define _P_NOWAITO 3
# define _P_DETACH 4
# define WAIT_CHILD 0
# define WAIT_GRANDCHILD 1
#endif
/* Win32 supports pipes */
int
pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
const char *program;
char * const *argv;
const char *this_pname;
const char *temp_base;
char **errmsg_fmt, **errmsg_arg;
int flags;
{
int pid;
int pdes[2], org_stdin, org_stdout;
int input_desc, output_desc;
int retries, sleep_interval;
/* Pipe waiting from last process, to be used as input for the next one.
Value is STDIN_FILE_NO if no pipe is waiting
(i.e. the next command is the first of a group). */
static int last_pipe_input;
/* If this is the first process, initialize. */
if (flags & PEXECUTE_FIRST)
last_pipe_input = STDIN_FILE_NO;
input_desc = last_pipe_input;
/* 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 (! (flags & PEXECUTE_LAST))
{
if (_pipe (pdes, 256, O_BINARY) < 0)
{
*errmsg_fmt = "pipe";
*errmsg_arg = NULL;
return -1;
}
output_desc = pdes[WRITE_PORT];
last_pipe_input = pdes[READ_PORT];
}
else
{
/* Last process. */
output_desc = STDOUT_FILE_NO;
last_pipe_input = STDIN_FILE_NO;
}
if (input_desc != STDIN_FILE_NO)
{
org_stdin = dup (STDIN_FILE_NO);
dup2 (input_desc, STDIN_FILE_NO);
close (input_desc);
}
if (output_desc != STDOUT_FILE_NO)
{
org_stdout = dup (STDOUT_FILE_NO);
dup2 (output_desc, STDOUT_FILE_NO);
close (output_desc);
}
pid = (flags & PEXECUTE_SEARCH ? _spawnvp : _spawnv)
(_P_NOWAIT, program, fix_argv(argv));
if (input_desc != STDIN_FILE_NO)
{
dup2 (org_stdin, STDIN_FILE_NO);
close (org_stdin);
}
if (output_desc != STDOUT_FILE_NO)
{
dup2 (org_stdout, STDOUT_FILE_NO);
close (org_stdout);
}
if (pid == -1)
{
*errmsg_fmt = install_error_msg;
*errmsg_arg = program;
return -1;
}
return pid;
}
/* MS CRTDLL doesn't return enough information in status to decide if the
child exited due to a signal or not, rather it simply returns an
integer with the exit code of the child; eg., if the child exited with
an abort() call and didn't have a handler for SIGABRT, it simply returns
with status = 3. We fix the status code to conform to the usual WIF*
macros. Note that WIFSIGNALED will never be true under CRTDLL. */
int
pwait (pid, status, flags)
int pid;
int *status;
int flags;
{
#ifdef __CYGWIN__
return wait (status);
#else
int termstat;
pid = _cwait (&termstat, pid, WAIT_CHILD);
/* ??? Here's an opportunity to canonicalize the values in STATUS.
Needed? */
/* cwait returns the child process exit code in termstat.
A value of 3 indicates that the child caught a signal, but not
which one. Since only SIGABRT, SIGFPE and SIGINT do anything, we
report SIGABRT. */
if (termstat == 3)
*status = SIGABRT;
else
*status = (((termstat) & 0xff) << 8);
return pid;
#endif /* __CYGWIN__ */
}
#endif /* _WIN32 && ! _UWIN */
#ifdef OS2
/* ??? Does OS2 have process.h? */
extern int spawnv ();
extern int spawnvp ();
int
pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
const char *program;
char * const *argv;
const char *this_pname;
const char *temp_base;
char **errmsg_fmt, **errmsg_arg;
int flags;
{
int pid;
if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE)
abort ();
/* ??? Presumably 1 == _P_NOWAIT. */
pid = (flags & PEXECUTE_SEARCH ? spawnvp : spawnv) (1, program, argv);
if (pid == -1)
{
*errmsg_fmt = install_error_msg;
*errmsg_arg = program;
return -1;
}
return pid;
}
int
pwait (pid, status, flags)
int pid;
int *status;
int flags;
{
/* ??? Here's an opportunity to canonicalize the values in STATUS.
Needed? */
int pid = wait (status);
return pid;
}
#endif /* OS2 */
#ifdef MPW
/* MPW pexecute doesn't actually run anything; instead, it writes out
script commands that, when run, will do the actual executing.
For example, in GCC's case, GCC will write out several script commands:
cpp ...
cc1 ...
as ...
ld ...
and then exit. None of the above programs will have run yet. The task
that called GCC will then execute the script and cause cpp,etc. to run.
The caller must invoke pfinish before calling exit. This adds
the finishing touches to the generated script. */
static int first_time = 1;
int
pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
const char *program;
char * const *argv;
const char *this_pname;
const char *temp_base;
char **errmsg_fmt, **errmsg_arg;
int flags;
{
char tmpprogram[255];
char *cp, *tmpname;
int i;
mpwify_filename (program, tmpprogram);
if (first_time)
{
printf ("Set Failed 0\n");
first_time = 0;
}
fputs ("If {Failed} == 0\n", stdout);
/* If being verbose, output a copy of the command. It should be
accurate enough and escaped enough to be "clickable". */
if (flags & PEXECUTE_VERBOSE)
{
fputs ("\tEcho ", stdout);
fputc ('\'', stdout);
fputs (tmpprogram, stdout);
fputc ('\'', stdout);
fputc (' ', stdout);
for (i=1; argv[i]; i++)
{
fputc ('\'', stdout);
/* See if we have an argument that needs fixing. */
if (strchr(argv[i], '/'))
{
tmpname = (char *) xmalloc (256);
mpwify_filename (argv[i], tmpname);
argv[i] = tmpname;
}
for (cp = argv[i]; *cp; cp++)
{
/* Write an Option-d escape char in front of special chars. */
if (strchr("'+", *cp))
fputc ('\266', stdout);
fputc (*cp, stdout);
}
fputc ('\'', stdout);
fputc (' ', stdout);
}
fputs ("\n", stdout);
}
fputs ("\t", stdout);
fputs (tmpprogram, stdout);
fputc (' ', stdout);
for (i=1; argv[i]; i++)
{
/* See if we have an argument that needs fixing. */
if (strchr(argv[i], '/'))
{
tmpname = (char *) xmalloc (256);
mpwify_filename (argv[i], tmpname);
argv[i] = tmpname;
}
if (strchr (argv[i], ' '))
fputc ('\'', stdout);
for (cp = argv[i]; *cp; cp++)
{
/* Write an Option-d escape char in front of special chars. */
if (strchr("'+", *cp))
fputc ('\266', stdout);
fputc (*cp, stdout);
}
if (strchr (argv[i], ' '))
fputc ('\'', stdout);
fputc (' ', stdout);
}
fputs ("\n", stdout);
/* Output commands that arrange to clean up and exit if a failure occurs.
We have to be careful to collect the status from the program that was
run, rather than some other script command. Also, we don't exit
immediately, since necessary cleanups are at the end of the script. */
fputs ("\tSet TmpStatus {Status}\n", stdout);
fputs ("\tIf {TmpStatus} != 0\n", stdout);
fputs ("\t\tSet Failed {TmpStatus}\n", stdout);
fputs ("\tEnd\n", stdout);
fputs ("End\n", stdout);
/* We're just composing a script, can't fail here. */
return 0;
}
int
pwait (pid, status, flags)
int pid;
int *status;
int flags;
{
*status = 0;
return 0;
}
/* Write out commands that will exit with the correct error code
if something in the script failed. */
void
pfinish ()
{
printf ("\tExit \"{Failed}\"\n");
}
#endif /* MPW */
/* include for Unix-like environments but not for Dos-like environments */
#if ! defined (__MSDOS__) && ! defined (OS2) && ! defined (MPW) \
&& ! (defined (_WIN32) && ! defined (_UWIN))
extern int execv ();
extern int execvp ();
int
pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
const char *program;
char * const *argv;
const char *this_pname;
const char *temp_base ATTRIBUTE_UNUSED;
char **errmsg_fmt, **errmsg_arg;
int flags;
{
int (*func)() = (flags & PEXECUTE_SEARCH ? execvp : execv);
int pid;
int pdes[2];
int input_desc, output_desc;
int retries, sleep_interval;
/* Pipe waiting from last process, to be used as input for the next one.
Value is STDIN_FILE_NO if no pipe is waiting
(i.e. the next command is the first of a group). */
static int last_pipe_input;
/* If this is the first process, initialize. */
if (flags & PEXECUTE_FIRST)
last_pipe_input = STDIN_FILE_NO;
input_desc = last_pipe_input;
/* 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 (! (flags & PEXECUTE_LAST))
{
if (pipe (pdes) < 0)
{
*errmsg_fmt = "pipe";
*errmsg_arg = NULL;
return -1;
}
output_desc = pdes[WRITE_PORT];
last_pipe_input = pdes[READ_PORT];
}
else
{
/* Last process. */
output_desc = STDOUT_FILE_NO;
last_pipe_input = STDIN_FILE_NO;
}
/* Fork a subprocess; wait and retry if it fails. */
sleep_interval = 1;
pid = -1;
for (retries = 0; retries < 4; retries++)
{
pid = fork ();
if (pid >= 0)
break;
sleep (sleep_interval);
sleep_interval *= 2;
}
switch (pid)
{
case -1:
*errmsg_fmt = "fork";
*errmsg_arg = NULL;
return -1;
case 0: /* child */
/* Move the input and output pipes into place, if necessary. */
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);
fprintf (stderr, "%s: ", this_pname);
fprintf (stderr, install_error_msg, program);
fprintf (stderr, ": %s\n", xstrerror (errno));
_exit (-1);
/* NOTREACHED */
return 0;
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. */
return pid;
}
}
int
pwait (pid, status, flags)
int pid;
int *status;
int flags ATTRIBUTE_UNUSED;
{
/* ??? Here's an opportunity to canonicalize the values in STATUS.
Needed? */
#ifdef VMS
pid = waitpid (-1, status, 0);
#else
pid = wait (status);
#endif
return pid;
}
#endif /* ! __MSDOS__ && ! OS2 && ! MPW && ! (_WIN32 && ! _UWIN) */