* [fortran, patch] Implement EXECUTE_COMMAND_LINE
@ 2010-08-29 23:52 FX
2010-08-30 10:54 ` Tobias Burnus
0 siblings, 1 reply; 8+ messages in thread
From: FX @ 2010-08-29 23:52 UTC (permalink / raw)
To: Fortran List; +Cc: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 492 bytes --]
This is a respin of my patch last year (http://gcc.gnu.org/ml/fortran/2009-05/msg00044.html), with some more testing, a testcase and documentation.
Answering to Steve's review of last year:
* the asynchronous path is really asynchronous, because system() is called from the child process (which we never wait for)
* I noted in the doc that, because of the implementation, the child might ignore/block signals
Bootstrapped and regtesting on x86_64-darwin, OK to commit?
FX
[-- Attachment #2: exec.diff --]
[-- Type: application/octet-stream, Size: 17782 bytes --]
Index: gcc/fortran/intrinsic.c
===================================================================
--- gcc/fortran/intrinsic.c (revision 163620)
+++ gcc/fortran/intrinsic.c (working copy)
@@ -2798,6 +2798,15 @@
gfc_check_dtime_etime_sub, NULL, gfc_resolve_dtime_sub,
vl, BT_REAL, 4, REQUIRED, tm, BT_REAL, 4, REQUIRED);
+ add_sym_5s ("execute_command_line", GFC_ISYM_EXECUTE_COMMAND_LINE,
+ CLASS_IMPURE , BT_UNKNOWN, 0, GFC_STD_F2008,
+ NULL, NULL, gfc_resolve_execute_command_line,
+ "command", BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+ "wait", BT_LOGICAL, dl, OPTIONAL, INTENT_IN,
+ "exitstat", BT_INTEGER, di, OPTIONAL, INTENT_INOUT,
+ "cmdstat", BT_INTEGER, di, OPTIONAL, INTENT_OUT,
+ "cmdmsg", BT_CHARACTER, dc, OPTIONAL, INTENT_INOUT);
+
add_sym_1s ("fdate", GFC_ISYM_FDATE, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
gfc_check_fdate_sub, NULL, gfc_resolve_fdate_sub,
dt, BT_CHARACTER, dc, REQUIRED);
Index: gcc/fortran/intrinsic.h
===================================================================
--- gcc/fortran/intrinsic.h (revision 163620)
+++ gcc/fortran/intrinsic.h (working copy)
@@ -536,6 +536,7 @@
void gfc_resolve_chmod_sub (gfc_code *);
void gfc_resolve_cpu_time (gfc_code *);
void gfc_resolve_ctime_sub (gfc_code *);
+void gfc_resolve_execute_command_line (gfc_code *);
void gfc_resolve_exit (gfc_code *);
void gfc_resolve_fdate_sub (gfc_code *);
void gfc_resolve_flush (gfc_code *);
Index: gcc/fortran/gfortran.h
===================================================================
--- gcc/fortran/gfortran.h (revision 163620)
+++ gcc/fortran/gfortran.h (working copy)
@@ -362,6 +362,7 @@
GFC_ISYM_ERFC,
GFC_ISYM_ERFC_SCALED,
GFC_ISYM_ETIME,
+ GFC_ISYM_EXECUTE_COMMAND_LINE,
GFC_ISYM_EXIT,
GFC_ISYM_EXP,
GFC_ISYM_EXPONENT,
Index: gcc/fortran/iresolve.c
===================================================================
--- gcc/fortran/iresolve.c (revision 163620)
+++ gcc/fortran/iresolve.c (working copy)
@@ -3184,6 +3184,17 @@
}
+/* Resolve the EXECUTE_COMMAND_LINE intrinsic subroutine. */
+void
+gfc_resolve_execute_command_line (gfc_code *c)
+{
+ const char *name;
+ name = gfc_get_string (PREFIX ("execute_command_line_i%d"),
+ gfc_default_integer_kind);
+ c->resolved_sym = gfc_get_intrinsic_sub_symbol (name);
+}
+
+
/* Resolve the EXIT intrinsic subroutine. */
void
Index: intrinsic.texi
===================================================================
--- intrinsic.texi (revision 163620)
+++ intrinsic.texi (working copy)
@@ -104,6 +104,7 @@
* @code{ERFC}: ERFC, Complementary error function
* @code{ERFC_SCALED}: ERFC_SCALED, Exponentially-scaled complementary error function
* @code{ETIME}: ETIME, Execution time subroutine (or function)
+* @code{EXECUTE_COMMAND_LINE}: EXECUTE_COMMAND_LINE, Execute a shell command
* @code{EXIT}: EXIT, Exit the program with status.
* @code{EXP}: EXP, Exponential function
* @code{EXPONENT}: EXPONENT, Exponent function
@@ -3815,6 +3816,82 @@
+@node EXECUTE_COMMAND_LINE
+@section @code{EXECUTE_COMMAND_LINE} --- Execute a shell command
+@fnindex EXECUTE_COMMAND_LINE
+@cindex system, system call
+@cindex command line
+
+@table @asis
+@item @emph{Description}:
+@code{EXECUTE_COMMAND_LINE} runs a shell command, synchronously or
+asynchronously.
+
+The @code{COMMAND} argument is passed to the shell and executed, using
+the @code{system()} call. (The shell is @code{sh} on Unix systems, and
+@code{cmd.exe} on Windows.) If @code{WAIT} is present and has the value
+false, the execution of the command is asynchronous if the system
+supports it; otherwise, the command is executed synchronously.
+
+The three last arguments allow the user to get status information. After
+synchronous execution, @code{EXITSTAT} contains the integer exit code of
+the command, as returned by @code{system}. @code{CMDSTAT} is set to zero
+if the command line was executed (whatever its exit status was).
+@code{CMDMSG} is assigned an error message if an error has occurred.
+
+
+@item @emph{Standard}:
+Fortran 2008 and later
+
+@item @emph{Class}:
+Subroutine
+
+@item @emph{Syntax}:
+@code{CALL EXECUTE_COMMAND_LINE(COMMAND [, WAIT, EXITSTAT, CMDSTAT, CMDMSG ])}
+
+@item @emph{Arguments}:
+@multitable @columnfractions .15 .70
+@item @var{COMMAND} @tab Shall be a default @code{CHARACTER} scalar.
+@item @var{WAIT} @tab (Optional) Shall be a default @code{LOGICAL} scalar.
+@item @var{EXITSTAT} @tab (Optional) Shall be an @code{INTEGER} of the
+default kind.
+@item @var{CMDSTAT} @tab (Optional) Shall be an @code{INTEGER} of the
+default kind.
+@item @var{CMDMSG} @tab (Optional) Shall be an @code{CHARACTER} scalar of the
+default kind.
+@end multitable
+
+@item @emph{Example}:
+@smallexample
+program test_exec
+ integer :: i
+
+ call execute_command_line ("external_prog.exe", exitstat=i)
+ print *, "Exit status of external_prog.exe was ", i
+
+ call execute_command_line ("reindex_files.exe", wait=.false.)
+ print *, "Now reindexing files in the background"
+
+end program test_exec
+@end smallexample
+
+
+@item @emph{Note}:
+
+Because this intrinsic is implemented in terms of the @code{system()}
+function call, its behavior with respect to signalling is processor
+dependent. In particular, on POSIX-compliant systems, the SIGINT and
+SIGQUIT signals will be ignored, and the SIGCHLD will be blocked. As
+such, if the parent process is terminated, the child process might not be
+terminated alongside.
+
+
+@item @emph{See also}:
+@ref{SYSTEM}
+@end table
+
+
+
@node EXIT
@section @code{EXIT} --- Exit the program with status.
@fnindex EXIT
Index: libgfortran/Makefile.in
===================================================================
--- libgfortran/Makefile.in (revision 163620)
+++ libgfortran/Makefile.in (working copy)
@@ -225,12 +225,12 @@
am__objects_39 = associated.lo abort.lo access.lo args.lo \
bit_intrinsics.lo c99_functions.lo chdir.lo chmod.lo clock.lo \
cpu_time.lo cshift0.lo ctime.lo date_and_time.lo dtime.lo \
- env.lo eoshift0.lo eoshift2.lo erfc_scaled.lo etime.lo exit.lo \
- extends_type_of.lo fnum.lo gerror.lo getcwd.lo getlog.lo \
- getXid.lo hostnm.lo ierrno.lo ishftc.lo \
- iso_c_generated_procs.lo iso_c_binding.lo kill.lo link.lo \
- malloc.lo mvbits.lo move_alloc.lo pack_generic.lo perror.lo \
- selected_char_kind.lo signal.lo size.lo sleep.lo \
+ env.lo eoshift0.lo eoshift2.lo erfc_scaled.lo etime.lo \
+ execute_command_line.lo exit.lo extends_type_of.lo fnum.lo \
+ gerror.lo getcwd.lo getlog.lo getXid.lo hostnm.lo ierrno.lo \
+ ishftc.lo iso_c_generated_procs.lo iso_c_binding.lo kill.lo \
+ link.lo malloc.lo mvbits.lo move_alloc.lo pack_generic.lo \
+ perror.lo selected_char_kind.lo signal.lo size.lo sleep.lo \
spread_generic.lo string_intrinsics.lo system.lo rand.lo \
random.lo rename.lo reshape_generic.lo reshape_packed.lo \
selected_int_kind.lo selected_real_kind.lo stat.lo symlnk.lo \
@@ -522,6 +522,7 @@
intrinsics/eoshift2.c \
intrinsics/erfc_scaled.c \
intrinsics/etime.c \
+intrinsics/execute_command_line.c \
intrinsics/exit.c \
intrinsics/extends_type_of.c \
intrinsics/fnum.c \
@@ -1404,6 +1405,7 @@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/erfc_scaled.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etime.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/execute_command_line.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exit.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exponent_r10.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exponent_r16.Plo@am__quote@
@@ -5089,6 +5091,13 @@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o etime.lo `test -f 'intrinsics/etime.c' || echo '$(srcdir)/'`intrinsics/etime.c
+execute_command_line.lo: intrinsics/execute_command_line.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT execute_command_line.lo -MD -MP -MF $(DEPDIR)/execute_command_line.Tpo -c -o execute_command_line.lo `test -f 'intrinsics/execute_command_line.c' || echo '$(srcdir)/'`intrinsics/execute_command_line.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/execute_command_line.Tpo $(DEPDIR)/execute_command_line.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/execute_command_line.c' object='execute_command_line.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o execute_command_line.lo `test -f 'intrinsics/execute_command_line.c' || echo '$(srcdir)/'`intrinsics/execute_command_line.c
+
exit.lo: intrinsics/exit.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT exit.lo -MD -MP -MF $(DEPDIR)/exit.Tpo -c -o exit.lo `test -f 'intrinsics/exit.c' || echo '$(srcdir)/'`intrinsics/exit.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/exit.Tpo $(DEPDIR)/exit.Plo
Index: libgfortran/intrinsics/execute_command_line.c
===================================================================
--- libgfortran/intrinsics/execute_command_line.c (revision 0)
+++ libgfortran/intrinsics/execute_command_line.c (revision 0)
@@ -0,0 +1,164 @@
+/* Implementation of the EXECUTE_COMMAND_LINE intrinsic.
+ Copyright (C) 2009 Free Software Foundation, Inc.
+ Contributed by François-Xavier Coudert.
+
+This file is part of the GNU Fortran runtime library (libgfortran).
+
+Libgfortran 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 3, or (at your option) any later
+version.
+
+Libgfortran 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#include "libgfortran.h"
+#include <string.h>
+#include <stdbool.h>
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+
+enum { EXEC_NOERROR = 0, EXEC_SYSTEMFAILED };
+static const char *cmdmsg_values[] =
+ { "", "Execution of child process impossible" };
+
+static void
+execute_command_line (const char *command, bool wait, int *exitstat,
+ int *cmdstat, char *cmdmsg,
+ gfc_charlen_type command_len,
+ gfc_charlen_type cmdmsg_len)
+{
+ /* Transform the Fortran string to a C string. */
+ char cmd[command_len + 1];
+ memcpy (cmd, command, command_len);
+ cmd[command_len] = '\0';
+
+ /* Flush all I/O units before executing the command. */
+ flush_all_units();
+
+#if defined(HAVE_FORK)
+ if (!wait)
+ {
+ /* Asynchronous execution. */
+ pid_t pid;
+
+ *cmdstat = 0;
+ if ((pid = fork()) < 0)
+ *cmdstat = EXEC_SYSTEMFAILED;
+ else if (pid == 0)
+ {
+ /* Child process. */
+ int res = system (cmd);
+ _exit (WIFEXITED(res) ? WEXITSTATUS(res) : res);
+ }
+ }
+ else
+#endif
+ {
+ /* Synchronous execution. */
+ int res = system (cmd);
+
+ if (!wait)
+ *cmdstat = -2;
+ else if (res == -1)
+ *cmdstat = EXEC_SYSTEMFAILED;
+ else
+ {
+ *cmdstat = 0;
+#if defined(WEXITSTATUS) && defined(WIFEXITED)
+ *exitstat = WIFEXITED(res) ? WEXITSTATUS(res) : res;
+#else
+ *exitstat = res;
+#endif
+ }
+ }
+
+ /* Now copy back to the Fortran string if needed. */
+ if (*cmdstat > 0)
+ {
+ if (cmdmsg)
+ fstrcpy (cmdmsg, cmdmsg_len, cmdmsg_values[*cmdstat],
+ strlen (cmdmsg_values[*cmdstat]));
+ else
+ runtime_error ("Failure in EXECUTE_COMMAND_LINE: %s",
+ cmdmsg_values[*cmdstat]);
+ }
+}
+
+
+extern void
+execute_command_line_i4 (const char *command, GFC_LOGICAL_4 *wait,
+ GFC_INTEGER_4 *exitstat, GFC_INTEGER_4 *cmdstat,
+ char *cmdmsg, gfc_charlen_type command_len,
+ gfc_charlen_type cmdmsg_len);
+export_proto(execute_command_line_i4);
+
+void
+execute_command_line_i4 (const char *command, GFC_LOGICAL_4 *wait,
+ GFC_INTEGER_4 *exitstat, GFC_INTEGER_4 *cmdstat,
+ char *cmdmsg, gfc_charlen_type command_len,
+ gfc_charlen_type cmdmsg_len)
+{
+ bool w = wait ? *wait : true;
+ int estat, estat_initial, cstat;
+
+ if (exitstat)
+ estat_initial = estat = *exitstat;
+
+ execute_command_line (command, w, &estat, &cstat, cmdmsg, command_len,
+ cmdmsg_len);
+
+ if (exitstat && estat != estat_initial)
+ *exitstat = estat;
+ if (cmdstat)
+ *cmdstat = cstat;
+}
+
+
+extern void
+execute_command_line_i8 (const char *command, GFC_LOGICAL_8 *wait,
+ GFC_INTEGER_8 *exitstat, GFC_INTEGER_8 *cmdstat,
+ char *cmdmsg, gfc_charlen_type command_len,
+ gfc_charlen_type cmdmsg_len);
+export_proto(execute_command_line_i8);
+
+void
+execute_command_line_i8 (const char *command, GFC_LOGICAL_8 *wait,
+ GFC_INTEGER_8 *exitstat, GFC_INTEGER_8 *cmdstat,
+ char *cmdmsg, gfc_charlen_type command_len,
+ gfc_charlen_type cmdmsg_len)
+{
+ bool w = wait ? *wait : true;
+ int estat, estat_initial, cstat;
+
+ if (exitstat)
+ estat_initial = estat = *exitstat;
+
+ execute_command_line (command, w, &estat, &cstat, cmdmsg, command_len,
+ cmdmsg_len);
+
+ if (exitstat && estat != estat_initial)
+ *exitstat = estat;
+ if (cmdstat)
+ *cmdstat = cstat;
+}
Index: libgfortran/gfortran.map
===================================================================
--- libgfortran/gfortran.map (revision 163620)
+++ libgfortran/gfortran.map (working copy)
@@ -1069,6 +1069,8 @@
_gfortran_erfc_scaled_r16;
_gfortran_erfc_scaled_r4;
_gfortran_erfc_scaled_r8;
+ _gfortran_execute_command_line_i4;
+ _gfortran_execute_command_line_i8;
_gfortran_pack_char4;
_gfortran_pack_s_char4;
_gfortran_reshape_char4;
Index: libgfortran/Makefile.am
===================================================================
--- libgfortran/Makefile.am (revision 163620)
+++ libgfortran/Makefile.am (working copy)
@@ -102,6 +102,7 @@
intrinsics/eoshift2.c \
intrinsics/erfc_scaled.c \
intrinsics/etime.c \
+intrinsics/execute_command_line.c \
intrinsics/exit.c \
intrinsics/extends_type_of.c \
intrinsics/fnum.c \
Index: gcc/testsuite/gfortran.dg/execute_command_line_1.f90
===================================================================
--- gcc/testsuite/gfortran.dg/execute_command_line_1.f90 (revision 0)
+++ gcc/testsuite/gfortran.dg/execute_command_line_1.f90 (revision 0)
@@ -0,0 +1,60 @@
+! { dg-do compile }
+!
+! Check that we accept all variants of the EXECUTE_COMMAND_LINE intrinsic.
+!
+ integer :: i, j
+ character(len=100) :: s
+
+ s = ""
+
+ call execute_command_line ("ls *.f90")
+
+ print *, "-----------------------------"
+
+ call execute_command_line ("sleep 1 ; ls *.f90", .false.)
+ print *, "I'm not waiting"
+ call sleep(2)
+
+ print *, "-----------------------------"
+
+ call execute_command_line ("sleep 1 ; ls *.f90", .true.)
+ print *, "I did wait"
+ call sleep(2)
+
+ print *, "-----------------------------"
+
+ call execute_command_line ("ls *.f90", .true., i)
+ print *, "Exist status was: ", i
+
+ print *, "-----------------------------"
+
+ call execute_command_line ("ls *.doesnotexist", .true., i)
+ print *, "Exist status was: ", i
+
+ print *, "-----------------------------"
+
+ call execute_command_line ("echo foo", .true., i, j)
+ print *, "Exist status was: ", i
+ print *, "Command status was: ", j
+
+ print *, "-----------------------------"
+
+ call execute_command_line ("echo foo", .true., i, j, s)
+ print *, "Exist status was: ", i
+ print *, "Command status was: ", j
+ print *, "Error message is: ", trim(s)
+
+ print *, "-----------------------------"
+
+ call execute_command_line ("ls *.doesnotexist", .true., i, j, s)
+ print *, "Exist status was: ", i
+ print *, "Command status was: ", j
+ print *, "Error message is: ", trim(s)
+
+ print *, "-----------------------------"
+
+ call execute_command_line ("sleep 20", .false.)
+ print *, "Please kill me with ^C"
+ call sleep (10)
+
+ end
[-- Attachment #3: exec.ChangeLog --]
[-- Type: application/octet-stream, Size: 775 bytes --]
2010-08-29 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
* intrinsic.c: Add EXECUTE_COMMAND_LINE intrinsic.
* intrinsic.h (gfc_resolve_execute_command_line): New function.
* iresolve.c (gfc_resolve_execute_command_line): New function.
* gfortran.h (GFC_ISYM_EXECUTE_COMMAND_LINE): New value.
* intrinsic.texi: Document EXECUTE_COMMAND_LINE.
2010-08-29 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
* intrinsics/execute_command_line.c: New file.
* gfortran.map (_gfortran_execute_command_line_i4,
_gfortran_execute_command_line_i8): New symbols.
* Makefile.am: Add new file intrinsics/execute_command_line.c.
* Makefile.in: Regenerated.
2010-08-29 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
* gfortran.dg/execute_command_line_1.f90: New test.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [fortran, patch] Implement EXECUTE_COMMAND_LINE
2010-08-29 23:52 [fortran, patch] Implement EXECUTE_COMMAND_LINE FX
@ 2010-08-30 10:54 ` Tobias Burnus
2010-08-30 11:38 ` FX
0 siblings, 1 reply; 8+ messages in thread
From: Tobias Burnus @ 2010-08-30 10:54 UTC (permalink / raw)
To: FX; +Cc: Fortran List, gcc-patches
On 08/29/2010 11:13 PM, FX wrote:
> This is a respin of my patch last year (http://gcc.gnu.org/ml/fortran/2009-05/msg00044.html), with some more testing, a testcase and documentation.
>
> Bootstrapped and regtesting on x86_64-darwin, OK to commit?
Please add a @ref to SYSTEM, pointing to the new intrinsic; maybe one
should also recommend there to use the F2008 intrinsics (similarly to
GETARG/IARGC).
+The @code{COMMAND} argument is passed to the shell and executed, using
+the @code{system()} call. (The shell is @code{sh} on Unix systems, and
I wonder whether one should add a qualifier before "system", e.g. "the
POSIX's system call" or the C library's system call" to make clear that
it is not Fortran's SYSTEM call.
+ char cmd[command_len + 1];
Welcome in the world of C99's VLA :-)
+execute_command_line (const char *command, bool wait, int *exitstat,
Using 'bool wait' instead of "bool *wait" looks wrong. I think you need
either use "*bool" or something like
set_attr_value (5, false, true, false, false, false);
(or shorter: set_attr_value (2, false, true))
+#if defined(HAVE_FORK)
+ if (!wait)
+ *cmdstat = 0;
+ if ((pid = fork())< 0)
+ *cmdstat = EXEC_SYSTEMFAILED;
That won't work if cmdstat is not available. As F2008 states:
"If a condition occurs that would assign a nonzero value to CMDSTAT but
the CMDSTAT variable is not present, error termination is initiated."
+ /* Synchronous execution. */
+ int res = system (cmd);
+
+ if (!wait)
+ *cmdstat = -2;
Ditto for the cmdstat/exitstat. Additionally, I read the standard such
that the intrinsic immediately returns with cmdstat = -2 if HAVE_FORK is
false - not after the synchronous execution. However, I think the
standard is not unambiguous.
Tobias
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [fortran, patch] Implement EXECUTE_COMMAND_LINE
2010-08-30 10:54 ` Tobias Burnus
@ 2010-08-30 11:38 ` FX
2010-08-30 12:28 ` [fortran, patch] Dependencies for frontend-passes.c FX
2010-09-01 6:55 ` [fortran, patch] Implement EXECUTE_COMMAND_LINE Tobias Burnus
0 siblings, 2 replies; 8+ messages in thread
From: FX @ 2010-08-30 11:38 UTC (permalink / raw)
To: Tobias Burnus; +Cc: Fortran List, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 2586 bytes --]
> Please add a @ref to SYSTEM, pointing to the new intrinsic; maybe one should also recommend there to use the F2008 intrinsics (similarly to GETARG/IARGC).
OK.
> +The @code{COMMAND} argument is passed to the shell and executed, using
> +the @code{system()} call. (The shell is @code{sh} on Unix systems, and
>
> I wonder whether one should add a qualifier before "system", e.g. "the POSIX's system call" or the C library's system call" to make clear that it is not Fortran's SYSTEM call.
I changed to "the C library's system() call".
> +execute_command_line (const char *command, bool wait, int *exitstat,
>
> Using 'bool wait' instead of "bool *wait" looks wrong.
No call to execute_command_line is emitted directly by the front-end. The library's entry points are execute_command_line_i4 and execute_command_line_i8, which in turn call execute_command_line(). They take care of this and other issues as absent optional arguments (CMDSTAT and EXITSTAT).
> set_attr_value (5, false, true, false, false, false);
> (or shorter: set_attr_value (2, false, true))
Whow, that's new, and that's neat!
> +#if defined(HAVE_FORK)
> + if (!wait)
> + *cmdstat = 0;
> + if ((pid = fork())< 0)
> + *cmdstat = EXEC_SYSTEMFAILED;
>
> That won't work if cmdstat is not available. As F2008 states:
>
> "If a condition occurs that would assign a nonzero value to CMDSTAT but the CMDSTAT variable is not present, error termination is initiated."
I missed that sentence, thanks for pointing it out.
> + /* Synchronous execution. */
> + int res = system (cmd);
> +
> + if (!wait)
> + *cmdstat = -2;
>
>
> Ditto for the cmdstat/exitstat. Additionally, I read the standard such that the intrinsic immediately returns with cmdstat = -2 if HAVE_FORK is false - not after the synchronous execution. However, I think the standard is not unambiguous.
I agree with you that it's ambiguous, but I think the answer is in the definition of the WAIT argument: "If WAIT is present with the value false, and the processor supports asynchronous execution of the command, the command is executed asynchronously; otherwise it is executed synchronously."
I think that part is unambiguous: WAIT = .true. and !HAVE_FORK falls into the "otherwise": the command is actually executed.
I have two testsuite failures on x86_64-darwin: trim_optimize_1.f90 and widechar_intrinsics_5.f90. I don't know how they could possibly be related, but my baseline testsuite run is still running.
OK to commit if regtest completes OK?
FX
[-- Attachment #2: exec_2.ChangeLog --]
[-- Type: application/octet-stream, Size: 775 bytes --]
2010-08-30 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
* intrinsic.c: Add EXECUTE_COMMAND_LINE intrinsic.
* intrinsic.h (gfc_resolve_execute_command_line): New function.
* iresolve.c (gfc_resolve_execute_command_line): New function.
* gfortran.h (GFC_ISYM_EXECUTE_COMMAND_LINE): New value.
* intrinsic.texi: Document EXECUTE_COMMAND_LINE.
2010-08-30 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
* intrinsics/execute_command_line.c: New file.
* gfortran.map (_gfortran_execute_command_line_i4,
_gfortran_execute_command_line_i8): New symbols.
* Makefile.am: Add new file intrinsics/execute_command_line.c.
* Makefile.in: Regenerated.
2010-08-30 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
* gfortran.dg/execute_command_line_1.f90: New test.
[-- Attachment #3: exec_2.diff --]
[-- Type: application/octet-stream, Size: 18357 bytes --]
Index: gcc/fortran/intrinsic.c
===================================================================
--- gcc/fortran/intrinsic.c (revision 163620)
+++ gcc/fortran/intrinsic.c (working copy)
@@ -2798,6 +2798,15 @@
gfc_check_dtime_etime_sub, NULL, gfc_resolve_dtime_sub,
vl, BT_REAL, 4, REQUIRED, tm, BT_REAL, 4, REQUIRED);
+ add_sym_5s ("execute_command_line", GFC_ISYM_EXECUTE_COMMAND_LINE,
+ CLASS_IMPURE , BT_UNKNOWN, 0, GFC_STD_F2008,
+ NULL, NULL, gfc_resolve_execute_command_line,
+ "command", BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+ "wait", BT_LOGICAL, dl, OPTIONAL, INTENT_IN,
+ "exitstat", BT_INTEGER, di, OPTIONAL, INTENT_INOUT,
+ "cmdstat", BT_INTEGER, di, OPTIONAL, INTENT_OUT,
+ "cmdmsg", BT_CHARACTER, dc, OPTIONAL, INTENT_INOUT);
+
add_sym_1s ("fdate", GFC_ISYM_FDATE, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
gfc_check_fdate_sub, NULL, gfc_resolve_fdate_sub,
dt, BT_CHARACTER, dc, REQUIRED);
Index: gcc/fortran/intrinsic.h
===================================================================
--- gcc/fortran/intrinsic.h (revision 163620)
+++ gcc/fortran/intrinsic.h (working copy)
@@ -536,6 +536,7 @@
void gfc_resolve_chmod_sub (gfc_code *);
void gfc_resolve_cpu_time (gfc_code *);
void gfc_resolve_ctime_sub (gfc_code *);
+void gfc_resolve_execute_command_line (gfc_code *);
void gfc_resolve_exit (gfc_code *);
void gfc_resolve_fdate_sub (gfc_code *);
void gfc_resolve_flush (gfc_code *);
Index: gcc/fortran/gfortran.h
===================================================================
--- gcc/fortran/gfortran.h (revision 163620)
+++ gcc/fortran/gfortran.h (working copy)
@@ -362,6 +362,7 @@
GFC_ISYM_ERFC,
GFC_ISYM_ERFC_SCALED,
GFC_ISYM_ETIME,
+ GFC_ISYM_EXECUTE_COMMAND_LINE,
GFC_ISYM_EXIT,
GFC_ISYM_EXP,
GFC_ISYM_EXPONENT,
Index: gcc/fortran/iresolve.c
===================================================================
--- gcc/fortran/iresolve.c (revision 163620)
+++ gcc/fortran/iresolve.c (working copy)
@@ -3184,6 +3184,17 @@
}
+/* Resolve the EXECUTE_COMMAND_LINE intrinsic subroutine. */
+void
+gfc_resolve_execute_command_line (gfc_code *c)
+{
+ const char *name;
+ name = gfc_get_string (PREFIX ("execute_command_line_i%d"),
+ gfc_default_integer_kind);
+ c->resolved_sym = gfc_get_intrinsic_sub_symbol (name);
+}
+
+
/* Resolve the EXIT intrinsic subroutine. */
void
Index: gcc/fortran/intrinsic.texi
===================================================================
--- gcc/fortran/intrinsic.texi (revision 163620)
+++ gcc/fortran/intrinsic.texi (working copy)
@@ -104,6 +104,7 @@
* @code{ERFC}: ERFC, Complementary error function
* @code{ERFC_SCALED}: ERFC_SCALED, Exponentially-scaled complementary error function
* @code{ETIME}: ETIME, Execution time subroutine (or function)
+* @code{EXECUTE_COMMAND_LINE}: EXECUTE_COMMAND_LINE, Execute a shell command
* @code{EXIT}: EXIT, Exit the program with status.
* @code{EXP}: EXP, Exponential function
* @code{EXPONENT}: EXPONENT, Exponent function
@@ -3815,6 +3816,82 @@
+@node EXECUTE_COMMAND_LINE
+@section @code{EXECUTE_COMMAND_LINE} --- Execute a shell command
+@fnindex EXECUTE_COMMAND_LINE
+@cindex system, system call
+@cindex command line
+
+@table @asis
+@item @emph{Description}:
+@code{EXECUTE_COMMAND_LINE} runs a shell command, synchronously or
+asynchronously.
+
+The @code{COMMAND} argument is passed to the shell and executed, using
+the C library's @code{system()} call. (The shell is @code{sh} on Unix
+systems, and @code{cmd.exe} on Windows.) If @code{WAIT} is present and
+has the value false, the execution of the command is asynchronous if the
+system supports it; otherwise, the command is executed synchronously.
+
+The three last arguments allow the user to get status information. After
+synchronous execution, @code{EXITSTAT} contains the integer exit code of
+the command, as returned by @code{system}. @code{CMDSTAT} is set to zero
+if the command line was executed (whatever its exit status was).
+@code{CMDMSG} is assigned an error message if an error has occurred.
+
+
+@item @emph{Standard}:
+Fortran 2008 and later
+
+@item @emph{Class}:
+Subroutine
+
+@item @emph{Syntax}:
+@code{CALL EXECUTE_COMMAND_LINE(COMMAND [, WAIT, EXITSTAT, CMDSTAT, CMDMSG ])}
+
+@item @emph{Arguments}:
+@multitable @columnfractions .15 .70
+@item @var{COMMAND} @tab Shall be a default @code{CHARACTER} scalar.
+@item @var{WAIT} @tab (Optional) Shall be a default @code{LOGICAL} scalar.
+@item @var{EXITSTAT} @tab (Optional) Shall be an @code{INTEGER} of the
+default kind.
+@item @var{CMDSTAT} @tab (Optional) Shall be an @code{INTEGER} of the
+default kind.
+@item @var{CMDMSG} @tab (Optional) Shall be an @code{CHARACTER} scalar of the
+default kind.
+@end multitable
+
+@item @emph{Example}:
+@smallexample
+program test_exec
+ integer :: i
+
+ call execute_command_line ("external_prog.exe", exitstat=i)
+ print *, "Exit status of external_prog.exe was ", i
+
+ call execute_command_line ("reindex_files.exe", wait=.false.)
+ print *, "Now reindexing files in the background"
+
+end program test_exec
+@end smallexample
+
+
+@item @emph{Note}:
+
+Because this intrinsic is implemented in terms of the @code{system()}
+function call, its behavior with respect to signalling is processor
+dependent. In particular, on POSIX-compliant systems, the SIGINT and
+SIGQUIT signals will be ignored, and the SIGCHLD will be blocked. As
+such, if the parent process is terminated, the child process might not be
+terminated alongside.
+
+
+@item @emph{See also}:
+@ref{SYSTEM}
+@end table
+
+
+
@node EXIT
@section @code{EXIT} --- Exit the program with status.
@fnindex EXIT
@@ -10864,6 +10941,8 @@
@end multitable
@item @emph{See also}:
+@ref{EXECUTE_COMMAND_LINE}, which is part of the Fortran 2008 standard
+and should considered in new code for future portability.
@end table
Index: gcc/testsuite/gfortran.dg/execute_command_line_1.f90
===================================================================
--- gcc/testsuite/gfortran.dg/execute_command_line_1.f90 (revision 0)
+++ gcc/testsuite/gfortran.dg/execute_command_line_1.f90 (revision 0)
@@ -0,0 +1,60 @@
+! { dg-do compile }
+!
+! Check that we accept all variants of the EXECUTE_COMMAND_LINE intrinsic.
+!
+ integer :: i, j
+ character(len=100) :: s
+
+ s = ""
+
+ call execute_command_line ("ls *.f90")
+
+ print *, "-----------------------------"
+
+ call execute_command_line ("sleep 1 ; ls *.f90", .false.)
+ print *, "I'm not waiting"
+ call sleep(2)
+
+ print *, "-----------------------------"
+
+ call execute_command_line ("sleep 1 ; ls *.f90", .true.)
+ print *, "I did wait"
+ call sleep(2)
+
+ print *, "-----------------------------"
+
+ call execute_command_line ("ls *.f90", .true., i)
+ print *, "Exist status was: ", i
+
+ print *, "-----------------------------"
+
+ call execute_command_line ("ls *.doesnotexist", .true., i)
+ print *, "Exist status was: ", i
+
+ print *, "-----------------------------"
+
+ call execute_command_line ("echo foo", .true., i, j)
+ print *, "Exist status was: ", i
+ print *, "Command status was: ", j
+
+ print *, "-----------------------------"
+
+ call execute_command_line ("echo foo", .true., i, j, s)
+ print *, "Exist status was: ", i
+ print *, "Command status was: ", j
+ print *, "Error message is: ", trim(s)
+
+ print *, "-----------------------------"
+
+ call execute_command_line ("ls *.doesnotexist", .true., i, j, s)
+ print *, "Exist status was: ", i
+ print *, "Command status was: ", j
+ print *, "Error message is: ", trim(s)
+
+ print *, "-----------------------------"
+
+ call execute_command_line ("sleep 20", .false.)
+ print *, "Please kill me with ^C"
+ call sleep (10)
+
+ end
Index: libgfortran/intrinsics/execute_command_line.c
===================================================================
--- libgfortran/intrinsics/execute_command_line.c (revision 0)
+++ libgfortran/intrinsics/execute_command_line.c (revision 0)
@@ -0,0 +1,177 @@
+/* Implementation of the EXECUTE_COMMAND_LINE intrinsic.
+ Copyright (C) 2009 Free Software Foundation, Inc.
+ Contributed by François-Xavier Coudert.
+
+This file is part of the GNU Fortran runtime library (libgfortran).
+
+Libgfortran 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 3, or (at your option) any later
+version.
+
+Libgfortran 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#include "libgfortran.h"
+#include <string.h>
+#include <stdbool.h>
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+
+enum { EXEC_NOERROR = 0, EXEC_SYSTEMFAILED };
+static const char *cmdmsg_values[] =
+ { "", "Execution of child process impossible" };
+
+
+
+static void
+set_cmdstat (int *cmdstat, int value)
+{
+ if (cmdstat)
+ *cmdstat = value;
+ else if (value != 0)
+ runtime_error ("Could not execute command line");
+}
+
+
+static void
+execute_command_line (const char *command, bool wait, int *exitstat,
+ int *cmdstat, char *cmdmsg,
+ gfc_charlen_type command_len,
+ gfc_charlen_type cmdmsg_len)
+{
+ /* Transform the Fortran string to a C string. */
+ char cmd[command_len + 1];
+ memcpy (cmd, command, command_len);
+ cmd[command_len] = '\0';
+
+ /* Flush all I/O units before executing the command. */
+ flush_all_units();
+
+#if defined(HAVE_FORK)
+ if (!wait)
+ {
+ /* Asynchronous execution. */
+ pid_t pid;
+
+ set_cmdstat (cmdstat, 0);
+
+ if ((pid = fork()) < 0)
+ set_cmdstat (cmdstat, EXEC_SYSTEMFAILED);
+ else if (pid == 0)
+ {
+ /* Child process. */
+ int res = system (cmd);
+ _exit (WIFEXITED(res) ? WEXITSTATUS(res) : res);
+ }
+ }
+ else
+#endif
+ {
+ /* Synchronous execution. */
+ int res = system (cmd);
+
+ if (!wait)
+ set_cmdstat (cmdstat, -2);
+ else if (res == -1)
+ set_cmdstat (cmdstat, EXEC_SYSTEMFAILED);
+ else
+ {
+ set_cmdstat (cmdstat, 0);
+#if defined(WEXITSTATUS) && defined(WIFEXITED)
+ *exitstat = WIFEXITED(res) ? WEXITSTATUS(res) : res;
+#else
+ *exitstat = res;
+#endif
+ }
+ }
+
+ /* Now copy back to the Fortran string if needed. */
+ if (cmdstat && *cmdstat > 0)
+ {
+ if (cmdmsg)
+ fstrcpy (cmdmsg, cmdmsg_len, cmdmsg_values[*cmdstat],
+ strlen (cmdmsg_values[*cmdstat]));
+ else
+ runtime_error ("Failure in EXECUTE_COMMAND_LINE: %s",
+ cmdmsg_values[*cmdstat]);
+ }
+}
+
+
+extern void
+execute_command_line_i4 (const char *command, GFC_LOGICAL_4 *wait,
+ GFC_INTEGER_4 *exitstat, GFC_INTEGER_4 *cmdstat,
+ char *cmdmsg, gfc_charlen_type command_len,
+ gfc_charlen_type cmdmsg_len);
+export_proto(execute_command_line_i4);
+
+void
+execute_command_line_i4 (const char *command, GFC_LOGICAL_4 *wait,
+ GFC_INTEGER_4 *exitstat, GFC_INTEGER_4 *cmdstat,
+ char *cmdmsg, gfc_charlen_type command_len,
+ gfc_charlen_type cmdmsg_len)
+{
+ bool w = wait ? *wait : true;
+ int estat, estat_initial, cstat;
+
+ if (exitstat)
+ estat_initial = estat = *exitstat;
+
+ execute_command_line (command, w, &estat, cmdstat ? &cstat : NULL,
+ cmdmsg, command_len, cmdmsg_len);
+
+ if (exitstat && estat != estat_initial)
+ *exitstat = estat;
+ if (cmdstat)
+ *cmdstat = cstat;
+}
+
+
+extern void
+execute_command_line_i8 (const char *command, GFC_LOGICAL_8 *wait,
+ GFC_INTEGER_8 *exitstat, GFC_INTEGER_8 *cmdstat,
+ char *cmdmsg, gfc_charlen_type command_len,
+ gfc_charlen_type cmdmsg_len);
+export_proto(execute_command_line_i8);
+
+void
+execute_command_line_i8 (const char *command, GFC_LOGICAL_8 *wait,
+ GFC_INTEGER_8 *exitstat, GFC_INTEGER_8 *cmdstat,
+ char *cmdmsg, gfc_charlen_type command_len,
+ gfc_charlen_type cmdmsg_len)
+{
+ bool w = wait ? *wait : true;
+ int estat, estat_initial, cstat;
+
+ if (exitstat)
+ estat_initial = estat = *exitstat;
+
+ execute_command_line (command, w, &estat, cmdstat ? &cstat : NULL,
+ cmdmsg, command_len, cmdmsg_len);
+
+ if (exitstat && estat != estat_initial)
+ *exitstat = estat;
+ if (cmdstat)
+ *cmdstat = cstat;
+}
Index: libgfortran/gfortran.map
===================================================================
--- libgfortran/gfortran.map (revision 163620)
+++ libgfortran/gfortran.map (working copy)
@@ -1069,6 +1069,8 @@
_gfortran_erfc_scaled_r16;
_gfortran_erfc_scaled_r4;
_gfortran_erfc_scaled_r8;
+ _gfortran_execute_command_line_i4;
+ _gfortran_execute_command_line_i8;
_gfortran_pack_char4;
_gfortran_pack_s_char4;
_gfortran_reshape_char4;
Index: libgfortran/Makefile.am
===================================================================
--- libgfortran/Makefile.am (revision 163620)
+++ libgfortran/Makefile.am (working copy)
@@ -102,6 +102,7 @@
intrinsics/eoshift2.c \
intrinsics/erfc_scaled.c \
intrinsics/etime.c \
+intrinsics/execute_command_line.c \
intrinsics/exit.c \
intrinsics/extends_type_of.c \
intrinsics/fnum.c \
Index: libgfortran/Makefile.in
===================================================================
--- libgfortran/Makefile.in (revision 163620)
+++ libgfortran/Makefile.in (working copy)
@@ -225,12 +225,12 @@
am__objects_39 = associated.lo abort.lo access.lo args.lo \
bit_intrinsics.lo c99_functions.lo chdir.lo chmod.lo clock.lo \
cpu_time.lo cshift0.lo ctime.lo date_and_time.lo dtime.lo \
- env.lo eoshift0.lo eoshift2.lo erfc_scaled.lo etime.lo exit.lo \
- extends_type_of.lo fnum.lo gerror.lo getcwd.lo getlog.lo \
- getXid.lo hostnm.lo ierrno.lo ishftc.lo \
- iso_c_generated_procs.lo iso_c_binding.lo kill.lo link.lo \
- malloc.lo mvbits.lo move_alloc.lo pack_generic.lo perror.lo \
- selected_char_kind.lo signal.lo size.lo sleep.lo \
+ env.lo eoshift0.lo eoshift2.lo erfc_scaled.lo etime.lo \
+ execute_command_line.lo exit.lo extends_type_of.lo fnum.lo \
+ gerror.lo getcwd.lo getlog.lo getXid.lo hostnm.lo ierrno.lo \
+ ishftc.lo iso_c_generated_procs.lo iso_c_binding.lo kill.lo \
+ link.lo malloc.lo mvbits.lo move_alloc.lo pack_generic.lo \
+ perror.lo selected_char_kind.lo signal.lo size.lo sleep.lo \
spread_generic.lo string_intrinsics.lo system.lo rand.lo \
random.lo rename.lo reshape_generic.lo reshape_packed.lo \
selected_int_kind.lo selected_real_kind.lo stat.lo symlnk.lo \
@@ -522,6 +522,7 @@
intrinsics/eoshift2.c \
intrinsics/erfc_scaled.c \
intrinsics/etime.c \
+intrinsics/execute_command_line.c \
intrinsics/exit.c \
intrinsics/extends_type_of.c \
intrinsics/fnum.c \
@@ -1404,6 +1405,7 @@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/erfc_scaled.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etime.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/execute_command_line.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exit.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exponent_r10.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exponent_r16.Plo@am__quote@
@@ -5089,6 +5091,13 @@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o etime.lo `test -f 'intrinsics/etime.c' || echo '$(srcdir)/'`intrinsics/etime.c
+execute_command_line.lo: intrinsics/execute_command_line.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT execute_command_line.lo -MD -MP -MF $(DEPDIR)/execute_command_line.Tpo -c -o execute_command_line.lo `test -f 'intrinsics/execute_command_line.c' || echo '$(srcdir)/'`intrinsics/execute_command_line.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/execute_command_line.Tpo $(DEPDIR)/execute_command_line.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/execute_command_line.c' object='execute_command_line.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o execute_command_line.lo `test -f 'intrinsics/execute_command_line.c' || echo '$(srcdir)/'`intrinsics/execute_command_line.c
+
exit.lo: intrinsics/exit.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT exit.lo -MD -MP -MF $(DEPDIR)/exit.Tpo -c -o exit.lo `test -f 'intrinsics/exit.c' || echo '$(srcdir)/'`intrinsics/exit.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/exit.Tpo $(DEPDIR)/exit.Plo
^ permalink raw reply [flat|nested] 8+ messages in thread
* [fortran, patch] Dependencies for frontend-passes.c
2010-08-30 11:38 ` FX
@ 2010-08-30 12:28 ` FX
2010-08-30 13:21 ` Tobias Burnus
2010-09-01 6:55 ` [fortran, patch] Implement EXECUTE_COMMAND_LINE Tobias Burnus
1 sibling, 1 reply; 8+ messages in thread
From: FX @ 2010-08-30 12:28 UTC (permalink / raw)
To: Fortran List, gcc-patches
> I have two testsuite failures on x86_64-darwin: trim_optimize_1.f90 and widechar_intrinsics_5.f90. I don't know how they could possibly be related, but my baseline testsuite run is still running.
Now I understand why I had these failures... When the file frontend-passes.c was added to the Fortran front-end, its dependencies were not clearly indicated in Make-lang.in... not even its dependency on gfortran.h, which is rather annoying and can get build in mixed states (in my case, frontend-passes.c values for intrinsic symbol IDs were off by one due to the introduction of the new EXECUTE_COMMAND_LINE in my patch).
So, I propose the following patch:
2010-08-30 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
* Make-lang.in: Add frontend-passes.o dependencies.
Built on x64_64-linux. OK to commit?
FX
Index: Make-lang.in
===================================================================
--- Make-lang.in (revision 163620)
+++ Make-lang.in (working copy)
@@ -339,6 +339,7 @@
libfuncs.h expr.h
fortran/scanner.o: toplev.h fortran/cpp.h
fortran/convert.o: $(GFORTRAN_TRANS_DEPS)
+fortran/frontend-passes.o: $(GFORTRAN_TRANS_DEPS)
fortran/trans.o: $(GFORTRAN_TRANS_DEPS) tree-iterator.h
fortran/trans-decl.o: $(GFORTRAN_TRANS_DEPS) gt-fortran-trans-decl.h \
$(CGRAPH_H) $(TARGET_H) $(FUNCTION_H) $(FLAGS_H) $(RTL_H) $(GIMPLE_H) \
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [fortran, patch] Dependencies for frontend-passes.c
2010-08-30 12:28 ` [fortran, patch] Dependencies for frontend-passes.c FX
@ 2010-08-30 13:21 ` Tobias Burnus
2010-08-30 17:44 ` Thomas Koenig
0 siblings, 1 reply; 8+ messages in thread
From: Tobias Burnus @ 2010-08-30 13:21 UTC (permalink / raw)
To: FX; +Cc: Fortran List, gcc-patches
On 08/30/2010 12:54 PM, FX wrote:
> 2010-08-30 Francois-Xavier Coudert<fxcoudert@gcc.gnu.org>
>
> * Make-lang.in: Add frontend-passes.o dependencies.
>
>
> Built on x64_64-linux. OK to commit?
OK. Sorry for missing it in the initial review.
Tobias
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [fortran, patch] Dependencies for frontend-passes.c
2010-08-30 13:21 ` Tobias Burnus
@ 2010-08-30 17:44 ` Thomas Koenig
0 siblings, 0 replies; 8+ messages in thread
From: Thomas Koenig @ 2010-08-30 17:44 UTC (permalink / raw)
To: Tobias Burnus; +Cc: FX, Fortran List, gcc-patches
Am Montag, den 30.08.2010, 13:38 +0200 schrieb Tobias Burnus:
> On 08/30/2010 12:54 PM, FX wrote:
> > 2010-08-30 Francois-Xavier Coudert<fxcoudert@gcc.gnu.org>
> >
> > * Make-lang.in: Add frontend-passes.o dependencies.
> >
> >
> > Built on x64_64-linux. OK to commit?
>
> OK. Sorry for missing it in the initial review.
Thanks for fixing this, and sorry for missing this in the first place.
Thomas
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [fortran, patch] Implement EXECUTE_COMMAND_LINE
2010-08-30 11:38 ` FX
2010-08-30 12:28 ` [fortran, patch] Dependencies for frontend-passes.c FX
@ 2010-09-01 6:55 ` Tobias Burnus
2010-09-01 8:40 ` FX
1 sibling, 1 reply; 8+ messages in thread
From: Tobias Burnus @ 2010-09-01 6:55 UTC (permalink / raw)
To: FX; +Cc: Fortran List, gcc-patches
FX wrote:
> OK to commit if regtest completes OK?
OK.
Tobias
PS: I have filled a follow up PR as there is seemingly no check whether
the actual argument is definable or not: PR 45474.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [fortran, patch] Implement EXECUTE_COMMAND_LINE
2010-09-01 6:55 ` [fortran, patch] Implement EXECUTE_COMMAND_LINE Tobias Burnus
@ 2010-09-01 8:40 ` FX
0 siblings, 0 replies; 8+ messages in thread
From: FX @ 2010-09-01 8:40 UTC (permalink / raw)
To: Tobias Burnus; +Cc: Fortran List, gcc-patches
> OK.
Thanks for the review, committed as rev. 163719.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-09-01 8:34 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-29 23:52 [fortran, patch] Implement EXECUTE_COMMAND_LINE FX
2010-08-30 10:54 ` Tobias Burnus
2010-08-30 11:38 ` FX
2010-08-30 12:28 ` [fortran, patch] Dependencies for frontend-passes.c FX
2010-08-30 13:21 ` Tobias Burnus
2010-08-30 17:44 ` Thomas Koenig
2010-09-01 6:55 ` [fortran, patch] Implement EXECUTE_COMMAND_LINE Tobias Burnus
2010-09-01 8:40 ` FX
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).