Description: Neither Fortran standard nor gfortran support calling
 vararg C function from Fortran. It used to work 'by chance' for
 most Debian supported architectures, but was broken for POWER by
 GCC PR fortran/87689 [1].
 This GCC PR request [2] explains it all.
 .
 [1] https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=268992
 [2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92361
Author: Gilles Filippini <pini@debian.org>
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=944127
Forwarded: https://cgnsorg.atlassian.net/browse/CGNS-179
Index: libcgns/src/cg_ftoc.c
===================================================================
--- libcgns.orig/src/cg_ftoc.c
+++ libcgns/src/cg_ftoc.c
@@ -2652,11 +2652,8 @@ CGNSDLL void __stdcall cg_goto_f(cgint_f
 CGNSDLL void FMNAME(cg_goto_f, CG_GOTO_F)(cgint_f *fn, cgint_f *B, cgint_f *ier, ...)
 #endif
 {
-#ifdef _CRAY
-    _fcd cray_string;
-#endif
-    char *f_label[CG_MAX_GOTO_DEPTH], *label[CG_MAX_GOTO_DEPTH];
-    int index[CG_MAX_GOTO_DEPTH], n, i, len[CG_MAX_GOTO_DEPTH];
+    char *label[CG_MAX_GOTO_DEPTH];
+    int index[CG_MAX_GOTO_DEPTH], n, i;
     va_list ap;
 
      /* initialize ap to the last parameter before the variable argument list */
@@ -2666,19 +2663,9 @@ CGNSDLL void FMNAME(cg_goto_f, CG_GOTO_F
 
      /* read arguments */
     for (n = 0; n < CG_MAX_GOTO_DEPTH; n++)  {
-#ifdef _CRAY
-        cray_string = va_arg(ap, _fcd);
-        f_label[n] = _fcdtocp(cray_string);
-        len[n] = _fcdlen(cray_string);
-#else
-        f_label[n] = va_arg(ap, char *);
-# ifdef WIN32_FORTRAN
-     /* In Windows, the arguments appear in a different order: char*, len, index,...*/
-        len[n] = (int)va_arg(ap, int);
-# endif
-#endif
-        if (f_label[n][0] == ' ' || 0 == strncmp(f_label[n],"end",3) ||
-            0 == strncmp(f_label[n],"END",3)) break;
+        label[n] = va_arg(ap, char *);
+        if (label[n][0] == ' ' || 0 == strncmp(label[n],"end",3) ||
+            0 == strncmp(label[n],"END",3)) break;
 
         index[n] = (int)*(va_arg(ap, cgint_f *));
         if (index[n] < 0) {
@@ -2688,19 +2675,8 @@ CGNSDLL void FMNAME(cg_goto_f, CG_GOTO_F
         }
     }
 
-#if !defined(_CRAY) && !defined(WIN32_FORTRAN)
-    for (i=0; i<n; i++) {
-      len[i] = va_arg(ap, int);
-    }
-#endif
     va_end(ap);
 
-     /* convert strings to C-strings */
-    for (i=0; i < n; i++) {
-        label[i] = CGNS_NEW(char,len[i]+1);
-        string_2_C_string(f_label[i], len[i], label[i], len[i], ier);
-    }
-
 #if DEBUG_GOTO
     printf("\nIn cg_ftoc.c: narguments=%d\n",n);
     for (i=0; i<n; i++) printf("\targ %d: '%s' #%d\n",i,label[i], index[i]);
@@ -2708,7 +2684,6 @@ CGNSDLL void FMNAME(cg_goto_f, CG_GOTO_F
 
     *ier = (cgint_f)cgi_set_posit((int)*fn, (int)*B, n, index, label);
 
-    for (i=0; i<n; i++) CGNS_FREE(label[i]);
     return;
 }
 
@@ -2720,11 +2695,8 @@ CGNSDLL void __stdcall cg_gorel_f(cgint_
 CGNSDLL void FMNAME(cg_gorel_f, CG_GOREL_F)(cgint_f *fn, cgint_f *ier, ...)
 #endif
 {
-#ifdef _CRAY
-    _fcd cray_string;
-#endif
-    char *f_label[CG_MAX_GOTO_DEPTH], *label[CG_MAX_GOTO_DEPTH];
-    int index[CG_MAX_GOTO_DEPTH], n, i, len[CG_MAX_GOTO_DEPTH];
+    char *label[CG_MAX_GOTO_DEPTH];
+    int index[CG_MAX_GOTO_DEPTH], n, i;
     va_list ap;
 
     if (posit == 0) {
@@ -2745,19 +2717,9 @@ CGNSDLL void FMNAME(cg_gorel_f, CG_GOREL
 
      /* read arguments */
     for (n = 0; n < CG_MAX_GOTO_DEPTH; n++)  {
-#ifdef _CRAY
-        cray_string = va_arg(ap, _fcd);
-        f_label[n] = _fcdtocp(cray_string);
-        len[n] = _fcdlen(cray_string);
-#else
-        f_label[n] = va_arg(ap, char *);
-# ifdef WIN32_FORTRAN
-     /* In Windows, the arguments appear in a different order: char*, len, index,...*/
-        len[n] = va_arg(ap, int);
-# endif
-#endif
-        if (f_label[n][0] == ' ' || 0 == strncmp(f_label[n],"end",3) ||
-            0 == strncmp(f_label[n],"END",3)) break;
+        label[n] = va_arg(ap, char *);
+        if (label[n][0] == ' ' || 0 == strncmp(label[n],"end",3) ||
+            0 == strncmp(label[n],"END",3)) break;
 
         index[n] = (int)*(va_arg(ap, cgint_f *));
         if (index[n] < 0) {
@@ -2767,19 +2729,8 @@ CGNSDLL void FMNAME(cg_gorel_f, CG_GOREL
         }
     }
 
-#if !defined(_CRAY) && !defined(WIN32_FORTRAN)
-    for (i=0; i<n; i++) {
-        len[i] = va_arg(ap, int);
-    }
-#endif
     va_end(ap);
 
-     /* convert strings to C-strings */
-    for (i=0; i < n; i++) {
-        label[i] = CGNS_NEW(char,len[i]+1);
-        string_2_C_string(f_label[i], len[i], label[i], len[i], ier);
-    }
-
 #if DEBUG_GOTO
     printf("\nIn cg_ftoc.c: narguments=%d\n",n);
     for (i=0; i<n; i++) printf("\targ %d: '%s' #%d\n",i,label[i], index[i]);
@@ -2787,10 +2738,37 @@ CGNSDLL void FMNAME(cg_gorel_f, CG_GOREL
 
     *ier = (cgint_f)cgi_update_posit(n, index, label);
 
-    for (i=0; i<n; i++) CGNS_FREE(label[i]);
     return;
 }
 
+CGNSDLL void FMNAME(cg_goto_f1, CG_GOTO_F1)(cgint_f *fn, cgint_f *B, cgint_f *ier, STR_PSTR(name), cgint_f *index STR_PLEN(name))
+{
+    int length;
+    char *c_name;
+
+    length = (int) STR_LEN(name);
+    c_name = CGNS_NEW(char, length+1);
+
+    string_2_C_string(STR_PTR(name), STR_LEN(name), c_name, length, ier);
+    if (*ier == 0)
+        FMNAME(cg_goto_f, CG_GOTO_F)(fn, B, ier, c_name, index, "end");
+    CGNS_FREE(c_name);
+}
+
+CGNSDLL void FMNAME(cg_gorel_f1, CG_GOREL_F1)(cgint_f *fn, cgint_f *ier, STR_PSTR(name), cgint_f *index STR_PLEN(name))
+{
+    int length;
+    char *c_name;
+
+    length = (int) STR_LEN(name);
+    c_name = CGNS_NEW(char, length+1);
+
+    string_2_C_string(STR_PTR(name), STR_LEN(name), c_name, length, ier);
+    if (*ier == 0)
+        FMNAME(cg_gorel_f, CG_GOREL_F)(fn, ier, c_name, index, "end");
+    CGNS_FREE(c_name);
+}
+
 /*-----------------------------------------------------------------------*/
 
 CGNSDLL void FMNAME(cg_gopath_f, CG_GOPATH_F) (cgint_f *fn,
Index: libcgns/src/cgns_f.F90
===================================================================
--- libcgns.orig/src/cgns_f.F90
+++ libcgns/src/cgns_f.F90
@@ -3082,20 +3082,29 @@ MODULE cgns
   !      Go - To Function                                                 *
   ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 
-!!$     INTERFACE
-!!$           SUBROUTINE cg_goto_f, CG_GOTO_F)(cgint_f *fn, cgint_f *B, ier, ...)
-!!$cgint_f *fn, cgint_f *B, ier, ...)
-!!$
-!!$          INTEGER, INTENT(OUT) :: ier
-!!$           END SUBROUTINE
-!!$        END INTERFACE
-!!$
-!!$     INTERFACE
-!!$           SUBROUTINE cg_gorel_f, CG_GOREL_F)(cgint_f *fn, ier, ...)
-!!$cgint_f *fn, ier, ...)
-!!$          INTEGER, INTENT(OUT) :: ier
-!!$           END SUBROUTINE
-!!$        END INTERFACE
+  INTERFACE
+     SUBROUTINE cg_goto_f1(fn, B, ier, &
+                     name1, index1)
+       IMPORT :: c_char
+       IMPLICIT NONE
+       INTEGER :: fn
+       INTEGER :: B
+       INTEGER, INTENT(OUT) :: ier
+       CHARACTER(KIND=C_CHAR), DIMENSION(*) :: name1
+       INTEGER :: index1
+     END SUBROUTINE
+  END INTERFACE
+  INTERFACE
+     SUBROUTINE cg_gorel_f1(fn, ier, &
+                     name1, index1)
+       IMPORT :: c_char
+       IMPLICIT NONE
+       INTEGER :: fn
+       INTEGER, INTENT(OUT) :: ier
+       CHARACTER(KIND=C_CHAR), DIMENSION(*) :: name1
+       INTEGER :: index1
+     END SUBROUTINE
+  END INTERFACE
 
   INTERFACE
      SUBROUTINE cg_gopath_f(fn,path, ier) !BIND(C, NAME="cg_gopath_f")
@@ -4926,6 +4935,332 @@ MODULE cgns
 
 CONTAINS
 
+  SUBROUTINE cg_goto_f(fn, B, ier, &
+                  name1, index1,  &
+                  name2, index2,  &
+                  name3, index3,  &
+                  name4, index4,  &
+                  name5, index5,  &
+                  name6, index6,  &
+                  name7, index7,  &
+                  name8, index8,  &
+                  name9, index9,  &
+                  name10, index10,  &
+                  name11, index11,  &
+                  name12, index12,  &
+                  name13, index13,  &
+                  name14, index14,  &
+                  name15, index15,  &
+                  name16, index16,  &
+                  name17, index17,  &
+                  name18, index18,  &
+                  name19, index19,  &
+                  name20)
+     IMPLICIT NONE
+     INTEGER :: fn
+     INTEGER :: B
+     INTEGER, INTENT(OUT) :: ier
+     CHARACTER(*) :: name1
+     INTEGER, OPTIONAL :: index1
+     CHARACTER(*), OPTIONAL :: name2
+     INTEGER, OPTIONAL :: index2
+     CHARACTER(*), OPTIONAL :: name3
+     INTEGER, OPTIONAL :: index3
+     CHARACTER(*), OPTIONAL :: name4
+     INTEGER, OPTIONAL :: index4
+     CHARACTER(*), OPTIONAL :: name5
+     INTEGER, OPTIONAL :: index5
+     CHARACTER(*), OPTIONAL :: name6
+     INTEGER, OPTIONAL :: index6
+     CHARACTER(*), OPTIONAL :: name7
+     INTEGER, OPTIONAL :: index7
+     CHARACTER(*), OPTIONAL :: name8
+     INTEGER, OPTIONAL :: index8
+     CHARACTER(*), OPTIONAL :: name9
+     INTEGER, OPTIONAL :: index9
+     CHARACTER(*), OPTIONAL :: name10
+     INTEGER, OPTIONAL :: index10
+     CHARACTER(*), OPTIONAL :: name11
+     INTEGER, OPTIONAL :: index11
+     CHARACTER(*), OPTIONAL :: name12
+     INTEGER, OPTIONAL :: index12
+     CHARACTER(*), OPTIONAL :: name13
+     INTEGER, OPTIONAL :: index13
+     CHARACTER(*), OPTIONAL :: name14
+     INTEGER, OPTIONAL :: index14
+     CHARACTER(*), OPTIONAL :: name15
+     INTEGER, OPTIONAL :: index15
+     CHARACTER(*), OPTIONAL :: name16
+     INTEGER, OPTIONAL :: index16
+     CHARACTER(*), OPTIONAL :: name17
+     INTEGER, OPTIONAL :: index17
+     CHARACTER(*), OPTIONAL :: name18
+     INTEGER, OPTIONAL :: index18
+     CHARACTER(*), OPTIONAL :: name19
+     INTEGER, OPTIONAL :: index19
+     CHARACTER(*), OPTIONAL :: name20
+
+     IF (.NOT. PRESENT(index1)) THEN
+        CALL cg_goto_f1(fn, B, ier, name1, 0)
+        RETURN
+     ELSE
+        PRINT '(I3)', index1
+        CALL cg_goto_f1(fn, B, ier, name1, index1)
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index2))) THEN
+        CALL cg_gorel_f1(fn, ier, name2, index2)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index3))) THEN
+        CALL cg_gorel_f1(fn, ier, name3, index3)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index4))) THEN
+        CALL cg_gorel_f1(fn, ier, name4, index4)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index5))) THEN
+        CALL cg_gorel_f1(fn, ier, name5, index5)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index6))) THEN
+        CALL cg_gorel_f1(fn, ier, name6, index6)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index7))) THEN
+        CALL cg_gorel_f1(fn, ier, name7, index7)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index8))) THEN
+        CALL cg_gorel_f1(fn, ier, name8, index8)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index9))) THEN
+        CALL cg_gorel_f1(fn, ier, name9, index9)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index10))) THEN
+        CALL cg_gorel_f1(fn, ier, name10, index10)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index11))) THEN
+        CALL cg_gorel_f1(fn, ier, name11, index11)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index12))) THEN
+        CALL cg_gorel_f1(fn, ier, name12, index12)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index13))) THEN
+        CALL cg_gorel_f1(fn, ier, name13, index13)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index14))) THEN
+        CALL cg_gorel_f1(fn, ier, name14, index14)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index15))) THEN
+        CALL cg_gorel_f1(fn, ier, name15, index15)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index16))) THEN
+        CALL cg_gorel_f1(fn, ier, name16, index16)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index17))) THEN
+        CALL cg_gorel_f1(fn, ier, name17, index17)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index18))) THEN
+        CALL cg_gorel_f1(fn, ier, name18, index18)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index19))) THEN
+        CALL cg_gorel_f1(fn, ier, name19, index19)
+     ELSE
+        RETURN
+     END IF
+  END SUBROUTINE
+
+  SUBROUTINE cg_gorel_f(fn, ier, &
+                  name1, index1,  &
+                  name2, index2,  &
+                  name3, index3,  &
+                  name4, index4,  &
+                  name5, index5,  &
+                  name6, index6,  &
+                  name7, index7,  &
+                  name8, index8,  &
+                  name9, index9,  &
+                  name10, index10,  &
+                  name11, index11,  &
+                  name12, index12,  &
+                  name13, index13,  &
+                  name14, index14,  &
+                  name15, index15,  &
+                  name16, index16,  &
+                  name17, index17,  &
+                  name18, index18,  &
+                  name19, index19,  &
+                  name20)
+     IMPLICIT NONE
+     INTEGER :: fn
+     INTEGER, INTENT(OUT) :: ier
+     CHARACTER(*) :: name1
+     INTEGER, OPTIONAL :: index1
+     CHARACTER(*), OPTIONAL :: name2
+     INTEGER, OPTIONAL :: index2
+     CHARACTER(*), OPTIONAL :: name3
+     INTEGER, OPTIONAL :: index3
+     CHARACTER(*), OPTIONAL :: name4
+     INTEGER, OPTIONAL :: index4
+     CHARACTER(*), OPTIONAL :: name5
+     INTEGER, OPTIONAL :: index5
+     CHARACTER(*), OPTIONAL :: name6
+     INTEGER, OPTIONAL :: index6
+     CHARACTER(*), OPTIONAL :: name7
+     INTEGER, OPTIONAL :: index7
+     CHARACTER(*), OPTIONAL :: name8
+     INTEGER, OPTIONAL :: index8
+     CHARACTER(*), OPTIONAL :: name9
+     INTEGER, OPTIONAL :: index9
+     CHARACTER(*), OPTIONAL :: name10
+     INTEGER, OPTIONAL :: index10
+     CHARACTER(*), OPTIONAL :: name11
+     INTEGER, OPTIONAL :: index11
+     CHARACTER(*), OPTIONAL :: name12
+     INTEGER, OPTIONAL :: index12
+     CHARACTER(*), OPTIONAL :: name13
+     INTEGER, OPTIONAL :: index13
+     CHARACTER(*), OPTIONAL :: name14
+     INTEGER, OPTIONAL :: index14
+     CHARACTER(*), OPTIONAL :: name15
+     INTEGER, OPTIONAL :: index15
+     CHARACTER(*), OPTIONAL :: name16
+     INTEGER, OPTIONAL :: index16
+     CHARACTER(*), OPTIONAL :: name17
+     INTEGER, OPTIONAL :: index17
+     CHARACTER(*), OPTIONAL :: name18
+     INTEGER, OPTIONAL :: index18
+     CHARACTER(*), OPTIONAL :: name19
+     INTEGER, OPTIONAL :: index19
+     CHARACTER(*), OPTIONAL :: name20
+
+     IF (.NOT. PRESENT(index1)) THEN
+        CALL cg_gorel_f1(fn, ier, name1, 0)
+        RETURN
+     ELSE
+        CALL cg_gorel_f1(fn, ier, name1, index1)
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index2))) THEN
+        CALL cg_gorel_f1(fn, ier, name2, index2)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index3))) THEN
+        CALL cg_gorel_f1(fn, ier, name3, index3)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index4))) THEN
+        CALL cg_gorel_f1(fn, ier, name4, index4)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index5))) THEN
+        CALL cg_gorel_f1(fn, ier, name5, index5)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index6))) THEN
+        CALL cg_gorel_f1(fn, ier, name6, index6)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index7))) THEN
+        CALL cg_gorel_f1(fn, ier, name7, index7)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index8))) THEN
+        CALL cg_gorel_f1(fn, ier, name8, index8)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index9))) THEN
+        CALL cg_gorel_f1(fn, ier, name9, index9)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index10))) THEN
+        CALL cg_gorel_f1(fn, ier, name10, index10)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index11))) THEN
+        CALL cg_gorel_f1(fn, ier, name11, index11)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index12))) THEN
+        CALL cg_gorel_f1(fn, ier, name12, index12)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index13))) THEN
+        CALL cg_gorel_f1(fn, ier, name13, index13)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index14))) THEN
+        CALL cg_gorel_f1(fn, ier, name14, index14)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index15))) THEN
+        CALL cg_gorel_f1(fn, ier, name15, index15)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index16))) THEN
+        CALL cg_gorel_f1(fn, ier, name16, index16)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index17))) THEN
+        CALL cg_gorel_f1(fn, ier, name17, index17)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index18))) THEN
+        CALL cg_gorel_f1(fn, ier, name18, index18)
+     ELSE
+        RETURN
+     END IF
+     IF ((ier .EQ. 0) .AND. (PRESENT(index19))) THEN
+        CALL cg_gorel_f1(fn, ier, name19, index19)
+     ELSE
+        RETURN
+     END IF
+  END SUBROUTINE
+
   FUNCTION cg_get_type_c_int(a)
     USE ISO_C_BINDING
     INTEGER(C_INT) :: a
