Recent

Author Topic: ptop doesn't format "else if" well  (Read 2899 times)

anokim

  • Newbie
  • Posts: 3
ptop doesn't format "else if" well
« on: January 02, 2025, 09:47:55 am »
I'm using ptop to autoformat my code but it behaves strangely. Let's take this ptop-formatted code:

Code: Pascal  [Select][+][-]
  1.   n := 2;
  2.   if n < 0 then
  3.     WriteLn('negative')
  4.   else if n > 0 then
  5.          WriteLn('positive')
  6.   else
  7.     WriteLn('zero');
  8.  

Line 5 is indented too much. The problem is that it is aligned to "if", similarly to line 3, but it should be aligned to "else if".

For ptop, you can generate its config file with "ptop -g local.cfg". Then, you can tweak it and use the tweaked version: "ptop -c local.cfg in.pas out.pas". However, I couldn't figure out how to tweak it.

anokim

  • Newbie
  • Posts: 3
Re: ptop doesn't format "else if" well
« Reply #1 on: January 02, 2025, 12:27:33 pm »
I came up with a script that you can run after ptop:

Code: Python  [Select][+][-]
  1. #!/usr/bin/env python3
  2.  
  3. import sys
  4.  
  5. INDENT = 2
  6.  
  7.  
  8. def fix_elseif_indentation(input_lines):
  9.     fixed_lines = []
  10.     i = 0
  11.     while i < len(input_lines):
  12.         line = input_lines[i]
  13.         fixed_lines.append(line)
  14.  
  15.         # Look for "else if" pattern
  16.         stripped = line.lower().lstrip()
  17.         if stripped.startswith("else if"):
  18.             indents = len(line) - len(stripped)
  19.             good_indents = indents + INDENT
  20.             first_line_inside = True
  21.             while True:
  22.                 i += 1
  23.                 next_line = input_lines[i]
  24.                 stripped_next_line = next_line.lstrip()
  25.                 indents_next_line = len(next_line) - len(stripped_next_line)
  26.                 if indents_next_line == indents:
  27.                     fixed_lines.append(next_line)
  28.                     break
  29.                 # else:
  30.                 if first_line_inside:
  31.                     indents_to_remove = indents_next_line - good_indents
  32.                 #
  33.                 fixed_lines.append(next_line[indents_to_remove:])
  34.                 first_line_inside = False
  35.             #
  36.         #
  37.         i += 1
  38.     #
  39.     return fixed_lines
  40.  
  41.  
  42. def main():
  43.     if len(sys.argv) != 3:
  44.         print("Usage: python script.py input.pas output.pas")
  45.         sys.exit(1)
  46.  
  47.     input_file = sys.argv[1]
  48.     output_file = sys.argv[2]
  49.  
  50.     try:
  51.         # Read input file
  52.         with open(input_file, "r") as f:
  53.             lines = f.readlines()
  54.  
  55.         # Fix indentation
  56.         fixed_lines = fix_elseif_indentation(lines)
  57.  
  58.         # Write output file
  59.         with open(output_file, "w") as f:
  60.             f.writelines(fixed_lines)
  61.  
  62.     except FileNotFoundError:
  63.         print(f"Error: Could not find file {input_file}")
  64.         sys.exit(1)
  65.     except Exception as e:
  66.         print(f"Error: {str(e)}")
  67.         sys.exit(1)
  68.  
  69.  
  70. if __name__ == "__main__":
  71.     main()
  72.  

It's not battle-tested, just a first draft.

Example usage:

$ ./post_correction.py main.pas out.pas

Content of out.pas:

Code: Pascal  [Select][+][-]
  1.   n := 2;
  2.   If n < 0 Then
  3.     WriteLn('negative')
  4.   Else If n > 0 Then
  5.     WriteLn('positive')
  6.   Else
  7.     WriteLn('zero');
  8.  

Also works if you have a begin-end block under else-if.

Zvoni

  • Hero Member
  • *****
  • Posts: 3252
Re: ptop doesn't format "else if" well
« Reply #2 on: January 02, 2025, 01:10:25 pm »
https://www.freepascal.org/tools/ptop.html
At a guess (see example of manpage):
Code: [Select]
else=crbefore,dindonkey,inbytab
[else]=if,then,else
You need the "dindonkey"-option with the follow-up line "[else]"

EDIT:
Nope. i guessed wrong. Just played around with it.
Looks like some precedence-collision
« Last Edit: January 02, 2025, 01:34:09 pm by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

rgranger

  • Newbie
  • Posts: 1
Re: ptop doesn't format "else if" well
« Reply #3 on: January 24, 2026, 10:36:57 pm »
Ahh, I bet the same is going on with the on...do in exceptions. I also looked at the pascal-format build and it chokes on the compiler directives, so I guess ptop is it.


Code: Pascal  [Select][+][-]
  1.       If Resp = mrYes Then
  2.         Begin
  3.           Try
  4.             If Not ForceDirectories(MountDir) Then
  5.               Begin
  6.                 Log(Format('Failed to create mount point "%s".', [MountDir]));
  7.                 PlayFailureSound;
  8.                 Result := False;
  9.                 Exit;
  10.               End;
  11.           Except
  12.             on ECreate: Exception Do
  13.                         Begin
  14.                           Log(Format('Error creating mount point "%s": %s',
  15.                               [MountDir, ECreate.Message]));
  16.                           PlayFailureSound;
  17.                           Result := False;
  18.                           Exit;
  19.                         End;
  20.         End;

 

TinyPortal © 2005-2018