From b668d8d58eaa3868c274e31338d1c6d8a9b65236 Mon Sep 17 00:00:00 2001
From: Quentin Rodier <quentin.rodier@meteo.fr>
Date: Fri, 15 Apr 2022 00:03:14 +0200
Subject: [PATCH] Quentin 14/04/2022: Correct indent for #ifdef, multiple IF
 lines and add comments

---
 correct_indent.py | 275 ++++++++++++++++++++++++++++------------------
 1 file changed, 166 insertions(+), 109 deletions(-)

diff --git a/correct_indent.py b/correct_indent.py
index 5c95f933f..54a69182f 100755
--- a/correct_indent.py
+++ b/correct_indent.py
@@ -1,109 +1,166 @@
-#!/usr/bin/env python3
-def detectMNH_expand(f):
-    fin = open(f,'r')
-    fout  = open(f+'_EXPAND','w')
-    contentbyline = fin.readlines()
-    
-    for i in contentbyline:
-        if "!$mnh_expand" in i:
-            fout.writelines("! $MNH EXPAND$ !\n")
-            fout.writelines(i)    
-        elif "!$mnh_end_expand" in i:
-            fout.writelines(i)
-            fout.writelines("! $MNH END EXPAND$ !\n")
-        else: 
-            fout.writelines(i)
-    
-    fout.close()
-    fin.close()
-
-def count_blank(text):
-    count=0
-    for t in text:
-        if t == " ":
-            count=count+1
-        else:
-            break
-    return count
-        
-def check_indent(n,indent_score,worktext):
-    nblank=count_blank(worktext)
-    rawtext=worktext[nblank:]
-    correcttext=' '*((indent_score)*1) + rawtext
-    return correcttext
-
-def firstcharacnotblank(string):
-    for i in string:
-        if i == " ": pass
-        else: return i
-
-def correct_indent(f):
-    fin = open(f,'r')
-    fout  = open(f+'_CORRECT_INDENT','w')
-    contentbyline = fin.readlines()
-    
-    ncurrline=0
-    indent_score=0
-    expand_score=0
-    for i in contentbyline:
-        if "! $MNH EXPAND$ !" in i:
-            expand_score = expand_score + 1
-            textwrite = ""
-        elif "! $MNH END EXPAND$ !" in i:
-            expand_score = expand_score - 1
-            textwrite = ""
-        # Correct indentation only in between $MNH EXPAND$ and $MNH END EXPAND$
-        elif expand_score >= 1:
-            # Do not indent comment lines within mnh_expand
-            if firstcharacnotblank(i) == "!":
-                textwrite=i
-            elif indent_score > 0 and ("DO J" not in i and "ENDDO" not in i and "END IF" not in i and "ENDIF" not in i and "THEN" not in i and "ELSE" not in i):
-                textwrite=check_indent(ncurrline,indent_score,i)
-            elif "ELSE" in i:
-                indent_score = indent_score+1        
-                textwrite=check_indent(ncurrline,indent_score,i)
-                indent_score = indent_score-1
-            elif "THEN" in i:
-                textwrite=check_indent(ncurrline,indent_score,i)
-                indent_score = indent_score+1        
-            elif "DO J" in i:
-                textwrite=check_indent(ncurrline,indent_score,i)
-                indent_score = indent_score+1
-            elif ("ENDDO" in i) or ("END DO" in i):
-                indent_score = indent_score-1
-                textwrite=check_indent(ncurrline,indent_score,i)
-            elif ("END IF" in i) or ("ENDIF" in i):
-                indent_score = indent_score-1
-                textwrite=check_indent(ncurrline,indent_score,i)       
-            else:
-                textwrite=i
-        else: # not EXPAND lines nor within mnh_expand
-            if "THEN" in i:
-                indent_score = indent_score+1        
-            elif "DO J" in i:
-                indent_score = indent_score+1
-            elif ("ENDDO" in i) or ("END DO" in i):
-                indent_score = indent_score-1
-            elif ("END IF" in i) or ("ENDIF" in i):
-                indent_score = indent_score-1
-            textwrite=i
-        ncurrline=ncurrline+1
-        fout.writelines(textwrite)
-    
-    fout.close()
-    fin.close()
-
-if __name__ == "__main__":
-    import argparse
-    import sys
-    parser = argparse.ArgumentParser(description='Detecte les balises !$mnh_expand et !$mnh_end_expand et ajoute un commentaire avant et après pour corriger l\'indentation par la suite avec correct_indentation.py' )
-    value = argparse.ArgumentParser()
-    parser.add_argument('file1', metavar='file1', type=str, help="file to check")
-    parser.add_argument('action', metavar='action', type=str, help="action (indent or detect")   
-    args = parser.parse_args()
-    if "indent" in args.action:
-        sys.exit(correct_indent(args.file1))
-    elif "detect" in args.action:
-        sys.exit(detectMNH_expand(args.file1))
-    else:
-        sys.exit("Error : action should be indent or detect. Nothing has been done")
+#!/usr/bin/env python3
+
+def detectMNH_expand(f):
+# Adds MNH EXPAND comment before and after $mnh_expand$
+    fin = open(f,'r')
+    fout  = open(f+'_EXPAND','w')
+    contentbyline = fin.readlines()
+    
+    for i in contentbyline:
+        if "!$mnh_expand" in i:
+            fout.writelines("! $MNH EXPAND$ !\n")
+            fout.writelines(i)    
+        elif "!$mnh_end_expand" in i:
+            fout.writelines(i)
+            fout.writelines("! $MNH END EXPAND$ !\n")
+        else: 
+            fout.writelines(i)
+    
+    fout.close()
+    fin.close()
+
+def count_blank(text):
+# Count number of space blank before a first character of a line
+    count=0
+    for t in text:
+        if t == " ":
+            count=count+1
+        else:
+            break
+    return count
+        
+def check_indent(n,indent_score,worktext):
+# Correct the indentation with respect to the indent_score
+    nblank=count_blank(worktext)
+    rawtext=worktext[nblank:]
+    correcttext=' '*((indent_score)*2) + rawtext
+    return correcttext
+
+def firstchar(string):
+# Return the first non-blank character of a string
+    for i in string:
+        if i == " ": pass
+        else: return i
+
+def first7char(string):
+# Return the 7 first non-blank character of a string
+    nb_blank=0
+    for i in string:
+        if i == " ": nb_blank=nb_blank+1 
+        else: return string[nb_blank:nb_blank+7]
+
+
+def correct_indent(f):
+    import sys
+# Correct the indentation between MNH EXPAND comment
+# Does not change the indentation outside MNH EXPAND > ... < MNH END EXPAND
+# Does not indent comment lines
+# Handles IF in two lines (e.g IF(... &
+#                                 ......) THEN                                    
+# TODO : handles more than two lines of & with IF
+# TODO : do not correct indentation for & within an regular line
+# To improve : the indentation correction is weird (strict) if the indentation before
+# the MNH EXPAND comments is not respected (over-indentation)
+    fin = open(f,'r')
+    fout  = open(f+'_CORRECT_INDENT','w')
+    contentbyline = fin.readlines()
+    
+    ncurrline=0
+    indent_score=0
+    expand_score=0
+    passNextLine = {'Pass':False, 'Reason':"" }
+    for i in contentbyline:
+        i7=first7char(i)
+        if passNextLine['Pass']: #Second line with & for if or #if(n)def
+            textwrite=i
+            passNextLine['Pass']=False
+            if passNextLine['Reason'] == "IF":
+                indent_score = indent_score+1
+            elif passNextLine['Reason'] == "#ifdef":
+                textwrite=check_indent(ncurrline,indent_score,i)
+            elif passNextLine['Reason'] == "#else":
+                textwrite=check_indent(ncurrline,indent_score,i)
+                # ONLY IF present in between #ifdef is handled
+                # If more test is needed (present in the fortran code), duplicate test here
+                if "IF" in i7 and "THEN" in i:
+                    indent_score = indent_score+1
+            else:
+                 sys.exit("Reason for passing the line not defined")
+        elif "! $MNH EXPAND$ !" in i:
+            expand_score = expand_score + 1
+            textwrite = ""
+        elif "! $MNH END EXPAND$ !" in i:
+            expand_score = expand_score - 1
+            textwrite = ""
+        # Ignore comment lines
+        elif firstchar(i) == "!":
+            textwrite=i
+        # Correct indentation only in between $MNH EXPAND$ and $MNH END EXPAND$
+        elif expand_score >= 1:
+            if indent_score > 0 and ("DO J" not in i and "ENDDO" not in i and "END DO" not in i and "END IF" not in i and "ENDIF" not in i and "THEN" not in i and "ELSE" not in i and "#if" not in i and "#else" not in i and "#endif" not in i):
+                textwrite=check_indent(ncurrline,indent_score,i)
+            # #ifdef handling = pass to next lines with no indent
+            elif "#if" in i7:  #ifdef or ifndef
+                print(i)
+                textwrite=i
+                passNextLine['Pass'],passNextLine['Reason']= (True, "#ifdef")
+            elif "#else" in i7:
+                textwrite=i
+                passNextLine['Pass'],passNextLine['Reason']= (True, "#else")
+            elif '#endif' in i7:
+                textwrite=i
+            elif "ELSE" in i7: #ELSE or ELSEIF
+                indent_score = indent_score-1        
+                textwrite=check_indent(ncurrline,indent_score,i)
+                indent_score = indent_score+1
+            elif "IF" in i7 and "&" in i: #IF on two lines #TODO on > 2 lines
+                textwrite=i
+                passNextLine['Pass'],passNextLine['Reason']= (True, "IF")
+            elif "IF" in i7 and "THEN" in i: #exclude IF in one line (without THEN)
+                textwrite=check_indent(ncurrline,indent_score,i)
+                indent_score = indent_score+1        
+            elif "DO J" in i7:
+                textwrite=check_indent(ncurrline,indent_score,i)
+                indent_score = indent_score+1
+            elif ("ENDDO" in i7) or ("END DO" in i7):
+                indent_score = indent_score-1
+                textwrite=check_indent(ncurrline,indent_score,i)
+            elif ("END IF" in i7) or ("ENDIF" in i7):
+                indent_score = indent_score-1
+                textwrite=check_indent(ncurrline,indent_score,i)       
+            else:
+                textwrite=i
+        else: # not EXPAND lines nor within mnh_expand
+            if "ELSE" in i7: #ELSE or ELSEIF
+                pass #no increase in indent
+            elif "IF" in i7 and "&" in i: #IF on two lines #TODO on > 2 lines
+                passNextLine['Pass'],passNextLine['Reason']= (True, "IF")
+            elif "IF" in i7 and "THEN" in i: #exclude IF in one line (without THEN)
+                indent_score = indent_score+1        
+            elif "DO J" in i7:
+                indent_score = indent_score+1
+            elif ("ENDDO" in i7) or ("END DO" in i7):
+                indent_score = indent_score-1
+            elif ("END IF" in i7) or ("ENDIF" in i7):
+                indent_score = indent_score-1
+            textwrite=i
+        ncurrline=ncurrline+1
+        fout.writelines(textwrite)
+    
+    fout.close()
+    fin.close()
+
+if __name__ == "__main__":
+    import argparse
+    import sys
+    parser = argparse.ArgumentParser(description='Detecte les balises !$mnh_expand et !$mnh_end_expand et ajoute un commentaire avant et après pour corriger l\'indentation par la suite avec correct_indentation.py' )
+    value = argparse.ArgumentParser()
+    parser.add_argument('file1', metavar='file1', type=str, help="file to check")
+    parser.add_argument('action', metavar='action', type=str, help="action (indent or detect")   
+    args = parser.parse_args()
+    if "indent" in args.action:
+        sys.exit(correct_indent(args.file1))
+    elif "detect" in args.action:
+        sys.exit(detectMNH_expand(args.file1))
+    else:
+        sys.exit("Error : action should be indent or detect. Nothing has been done")
-- 
GitLab