From 3ef8e865873d386fe14cd6071924510721478793 Mon Sep 17 00:00:00 2001
From: Thomas Jahns <jahns@dkrz.de>
Date: Wed, 7 Mar 2018 14:51:22 +0100
Subject: [PATCH] Let ruby interface generator remove comments itself.

* The approach with cpp relies on GNU tools, i.e. is not portable.
---
 interfaces/f2003/bindGen.rb | 36 +++++++++++++++++++++++++++++++++---
 src/Makefile.am             |  3 ++-
 src/Makefile.in             |  3 ++-
 3 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/interfaces/f2003/bindGen.rb b/interfaces/f2003/bindGen.rb
index b28ba188d..0d2065ad0 100755
--- a/interfaces/f2003/bindGen.rb
+++ b/interfaces/f2003/bindGen.rb
@@ -1,4 +1,5 @@
 #!/usr/bin/env ruby
+$VERBOSE=true
 
 # This script generates a fortran source file that uses the ISO_C_BINDINGS to interface to the functions defined in the given C header file.
 # The basic approach is, that every C function is wrapped in a fortran function/subroutine, which internally uses a bind(c) interface to the C code.
@@ -934,10 +935,39 @@ end
 #Scan the given header and collect the interface information in the global variables.
 def scanHeader(headerPath)
 	#Scan the given header.
-	headerLines = IO.popen('cpp -fpreprocessed -dD ' + headerPath).readlines	#The options cause the preprocessor to strip all comments, but retain all #defines, and ignore #includes.
-	headerLines.each do |line|
+	headerFile = File.open(headerPath, 'r')
+	commentTerm = %r{\*/}
+	commentInit = %r{/[*/]}
+	while line = headerFile.gets
 		line.chomp!
 
+		commentBeginLineNo = headerFile.lineno
+		while foundComment = commentInit.match(line)
+			commentBegin = foundComment.begin(0)
+			typeChar = line[commentBegin+1]
+			if typeChar == "/"
+				line = line[0,commentBegin]
+				line.rstrip!
+				foundComment = false
+			elsif typeChar == "*"
+				commentSubStr=line[commentBegin..-1]
+				if commentTerm.match(commentSubStr)
+					newLine =	line.gsub(%r{/\*.*?\*/},'')
+					line = newLine.rstrip
+				else
+					while newLine = headerFile.gets and not foundCommentEnd = commentTerm.match(newLine)
+					end
+					if not newLine
+						$stderr.puts("Unterminated comment started at line ",
+												 commentBeginLineNo, "'", line, "'")
+						exit(1)
+					end
+					newLine.chomp!
+					line = line[0,commentBegin] +
+								 newLine[foundCommentEnd.begin(0)+2..-1]
+				end
+			end
+		end
 		if /^\s*$/.match(line)
 			#Empty lines are ignored.
 
@@ -971,7 +1001,7 @@ def fortranLine(file, line)
 		mline = line.gsub("\t", ' '*spacesPerTab)
 		charsPerLine=79
 		indentation = /^ */.match(mline)[0]
-		if not /^ *!/.match(mline)
+		if not %r{^ *!}.match(mline)
 			while mline.length > charsPerLine
 				# last position of space preceding line break
 				tspos = mline[0..charsPerLine].rindex(' ') || charsPerLine
diff --git a/src/Makefile.am b/src/Makefile.am
index f4a29ddc2..45c4eb9c2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -248,7 +248,8 @@ LOCALTARGETS += mo_cdi.$(OBJEXT)
 endif
 #
 mo_cdi.f90: $(top_srcdir)/src/cdi.h $(top_srcdir)/interfaces/f2003/bindGen.rb
-	$(RUBY) $(top_srcdir)/interfaces/f2003/bindGen.rb $(top_srcdir)/src/cdi.h $@
+	$(RUBY) $(top_srcdir)/interfaces/f2003/bindGen.rb \
+		$(top_srcdir)/src/cdi.h $@
 #
 mo_cdi.$(OBJEXT): mo_cdi.f90
 	$(FC) $(FCFLAGS) -c $(FCFLAGS_f90) $<
diff --git a/src/Makefile.in b/src/Makefile.in
index 558b400dd..2749000c6 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1057,7 +1057,8 @@ uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES \
 
 #
 mo_cdi.f90: $(top_srcdir)/src/cdi.h $(top_srcdir)/interfaces/f2003/bindGen.rb
-	$(RUBY) $(top_srcdir)/interfaces/f2003/bindGen.rb $(top_srcdir)/src/cdi.h $@
+	$(RUBY) $(top_srcdir)/interfaces/f2003/bindGen.rb \
+		$(top_srcdir)/src/cdi.h $@
 #
 mo_cdi.$(OBJEXT): mo_cdi.f90
 	$(FC) $(FCFLAGS) -c $(FCFLAGS_f90) $<
-- 
GitLab