diff --git a/ompi/mpi/fortran/base/fortran_base_strings.h b/ompi/mpi/fortran/base/fortran_base_strings.h index 98c3c86884..c1e4f7513e 100644 --- a/ompi/mpi/fortran/base/fortran_base_strings.h +++ b/ompi/mpi/fortran/base/fortran_base_strings.h @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2010-2012 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2010-2018 Cisco Systems, Inc. All rights reserved * $COPYRIGHT$ * * Additional copyrights may follow @@ -58,8 +58,8 @@ BEGIN_C_DECLS OMPI_DECLSPEC int ompi_fortran_string_c2f(char *cstr, char *fstr, int len); /** - * Convert an array of Fortran strings to an argv-style array of C - * strings. + * Convert an array of Fortran strings that are terminated with a + * blank line to an argv-style array of C strings. * * @param farray Array of fortran strings * @param string_len Length of each fortran string in the array @@ -86,8 +86,29 @@ BEGIN_C_DECLS * number_of_argv_arrays). Hence, the advance parameter is used * to specify this displacement. */ - OMPI_DECLSPEC int ompi_fortran_argv_f2c(char *farray, int string_len, - int advancex, char ***cargv); + OMPI_DECLSPEC int ompi_fortran_argv_blank_f2c(char *farray, int string_len, + int advancex, char ***cargv); + + /** + * Convert an array of a specific number of Fortran strings to an + * argv-style array of C strings. + * + * @param farray Array of fortran strings + * @param farray_length Number of entries in the farray array + * @param string_len Length of each fortran string in the array + * @param advance Number of bytes to advance to get to the next string + * @param cargv Returned argv-style array of C strings + * + * @retval OMPI_SUCCESS upon success + * @retval OMPI_ERROR upon error + * + * This function is just like ompi_fortran_argv_blank_f2c(), + * except that it uses farray_length to determine the length of + * farray (vs. looking for a blank string to look for the end of + * the array). + */ + OMPI_DECLSPEC int ompi_fortran_argv_count_f2c(char *farray, int farray_length, int string_len, + int advancex, char ***cargv); /** * Convert an array of argvs to a C style array of argvs diff --git a/ompi/mpi/fortran/base/strings.c b/ompi/mpi/fortran/base/strings.c index 18595fdd74..c8996afba6 100644 --- a/ompi/mpi/fortran/base/strings.c +++ b/ompi/mpi/fortran/base/strings.c @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2010-2012 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2010-2018 Cisco Systems, Inc. All rights reserved * Copyright (c) 2017 Research Organization for Information Science * and Technology (RIST). All rights reserved. * $COPYRIGHT$ @@ -101,11 +101,19 @@ int ompi_fortran_string_c2f(char *cstr, char *fstr, int len) /* - * creates a C argument vector from an F77 array of strings - * (terminated by a blank string) + * Creates a C argument vector from an F77 array of strings. The + * array is terminated by a blank string. + * + * This function is quite similar to ompi_fortran_argv_count_f2c(), + * that it looks for a blank string to know when it has finished + * traversing the entire array (vs. having the length of the array + * passed in as a parameter). + * + * This function is used to convert "argv" in MPI_COMM_SPAWN (which is + * defined to be terminated by a blank string). */ -int ompi_fortran_argv_f2c(char *array, int string_len, int advance, - char ***argv) +int ompi_fortran_argv_blank_f2c(char *array, int string_len, int advance, + char ***argv) { int err, argc = 0; char *cstr; @@ -141,8 +149,52 @@ int ompi_fortran_argv_f2c(char *array, int string_len, int advance, /* - * Creates a set of C argv arrays from an F77 array of argv's. The - * returned arrays need to be freed by the caller. + * Creates a C argument vector from an F77 array of array_len strings. + * + * This function is quite similar to ompi_fortran_argv_blank_f2c(), + * except that the length of the array is a parameter (vs. looking for + * a blank line to end the array). + * + * This function is used to convert "array_of_commands" in + * MPI_COMM_SPAWN_MULTIPLE (which is not precisely defined, but is + * assumed to be of length "count", and *not* terminated by a blank + * line). + */ +int ompi_fortran_argv_count_f2c(char *array, int array_len, int string_len, int advance, + char ***argv) +{ + int err, argc = 0; + char *cstr; + + /* Fortran lines up strings in memory, each delimited by \0. So + just convert them until we hit an extra \0. */ + + *argv = NULL; + for (int i = 0; i < array_len; ++i) { + if (OMPI_SUCCESS != (err = ompi_fortran_string_f2c(array, string_len, + &cstr))) { + opal_argv_free(*argv); + return err; + } + + if (OMPI_SUCCESS != (err = opal_argv_append(&argc, argv, cstr))) { + opal_argv_free(*argv); + free(cstr); + return err; + } + + free(cstr); + array += advance; + } + + return OMPI_SUCCESS; +} + + +/* + * Creates a set of C argv arrays from an F77 array of argv's (where + * each argv array is terminated by a blank string). The returned + * arrays need to be freed by the caller. */ int ompi_fortran_multiple_argvs_f2c(int num_argv_arrays, char *array, int string_len, char ****argv) @@ -155,9 +207,9 @@ int ompi_fortran_multiple_argvs_f2c(int num_argv_arrays, char *array, argv_array = (char ***) malloc (num_argv_arrays * sizeof(char **)); for (i = 0; i < num_argv_arrays; ++i) { - ret = ompi_fortran_argv_f2c(current_array, string_len, - string_len * num_argv_arrays, - &argv_array[i]); + ret = ompi_fortran_argv_blank_f2c(current_array, string_len, + string_len * num_argv_arrays, + &argv_array[i]); if (OMPI_SUCCESS != ret) { free(argv_array); return ret; diff --git a/ompi/mpi/fortran/mpif-h/comm_spawn_f.c b/ompi/mpi/fortran/mpif-h/comm_spawn_f.c index c9495f2911..17c290e561 100644 --- a/ompi/mpi/fortran/mpif-h/comm_spawn_f.c +++ b/ompi/mpi/fortran/mpif-h/comm_spawn_f.c @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2010-2012 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2010-2018 Cisco Systems, Inc. All rights reserved * Copyright (c) 2015-2017 Research Organization for Information Science * and Technology (RIST). All rights reserved. * $COPYRIGHT$ @@ -101,7 +101,7 @@ void ompi_comm_spawn_f(char *command, char *argv, MPI_Fint *maxprocs, if (OMPI_IS_FORTRAN_ARGV_NULL(argv)) { c_argv = MPI_ARGV_NULL; } else { - ompi_fortran_argv_f2c(argv, string_len, string_len, &c_argv); + ompi_fortran_argv_blank_f2c(argv, string_len, string_len, &c_argv); } c_ierr = PMPI_Comm_spawn(c_command, c_argv, diff --git a/ompi/mpi/fortran/mpif-h/comm_spawn_multiple_f.c b/ompi/mpi/fortran/mpif-h/comm_spawn_multiple_f.c index d6efe20ec2..c4b2d4270d 100644 --- a/ompi/mpi/fortran/mpif-h/comm_spawn_multiple_f.c +++ b/ompi/mpi/fortran/mpif-h/comm_spawn_multiple_f.c @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2010-2012 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2010-2018 Cisco Systems, Inc. All rights reserved * Copyright (c) 2015-2017 Research Organization for Information Science * and Technology (RIST). All rights reserved. * Copyright (c) 2016 Los Alamos National Security, LLC. All rights @@ -115,8 +115,8 @@ void ompi_comm_spawn_multiple_f(MPI_Fint *count, char *array_commands, OMPI_ARRAY_FINT_2_INT(array_maxprocs, array_size); - ompi_fortran_argv_f2c(array_commands, cmd_string_len, - cmd_string_len, &c_array_commands); + ompi_fortran_argv_count_f2c(array_commands, array_size, cmd_string_len, + cmd_string_len, &c_array_commands); c_info = (MPI_Info *) malloc (array_size * sizeof(MPI_Info)); for (i = 0; i < array_size; ++i) {