C to fortran converter


I find the following “C to Fortran converter”, https://drive.google.com/drive/u/0/folders/1RU1C3foVK-y6spuTKgSmHtfJ73HQKu1U, but it was written for windows a long time ago. I want to know if there are similar codes/projects/routines for such similar job targeted for *nix platforms.

Any hints will be highly appreciated.



I was able to compile the code in that zip file with Intel Fortran on Windows. Maybe it can also be compiled with the Linux Intel Fortran compiler? In the line USE DFLIB, ONLY: RUNQQ one could use the standard Fortran execute_command_line.

Instead of translating the C code to Fortran, which cannot be done fully automatically, why don’t you call the C code from Fortran using the interoperability features?

If anyone is curious, the C2F program does convert

#include <stdio.h>
int main() {
   int i;
   for (i = 1; i < 11; ++i)
      printf("%d ", i);
   return 0;


! --------------------------------------------------
MODULE MAIN_1         ! global declarations
! --------------------------------------------------

! --------------------------------------------------
! --------------------------------------------------
! - - - local declarations - - -
  INTEGER :: i

! - - - begin - - -
  DO i = 1,11-1
    WRITE (*,901,ADVANCE='NO') i," "
  STOP 0

901 FORMAT (I0,A)
!  0 Errors detected

But again, it is better to call a C code from Fortran than to use a clever but necessarily incomplete C-to-Fortran translator.

I tried to compile it on Ubuntu 20.04 with ifort but failed, see the following fore more detailed info:

werner@X10DAi:~/Downloads/c2f/C2F$ ifort --version
ifort (IFORT) 20200306
Copyright (C) 1985-2020 Intel Corporation.  All rights reserved.

werner@X10DAi:~/Downloads/c2f/C2F$ tree
├── C
│   └── DEBUG.C
├── C2F.F90
└── F
    ├── C2F.FD
    ├── C2F.FI
    └── C2F_LIB.F90

2 directories, 5 files
werner@X10DAi:~/Downloads/c2f/C2F$ ifort C2F.F90 
C2F.F90(4): error #7002: Error in opening the compiled module file.  Check INCLUDE paths.   [DFLIB]
C2F.F90(811): error #6406: Conflicting attributes or multiple declaration of name.   [RUNQQ]
      n = RUNQQ('CPP',' -C -P '//arg1//' '//arg2)   ! use GNU CPP if present
C2F.F90(813): error #6406: Conflicting attributes or multiple declaration of name.   [RUNQQ]
      n = RUNQQ('FPP',' /ansi /m /C '//arg1//' '//arg2) ! use DVF FPP instead
C2F.F90(4): error #6580: Name in only-list does not exist or is not accessible.   [RUNQQ]
compilation aborted for C2F.F90 (code 1)

For my case, I want to port a computational physics project from C to FORTRAN, so such conversion is just an intermediate step which can lighten my workload.


RUNQQ is an extension available in Visual Fortran (Windows version):

As noted by @Beliavsky , you can replace it easily with execute_command_line() (Fortran >= 2008):

@vmagnin Thanks a lot for directing me the valuable document websites. I’ve tried as below but still failed due to my too shallow FORTRAN language skill/knowledge:

Based on the pertinent document mentioned above, I tried with the following revisions:

$ egrep -inR execute_command_line .
./C2F.F90:5:USE DFLIB, ONLY: execute_command_line()
./C2F.F90:813:      n = execute_command_line('CPP',' -C -P '//arg1//' '//arg2)   ! use GNU CPP if present
./C2F.F90:816:      n = execute_command_line('FPP',' /ansi /m /C '//arg1//' '//arg2) ! use DVF FPP instead

But ifort still refused to compile the main source code file:

$ ifort C2F.F90 
C2F.F90(5): error #5082: Syntax error, found ')' when expecting one of: * .NOT. . + - /) = ** / // .LT. < .LE. <= .EQ. == .NE. /= .GT. ...
USE DFLIB, ONLY: execute_command_line()
C2F.F90(5): error #6268: The keyword ASSIGNMENT or OPERATOR was expected in this context.   [EXECUTE_COMMAND_LINE]
USE DFLIB, ONLY: execute_command_line()
C2F.F90(5): error #7002: Error in opening the compiled module file.  Check INCLUDE paths.   [DFLIB]
USE DFLIB, ONLY: execute_command_line()
C2F.F90(813): error #6404: This name does not have a type, and must have an explicit type.   [EXECUTE_COMMAND_LINE]
      n = execute_command_line('CPP',' -C -P '//arg1//' '//arg2)   ! use GNU CPP if present
compilation aborted for C2F.F90 (code 1)

Any hints/comments will be highly appreciated.


No, no, execute_command_line() is part of the Fortran 2008 language. You don’t need any library to use it.

Moreover, DFLIB was the Digital Fortran library coming with Digital Visual Fortran (ancestor of Intel Visual Fortran). You won’t have access in the Linux version of the compiler. So you must replace every function coming from the DFLIB by something more standard.

@vmagnin Thanks again. Now I commented out all the lines including RUNQQ:

$ egrep -inR runqq .
./C2F.F90:811:      !n = RUNQQ('CPP',' -C -P '//arg1//' '//arg2)   ! use GNU CPP if present
./C2F.F90:813:      !n = RUNQQ('FPP',' /ansi /m /C '//arg1//' '//arg2) ! use DVF FPP instead

This time, I successfully compiled it:

$ ifort C2F.F90 -o c2f

$ file c2f 
c2f: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=b8b84527efdbbf5cb52650262704b8d3ef6cd508, for GNU/Linux 3.2.0, not stripped

Then I try to test it with the above mentioned sample code given by @Beliavsky but still failed as below:

$ ./c2f < ~/test.c 
  filename d      + declaration summary 


How to fix it?


I failed opening the zip available on Google Drive (compression method unknown)…
But the above error message looks like a path problem: Windows uses \ as a separator and Linux uses /.

@vmagnin You can obtain it from my github repo here. I’ve removed the precompiled windows binaries files in the archive, converted all files into unix format with dos2unix, and finally rearranged the layout of the files according to the README.C2F file.

I’ve tried to change the Windows path separator \ with its *nix counterpart / in the source code, but a basic greping give me so many results. So, I still can’t figure out a safe regex to do the trick. See below for more detailed info:

$ grep -nRF '\' .
./C2F.F90:354:OPEN (1,FILE='F\C2F.FI')
./C2F.F90:390:WRITE (*,'(A\)') '>>'
./C2F.F90:406:filename = 'C\' // ProgramName(1:Nsize) // '.C'
./C2F.F90:409:   WRITE (*,90) ' CANNOT FIND -> C2F\', filename
./C2F.F90:422:!  PASS 1 phase 0, Copies C\NAME.C to F\NAME.C
./C2F.F90:434:OPEN (11,FILE='C\' // ProgramName(1:Nsize) // '.C', MODE='READ')
./C2F.F90:435:OPEN (2,FILE='F\' // ProgramName(1:Nsize) // '.C', MODE='WRITE')
./C2F.F90:436:IF (Debug) OPEN (9,FILE='F\' // ProgramName(1:Nsize) // '.ERR', MODE='WRITE')
./C2F.F90:570:         string = 'C\' // Cline(c1:c-1)
./C2F.F90:573:            WRITE (*,*) TRIM(string(3:))//' not found in C2F\C directory'
./C2F.F90:801:CLOSE (2)           ! F\NAME.C
./C2F.F90:804:!  PASS 1 phase 1, Generates F\C2F.1 until EOF F\NAME.C (or NAME.CPP)
./C2F.F90:807:   arg1 = 'F\' // ProgramName(1:Nsize) // '.C'
./C2F.F90:808:   arg2 = 'F\' // ProgramName(1:Nsize) // '.CPP'
./C2F.F90:815:   OPEN (11,FILE='F\' // ProgramName(1:Nsize) // '.CPP',MODE='READ')
./C2F.F90:818:   OPEN (11,FILE='F\' // ProgramName(1:Nsize) // '.C',MODE='READ')
./C2F.F90:821:OPEN (1,FILE='F\C2F.1',MODE='WRITE')
./C2F.F90:833:11 DO     ! process F\NAME.C  -> F\C2F.1
./C2F.F90:1249:OPEN (1,FILE='F\C2F.1',MODE='READ')     ! stays open until pass 2 reads EOF
./C2F.F90:1260:OPEN (21,FILE='F\C2F.21',MODE='WRITE')              ! prepass 2 output
./C2F.F90:1291:! setup Keys for F\C2F.1 records
./C2F.F90:1326:OPEN (21,FILE='F\C2F.21',MODE='READ')
./C2F.F90:1328:OPEN (2,FILE='F\C2F.2',MODE='WRITE')
./C2F.F90:1329:OPEN (22,FILE='F\C2F.DAT',MODE='WRITE')
./C2F.F90:1620:OPEN (2,FILE='F\C2F.2',MODE='READ')
./C2F.F90:1622:OPEN (22,FILE='F\C2F.DAT',MODE='READ')
./C2F.F90:1692:OPEN (3,FILE='F\' // ProgramName(1:Nsize) // '.F90') ! cant backspace MODE=WRITE
./C2F.F90:2114:! PASS 3 process F\C2F.2 -> NAME.F90
./C2F.F90:2187:            stringc = .FALSE.             ! reset '\' detect in "string"
./C2F.F90:2196:            IF (stringc.AND.CC(c+1) /= 'C') THEN  ! there was "123\456" syntax
./C2F.F90:2208:         IF (ch == '\') THEN
./C2F.F90:2210:            IF (CC(c) == DQUOTE.AND.CC(c-2) /= '\') CC(c) = QUOTE ! FPS bug
./C2F.F90:2505:      ELSE IF (ch == QUOTE.AND.CC(c+1) == '\') THEN   ! '\
./C2F.F90:2506:         IF (CC(c+2) == '\') THEN                     ! '\\  = \
./C2F.F90:2507:            Fline(f:f+2) = "'\'"
./C2F.F90:2655:GO TO 2            ! continue with next module from F\C2F.1
./C2F.F90:2680:   CLOSE (1,STATUS='DELETE')   ! F\C2F.1
./C2F.F90:2681:   CLOSE (2,STATUS='DELETE')   ! F\C2F.2
./C2F.F90:2682:   OPEN (1,FILE='F\' // ProgramName(1:Nsize) // '.C')
./C2F.F90:2683:   CLOSE (1,STATUS='DELETE')   ! F\NAME.C
./C2F.F90:2685:      OPEN (1,FILE='F\' // ProgramName(1:Nsize) // '.CPP')
./C2F.F90:2686:      CLOSE (1,STATUS='DELETE')   ! F\NAME.CPP
./C2F.F90:2688:   OPEN (1,FILE='F\' // ProgramName(1:Nsize) // '.ERR')
./C2F.F90:2695:   OPEN (3,FILE='F\' // ProgramName(1:Nsize) // '.F90')
./C2F.F90:2696:   OPEN (4,FILE='F\C2F.4')
./C2F.F90:2705:   OPEN (3,FILE='F\C2F.4')
./C2F.F90:2706:   OPEN (4,FILE='F\' // ProgramName(1:Nsize) // '.F90')
./C2F.F90:3303:   IF (ch == '\') Cend = Cend-1               ! remove \ from output
./C2F.F90:3332:   IF (CC(Cend) == '\') Cend = Cend-1
./C2F.F90:3424:! debug t80   printf("%d %d\n",*(int *)j,*(int *)k);
./C2F.F90:3425:! debug t81   printf("%s\n", ((struct S *)sp1)->name);
./C2F.F90:3426:! jos case    printf("%s\n", (char*)(*temp).entry);
./C2F.F90:6686:   OPEN (23,FILE='F\C2F.TMP')
./C2F.F90:6877:WRITE (*,'(2(A,I3))') 'Unexpected EOF F\C2F.TMP reading after rec',n,' #written=',nrecords
./C2F.F90:7712:      IF (Cline(c:c+1) == '\n') THEN
./C2F.F90:7719:            c = c+2                       ! past \n
./C2F.F90:7726:      ELSE IF (Cline(c:c+1) == '\t') THEN
./C2F.F90:7730:         c = c+2                       ! past \t
./C2F.F90:7750:            IF (Cline(c-2:c-1) /= '\n'.AND.Key /= C_scanf) THEN
./C2F.F90:8115:   CASE ('\')
./C2F.F90:8145:CASE (DQUOTE,'\')
./C2F.F90:8147:   IF (CC(Cend) == '\') THEN
./C/DEBUG.C:149:   printf("Output written to DEBUG.NEW\n");
./C/DEBUG.C:151:   printf("Output written to file: %s\n",argv[1]);
./C/DEBUG.C:164:fprintf(Outfile1,"\nTest 1\n");
./C/DEBUG.C:174:fprintf(Outfile1,"%f\n",sqrt((float) j));
./C/DEBUG.C:184:fprintf(Outfile1,"\nTest 2\n");
./C/DEBUG.C:189:fprintf(Outfile1,"%d %d\n",j,k);
./C/DEBUG.C:192:fprintf(Outfile1,"%d %d\n",j,k);
./C/DEBUG.C:193:for(i=0;i<10;i++) fprintf(Outfile1,"%d\n",i);
./C/DEBUG.C:200:fprintf(Outfile1,"\nTest 3\n");
./C/DEBUG.C:218:fprintf(Outfile1,"\nTest 4\n");
./C/DEBUG.C:233:fprintf(Outfile1,"\nTest 5\n");
./C/DEBUG.C:243:fprintf(Outfile1,"\nTest 6\n");
./C/DEBUG.C:260:fprintf(Outfile1,"\nTest 7\n");
./C/DEBUG.C:270:fprintf(Outfile1,"\nTest 8\n");
./C/DEBUG.C:274:        fprintf(Outfile1,"%d\n",i); fprintf(Outfile1,"%d\n",j);
./C/DEBUG.C:276:fprintf(Outfile1,"%s\n","               end test8");
./C/DEBUG.C:283:fprintf(Outfile1,"\nTest 9\n");
./C/DEBUG.C:288:   fprintf(Outfile1,"%d\n",i);
./C/DEBUG.C:299:fprintf(Outfile1,"\nTest 10\n");
./C/DEBUG.C:319:fprintf(Outfile1,"\nTest 11\n");
./C/DEBUG.C:329:fprintf(Outfile1,"\nTest 12\n");
./C/DEBUG.C:351:fprintf(Outfile1,"\nTest 13\n");
./C/DEBUG.C:352:if(isalpha('a'))fprintf(Outfile1,"alphabetic\n"); /* Test if alphabetic */
./C/DEBUG.C:353:if(isalnum('a'))fprintf(Outfile1,"alphanumeric\n"); /* alphanumeric ? */
./C/DEBUG.C:354:if(isdigit('1'))fprintf(Outfile1,"numeric\n"); /* Test if numeric */
./C/DEBUG.C:355:if(islower('a'))fprintf(Outfile1,"lower case\n"); /* Test if lower case */
./C/DEBUG.C:356:if(isupper('A'))fprintf(Outfile1,"upper case\n"); /* Test if upper case */
./C/DEBUG.C:365:fprintf(Outfile1,"\nTest 14\n");
./C/DEBUG.C:375:fprintf(Outfile1,"\nTest 15\n");
./C/DEBUG.C:384:     fprintf(Outfile1,"%d\n",y[i]);
./C/DEBUG.C:385:   if(x==y)fprintf(Outfile1,"These pointers are associated\n");
./C/DEBUG.C:393:fprintf(Outfile1,"\nTest 16\n");
./C/DEBUG.C:401:if(y==z)fprintf(Outfile1,"y and z are pointer associated\n");
./C/DEBUG.C:402:if(*y==*z)fprintf(Outfile1,"y and z contains the same values\n");
./C/DEBUG.C:415:fprintf(Outfile1,"\nTest 17\n");
./C/DEBUG.C:417:fprintf(Outfile1,"values =%d %f %d\n",i,x,n);/*note: Test# = output values*/
./C/DEBUG.C:427:fprintf(Outfile1,"\nTest 18\n");
./C/DEBUG.C:429:fprintf(Outfile1,"%f\n",ccc[3] [1] [kkk]+15.)   ;/*note: output value = 18. */
./C/DEBUG.C:436:fprintf(Outfile1,"\nTest 19\n");
./C/DEBUG.C:448:fprintf(Outfile1,"%d %d\n",arg1[3],arg2[3]);
./C/DEBUG.C:459:fprintf(Outfile1,"\nTest 20\n");
./C/DEBUG.C:484:     fprintf(Outfile1,"%3d%6.0f%6.0f\n",x[i][j],y[i][j],z[i][j]);
./C/DEBUG.C:494:fprintf(Outfile1,"\nTest 21\n");
./C/DEBUG.C:513:     fprintf(Outfile1,"%d\n",x[i][j]);
./C/DEBUG.C:520: fprintf(Outfile1,"\nTest 22\n");
./C/DEBUG.C:524:   fprintf(Outfile1,"%d %d\n",x,y);
./C/DEBUG.C:544: fprintf(Outfile1,"\nTest 23\n");
./C/DEBUG.C:553:   fprintf(Outfile1,"%4d%4d%6.1f\n",i,k,s[i]);
./C/DEBUG.C:561: fprintf(Outfile1,"\nTest 24\n");
./C/DEBUG.C:573: fprintf(Outfile1,"%d %d\n",*y,i);
./C/DEBUG.C:578: fprintf(Outfile1,"%d\n",p[1]);
./C/DEBUG.C:584: fprintf(Outfile1,"%d\n",p[1]);
./C/DEBUG.C:595:fprintf(Outfile1,"\nTest 25\n");
./C/DEBUG.C:604:fprintf(Outfile1,"%d %d\n",*k,l[0]);
./C/DEBUG.C:612:fprintf(Outfile1,"%d %d\n",*k,*l);
./C/DEBUG.C:621:fprintf(Outfile1,"\nTest 26\n");
./C/DEBUG.C:632:     fprintf(Outfile1,"%d\n",x[i][j]);
./C/DEBUG.C:642:fprintf(Outfile1,"\nTest 27\n");
./C/DEBUG.C:654:     fprintf(Outfile1,"%2d\n",x[i][j]);
./C/DEBUG.C:662:     fprintf(Outfile1,"%3d\n",x[i][j]);
./C/DEBUG.C:672:fprintf(Outfile1,"\nTest 28\n");
./C/DEBUG.C:673:fprintf(Outfile1,"%d %d %d\n",x[0],x[1],x[2]);
./C/DEBUG.C:680:fprintf(Outfile1,"%d %d %d\n",x[0],x[1],x[2]);
./C/DEBUG.C:685:fprintf(Outfile1,"%d %d %d\n",x[0],x[1],x[2]);
./C/DEBUG.C:699: fprintf(Outfile1,"\nTest 29\n");
./C/DEBUG.C:703: fprintf(Outfile1,"%d %f\n",example.x[1],example.i);
./C/DEBUG.C:716:fprintf(Outfile1,"\nTest 30\n");
./C/DEBUG.C:720:fprintf(Outfile1,"%d %f\n",example.x[1],*example.i);
./C/DEBUG.C:724:fprintf(Outfile1,"%d %f\n",*example2.x,example2.i[1]);
./C/DEBUG.C:736:fprintf(Outfile1,"\nTest 31\n");
./C/DEBUG.C:764:fprintf(Outfile1,"\nTest 32\n");
./C/DEBUG.C:767:fprintf(Outfile1,"%d %f\n",example.u1.c,example.s1.f);
./C/DEBUG.C:775:fprintf(Outfile1,"\nTest 33\n");
./C/DEBUG.C:793:fprintf(Outfile1,"\nTest 34\n");
./C/DEBUG.C:796:fprintf(Outfile1," 1 d array \n");
./C/DEBUG.C:797:for (i=0;i<3;i++) fprintf(Outfile1,"%d\n",a[i]);
./C/DEBUG.C:800:fprintf(Outfile1," 2d array \n");
./C/DEBUG.C:803:      fprintf(Outfile1,"%d\n",x[i][j]);
./C/DEBUG.C:806:fprintf(Outfile1," 3d array\n");
./C/DEBUG.C:810:         fprintf(Outfile1,"%d\n",y[i][j][k]);
./C/DEBUG.C:820:fprintf(Outfile1,"\nTest 35\n");
./C/DEBUG.C:823:fprintf(Outfile1," 1 d array \n");
./C/DEBUG.C:824:for (i=0;i<3;i++) fprintf(Outfile1,"%d\n",a[i]);
./C/DEBUG.C:827:fprintf(Outfile1," 2d array \n");
./C/DEBUG.C:830:      fprintf(Outfile1,"%d\n",x[i][j]);
./C/DEBUG.C:833:fprintf(Outfile1," 3d array\n");
./C/DEBUG.C:837:         fprintf(Outfile1,"%d\n",y[i][j][k]);
./C/DEBUG.C:849:fprintf(Outfile1,"\nTest 36\n");
./C/DEBUG.C:853:fprintf(Outfile1,"%f %d\n",b->bbb,b->x[1]);
./C/DEBUG.C:857:fprintf(Outfile1,"%f %d\n",b->bbb,b->x[2]);
./C/DEBUG.C:865:fprintf(Outfile1,"\nTest 37\n");
./C/DEBUG.C:881:fprintf(Outfile1,"\nTest 38  is not translated as yet \n");
./C/DEBUG.C:882:/* fprintf(Outfile1,"%e\n",fact(69)); */
./C/DEBUG.C:906:fprintf(Outfile1,"\nTest 39\n");
./C/DEBUG.C:907:fprintf(Outfile1,"%s %s\n",x,z);
./C/DEBUG.C:925:fprintf(Outfile1,"\nTest 40\n");
./C/DEBUG.C:926:fprintf(Outfile1,"%d %f %f %f\n",x1.x,x1.b[0],x1.b[1],x1.b[2]);
./C/DEBUG.C:927:fprintf(Outfile1,"%d %f %c\n",x2.a.x,x2.a.b[2],x2.b);
./C/DEBUG.C:938:fprintf(Outfile1,"\nTest 41\n");
./C/DEBUG.C:956:fprintf(Outfile1,"\nTest 42\n");
./C/DEBUG.C:966: fprintf(Outfile1,"\nTest 43\n");
./C/DEBUG.C:969: fprintf(Outfile1,"%f%f%f\n",x,y,pow(2.,pow(2.,2)));
./C/DEBUG.C:980:fprintf(Outfile1,"\nTest 44\n");
./C/DEBUG.C:983:fprintf(Outfile1,"%s %s\n",x,y);
./C/DEBUG.C:994:fprintf(Outfile1,"%s %s\n",x,
./C/DEBUG.C:1001:fprintf(Outfile1,"\nTest 45\n");
./C/DEBUG.C:1002:fprintf(Outfile1,"%d %d\n",a,b);
./C/DEBUG.C:1005:#define FORMAT "%f %f\n"
./C/DEBUG.C:1012:fprintf(Outfile1,"\nTest 46\n");
./C/DEBUG.C:1019: default: fprintf(Outfile1,"default\n");
./C/DEBUG.C:1028:fprintf(Outfile1,"\nTest 47\n");
./C/DEBUG.C:1031:   fprintf(Outfile1,"%d\n",i);
./C/DEBUG.C:1040:fprintf(Outfile1,"\nTest 48\n");
./C/DEBUG.C:1042:fprintf(Outfile1,"%d %f\n",n,result);
./C/DEBUG.C:1067:fprintf(Outfile1,"\nTest 49\n");
./C/DEBUG.C:1072:  fprintf(Outfile1,"degree %d value = %f\n",i,OP);
./C/DEBUG.C:1095:* b: [1..n] aux vectors \  to evaluate the orth. polynomials. for Qk   *
./C/DEBUG.C:1135:   test statement embedded {printf(" line 1\n line 2\n line 3\n");}
./C/DEBUG.C:1136:   test multirecord output using \n in above statement       */
./C/DEBUG.C:1138:fprintf(Outfile1,"\nTest 50\n");
./C/DEBUG.C:1140:{fprintf(Outfile1," line 1\n line 2\n line 3\n");}
./C/DEBUG.C:1150:  fprintf(Outfile1,"\nTest 51\n");
./C/DEBUG.C:1151:  for( n = 1; n <= 5; n=n+1 ) fprintf(Outfile1,"%d\n", n );
./C/DEBUG.C:1156:      fprintf(Outfile1,"%d%d\n",n,k);
./C/DEBUG.C:1163:  for( ; *s != '\0'; s++)
./C/DEBUG.C:1164:     fprintf(Outfile1,"%c\n",*s);
./C/DEBUG.C:1173:  fprintf(Outfile1,"\nTest 52\n");
./C/DEBUG.C:1175:  fprintf(Outfile1,"%d%c%d\n",n1,ch,n2);
./C/DEBUG.C:1184: fprintf(Outfile1,"\nTest 53\n");
./C/DEBUG.C:1188: fprintf(Outfile1,"%d\n",x[3][3]-5);
./C/DEBUG.C:1197:   fprintf(Outfile1,"%d\n",y[k]);
./C/DEBUG.C:1201: fprintf(Outfile1,"%d\n",k);
./C/DEBUG.C:1209: fprintf(Outfile1,"\nTest 54\n");
./C/DEBUG.C:1216:   fprintf(Outfile1,"%d\n",x[i]);
./C/DEBUG.C:1225: fprintf(Outfile1,"%d\n",y[i]);
./C/DEBUG.C:1232: fprintf(Outfile1,"\nTest 55\n");
./C/DEBUG.C:1234:   fprintf(Outfile1,"%d %d\n",l,i);
./C/DEBUG.C:1244: fprintf(Outfile1,"\nTest 56\n");
./C/DEBUG.C:1246: fprintf(Outfile1,"%f\n",y);
./C/DEBUG.C:1258: fprintf(Outfile1,"\nTest 57\n");
./C/DEBUG.C:1265: fprintf(Outfile1,"The contents of word[] is -->%s\n", word );
./C/DEBUG.C:1273: fprintf(Outfile1,"\nTest 58\n");
./C/DEBUG.C:1274: fprintf(Outfile1,"%c %c\n", c, *char_ptr);
./C/DEBUG.C:1276: fprintf(Outfile1,"%c %c\n", c, *char_ptr);
./C/DEBUG.C:1278: fprintf(Outfile1,"%c %c\n", c, *char_ptr);
./C/DEBUG.C:1286: fprintf(Outfile1,"\nTest 59\n");
./C/DEBUG.C:1293: fprintf(Outfile1,"Todays date is %d/%d/%d.\n", date_ptr->month,
./C/DEBUG.C:1302: fprintf(Outfile1,"\nTest 60\n");
./C/DEBUG.C:1307: fprintf(Outfile1,"Name = %s\n", item.name );
./C/DEBUG.C:1308: fprintf(Outfile1,"ID = %d\n", item.id);
./C/DEBUG.C:1309: fprintf(Outfile1,"Price = %.2f\n", item.price );
./C/DEBUG.C:1317: fprintf(Outfile1,"Name = %s\n", goods->name );
./C/DEBUG.C:1318: fprintf(Outfile1,"ID = %d\n", goods->id);
./C/DEBUG.C:1319: fprintf(Outfile1,"Price = %f\n", goods->price );
./C/DEBUG.C:1327: fprintf(Outfile1,"\nTest 61\n");
./C/DEBUG.C:1334: fprintf(Outfile1,"%d\n", n2.next->value);
./C/DEBUG.C:1342: fprintf(Outfile1,"\nTest 62\n");
./C/DEBUG.C:1343: fprintf(Outfile1,"%d %d %d\n",a,b,c);
./C/DEBUG.C:1344: fprintf(Outfile1,"%c %c %c\n",d,e,f);
./C/DEBUG.C:1345: fprintf(Outfile1,"%d %d %d\n",g,h,i);
./C/DEBUG.C:1354: fprintf(Outfile1,"\nTest 63\n");
./C/DEBUG.C:1357:   fprintf(Outfile1,"Cannot go %s\n", peast);
./C/DEBUG.C:1364: fprintf(Outfile1,"\nTest 64\n");
./C/DEBUG.C:1365: fprintf(Outfile1,"%d\n",intervall(3,.6,x));
./C/DEBUG.C:1417: fprintf(Outfile1,"\nTest 65\n");
./C/DEBUG.C:1421: fprintf(Outfile1,"\n");
./C/DEBUG.C:1446: fprintf(Outfile1,"\nTest 66\n");
./C/DEBUG.C:1447: fprintf(Outfile1,"%f\n",norm_max(x,5));
./C/DEBUG.C:1482: fprintf(Outfile1,"\nTest 67\n");
./C/DEBUG.C:1483: fprintf(Outfile1,"%f\n",skalprod(x,y,4));
./C/DEBUG.C:1534: fprintf(Outfile1,"\nTest 68\n");
./C/DEBUG.C:1535: fprintf(Outfile1,"%0.5f %0.5f\n",comabs(x,y),comabs(6.,4.));
./C/DEBUG.C:1587: fprintf(Outfile1,"\nTest 69\n");
./C/DEBUG.C:1588: while(i--) fprintf(Outfile1,"%d\n",i);
./C/DEBUG.C:1589: while(--j) fprintf(Outfile1,"%d\n",j);
./C/DEBUG.C:1591:            fprintf(Outfile1,"%d\n",k);
./C/DEBUG.C:1605: fprintf(Outfile1,"\nTest 70\n");
./C/DEBUG.C:1608: fprintf(Outfile1,"\n");
./C/DEBUG.C:1612: fprintf(Outfile1,"\n");
./C/DEBUG.C:1614: fprintf(Outfile1,"%d\n",(a>b ? 12 : 23) );
./C/DEBUG.C:1615: fprintf(Outfile1,"%f\n",(c>d ? 3.14 : 2.7) );
./C/DEBUG.C:1616: fprintf(Outfile1,"%c\n",('e'>'b' ? 'e' : 'b') );
./C/DEBUG.C:1627: fprintf(Outfile1,"\nTest 71\n");
./C/DEBUG.C:1628: fprintf(Outfile1,"%d\n",j);
./C/DEBUG.C:1629: fprintf(Outfile1,"%d\n",to_int(3.1416));
./C/DEBUG.C:1645: fprintf(Outfile1,"\nTest 72\n");
./C/DEBUG.C:1646: x[0]='\\';
./C/DEBUG.C:1647: x[1]='\67';
./C/DEBUG.C:1648: x[2]='\067';
./C/DEBUG.C:1649: x[3]='\t'; /* char(9)*/
./C/DEBUG.C:1650: x[4]='\n'; /* char(13)*/
./C/DEBUG.C:1651: fprintf(Outfile1,"%c %c %c\n",x[0],x[1],x[2]);
./C/DEBUG.C:1652: fprintf(Outfile1,"%d %d\n",(int)x[3],(int)x[4]);
./C/DEBUG.C:1658: fprintf(Outfile1,"\nTest 73\n");
./C/DEBUG.C:1659: fprintf (Outfile1,"%f\n",maxroot());
./C/DEBUG.C:1697: fprintf(Outfile1,"\nTest 74\n");
./C/DEBUG.C:1700: fprintf(Outfile1,"%f\n",xglobal[1]);
./C/DEBUG.C:1716: fprintf(Outfile1,"\nTest 75\n");
./C/DEBUG.C:1719: fprintf (Outfile1,"%d %d %d %d %d\n",FT_IMAGE,FT_POINT,FT_LINE,FT_POLYGON,
./C/DEBUG.C:1728: fprintf(Outfile1,"\nTest 76\n");
./C/DEBUG.C:1735:   fprintf(Outfile1,"%s\n",s[i]);
./C/DEBUG.C:1736: if(strcmp(s[3],s[1]) > 0) fprintf(Outfile1,"%s > %s\n",s[3],s[0]);
./C/DEBUG.C:1745: fprintf(Outfile1,"\nTest 77\n");
./C/DEBUG.C:1750: fprintf(Outfile1,"\n");
./C/DEBUG.C:1760: fprintf(Outfile1,"\n");
./C/DEBUG.C:1767: fprintf(Outfile1,"\nTest 78\n");
./C/DEBUG.C:1770: fprintf(Outfile1,"%f %f\n",x,y);
./C/DEBUG.C:1777: fprintf(Outfile1,"\nTest 79\n");
./C/DEBUG.C:1778: fprintf(Outfile1,"%d %d\n",a,q);
./C/DEBUG.C:1789: fprintf(Outfile1,"\nTest 80\n");
./C/DEBUG.C:1792: fprintf(Outfile1,"%d %d\n",*(int *)j,*(int *)k);
./C/DEBUG.C:1794: fprintf(Outfile1,"%d %d\n",*(int *)j,*(int *)k);
./C/DEBUG.C:1810:  fprintf(Outfile1,"\nTest 81\n");
./C/DEBUG.C:1819:  fprintf(Outfile1,"%s\n", ((struct S *)sp1)->name);
./C/DEBUG.C:1820:  fprintf(Outfile1,"%d\n", ((struct S *)sp1)->number);
./C/DEBUG.C:1828: fprintf(Outfile1,"\nTest 82\n");
./C/DEBUG.C:1832: fprintf(Outfile1,"z.r = %f\n", z.r);
./C/DEBUG.C:1833: fprintf(Outfile1,"z.i = %f\n", z.i);
./C/DEBUG.C:1848: fprintf(Outfile1,"\nTest 83\n");
./C/DEBUG.C:1854: fprintf(Outfile1,"x.r = %f\n", x.r);
./C/DEBUG.C:1855: fprintf(Outfile1,"*v.r = %f\n", (*v).r);
./C/DEBUG.C:1865: fprintf(Outfile1,"\nTest 84\n");
./C/DEBUG.C:1876: fprintf(Outfile1,"%d %d\n",k[i],kk[i]);
./C/DEBUG.C:1886: fprintf(Outfile1,"\nTest 85\n");
./C/DEBUG.C:1893: fprintf(Outfile1,"z=%f, x = %f, y = %f \n",z, x, y);
./C/DEBUG.C:1896: fprintf(Outfile1,"z=%f, x = %f, y = %f \n",z, x, y);
./C/DEBUG.C:1899: fprintf(Outfile1,"z=%f, x = %f, y = %f \n",z, x, y);
./C/DEBUG.C:1903: fprintf(Outfile1,"z=%f, x = %f, y = %f \n",z, x, y);
./C/DEBUG.C:1907: fprintf(Outfile1,"z=%f, x = %f, y = %f \n",z, x, y);
./C/DEBUG.C:1912: fprintf(Outfile1,"z=%f, x = %f, y = %f *s = %f\n",z, x, y,*s);
./C/DEBUG.C:1919: fprintf(Outfile1,"z=%f, x = %f, y = %f *s = %f ns = %d\n", z, x, y,*s, ns);
./C/DEBUG.C:1933:  fprintf(Outfile1,"\nTest 86\n");
./C/DEBUG.C:1940:  fprintf(Outfile1,"z=%f\n",z);
./C/DEBUG.C:1941:  fprintf(Outfile1,"z1=%f\n",z1);
./C/DEBUG.C:1946:  fprintf(Outfile1,"z=%f\n",z);
./C/DEBUG.C:1947:  fprintf(Outfile1,"z1=%f\n",z1);
./C/DEBUG.C:1992:  fprintf(Outfile1,"\nTest 87\n");
./C/DEBUG.C:1995:    fprintf(Outfile1,"arg %d  = %s\n",n,argv[n]);
./C/DEBUG.C:1996:  fprintf(Outfile1,"1st ch = %c\n", argv[0][0]);
./C/DEBUG.C:2007: fprintf(Outfile1,"\nTest 88\n");
./C/DEBUG.C:2012: fprintf(Outfile1,"Calling fWriteList\n");
./C/DEBUG.C:2020:  fprintf(Outfile1, "    %d : %s\n", ++i, (char*)(*temp).entry);


Could you run the C preprocessor on your C source file to get a file with the necessary code included? In general, c2f expects that C source files are in a c subdirectory. It writes the translated Fortran source files to an f subdirectory.

See the following:

$ cpp test.c > cpp-test.c
$ ./c2f < cpp-test.c 
  filename d      + declaration summary 


It looks like the program c2f is expecting the name of a file as an argument. You’re feeding it the file’s contents on standard input.

The < provides the contents of the file (in this case cpp-test.c to the running program as if you were typing them. It appears the program wants the name of the file as a command line argument; something which is determined at program startup, not during program execution.

TLDR: Try dropping the <, i.e. ./c2f cpp-test.c

I run the program from the Windows command line by typing c2f.exe and then entering the source file name when prompted. I uploaded c2f to Github.

See the following:

$ ./c2f cpp-test.c
  filename d      + declaration summary


It will stop as shown above. If I hit the , the following result will be generated:

$ ./c2f cpp-test.c
  filename d      + declaration summary

 CANNOT FIND -> C2F\C\.C            


You are testing the Windows version, but I still don’t know how to make it run on Linux.

I see. It wants the name of the file as interactive input. In which case you would do it as:

$ ./c2f
  filename d      + declaration summary

>> cpp-test.c

You could also put the file name in another file and run it like:

$ ./c2f < filename.txt

but that seems like overkill for a single file.

$ cat filename.txt 
$ ./c2f < filename.txt 
  filename d      + declaration summary 


Windows uses \ and Unix uses / for a directory separator. You may need to modify the code to make it work on Linux. I wonder if the OP has read the README.C2F file.

1 Like

Btw, I would like to see a project to take Clang and convert C and C++ codes to Fortran. For C I think this might be very useful in practice, I don’t know how feasible is to translate C++ constructs.

1 Like

I’ve read that file and try to adjust the source file for *nix platforms as below:

$ sed -rie 's/\\([^nt\ ])/\/\1/' C2F.F90

But I still meet the similar problem:

$ ./c2f 
  filename d      + declaration summary 


 CANNOT FIND -> C2F/C/TEST.C