Example PROTFORM.PRT
; PROTFORM
;
; Program for Proteus
;
; (C) 1998-2004 Simone Zanella Productions
;
; Pretty-printer for Proteus programs: add standard formatting,
; keeping line length below 75 characters;
; vanilla syntax check.
;
; This is the standard formatting (!ifdef..!endif just like IF..FI):
;
; IF test           REPEAT              SWITCH exp [func]
;   method            method            ON exp1
; ELSE                CONTINUE            method
;   method            BREAK             ONC exp2
; FI                UNTIL test            method
;                                       OTHER
;                                         method
;                                       OFF
;
; WHILE test        FUNCTION name([par1, [par2..]])
;   method            method
;   CONTINUE        RETURN value
;   BREAK
; LOOP
;
; FOR id = exp1 TO exp2 [STEP exp3]
;   method
;   CONTINUE
;   BREAK
; NEXT

; !bdoc..!edoc blocks, just like TEXT constants, are left unmodified.

; Initialize program
FUNCTION ONSTART()

  IF STREQ(ARGV(3), "..")
    CONSOLELN "Syntax: " ARGV(1) " " ARGV(2) " source destination"
    CONSOLELN ""
    CONSOLELN "Purpose: format source into destination (Proteus pretty-printer)"
    ABORT 0
  FI

  _IndLev = 0
  _LastLine = ""
  _LineLength = 75

  ; Increase indentation for the following methods
  _MI = VECCREATE("FOR","REPEAT","WHILE","IF","FUNCTION",\
                  "SWITCH","!ifdef","!ifndef")

  _RetVar = "RETURN"

  ; Decrease indentation for the following methods
  _MD = VECCREATE("LOOP","UNTIL",_RetVar,"OFF",\
                  "FI","NEXT","!endif")

  ; Delete indentation for current line, keeping it for the following lines
  _MS = VECCREATE("ON","ONC","ELSE","OTHER","!else")

  ; Sort arrays, for using BSEARCH
  SORT(_MI, 4, 1)
  SORT(_MD, 4, 1)
  SORT(_MS, 4, 1)

  _InDoc = 0
  _InText = 0
RETURN

; Print TEXT constants as they are
; Stampa le costanti TEXT verbatim
IF InText
  S = RTRIM(L, " \t")
  IF STREQ(RIGHT(S, STRLEN(TextTerm)), TextTerm)
    InText = 0
  FI
  PRINTLN L
  IGNORE
FI

; Print blocks between !bdoc and !edoc as they are
IF InDoc
  S = TOKEN(LTRIM(L, " "), 1, " ")
  SWITCH S STRIEQ
    ON "!BDOC"
      INC(@InDoc)
    ON "!EDOC"
      DEC(@InDoc)
      IF LT(InDoc, 0)
        CONSOLELN "Too many \"!EDOC\" directives (line " N " )"
        ABORT 1
      FI
  OFF
  PRINTLN L
  IGNORE
FI

PL = ALLTRIM(L, " ")

; Splitted line - merge it
IF STREQ(RIGHT(PL, 1), "\\")
  IF ISNOTEMPTY(LastLine)
    LastLine = LastLine " "
  FI
  LastLine = LastLine LEFT(PL, DEC(STRLEN(PL)))
  LastLine = RTRIM(LastLine, " ")
  IF EOF
    CONSOLELN "Unterminated line (" N ")"
    ABORT 1
  FI
  IGNORE
FI

; Add last segment at the end of a splitted line
IF ISNOTEMPTY(LastLine)
  LastLine = LastLine " " PL
  PL = RTRIM(LastLine, " ")
  LastLine = ""
FI

OldLev = IndLev

; Method name
FTok = UPPER(TOKEN(PL, 1, " "))

; Find method in arrays
IF ISNOTEMPTY(FTok)
  X = BSEARCH(MI, 4, FTok)
  IF X
    ; Increase indentation
    INC(@IndLev)
  ELSE
    X = BSEARCH(MD, 4, FTok)
    IF X
      ; If RETURN, decreases indentation only when the function declaration is completed
      IF OR(EQ(IndLev, 1), STRINEQ(FTok, RetVar))
        ; Decrease indentation
        DEC(@IndLev)
      FI
    ELSE
      X = BSEARCH(MS, 4, FTok)
      IF X
        ; Decrease indentation for this line only
        OldLev = DEC(IndLev)
      ELSE
        ; Check if line is special (!BDOC, TEXT..)
        SWITCH Ftok STRIEQ
          ON "!EDOC"
            CONSOLELN "Too many \"!EDOC\" directives (line " N " )"
            ABORT 1
          ON "!BDOC"
            INC(@InDoc)
            PRINTLN L
            IGNORE
          ON "TEXT"
            InText = 1
            X = POSTOKEN(L, 3, " ")
            IF STREQ(SUBSTR(L, X, 1), "=")
              TextTerm = RESTFROM(L, POSTOKEN(L, 4, " "))
            ELSE
              TextTerm = RESTFROM(L, X)
            FI
            IF STREQ(LEFT(TextTerm, 1), "\"")
              RTRIM(@TextTerm, " ")
              STRIPQUOTES(@TextTerm)
              CTRAN(@TextTerm)
            ELSE
              ; Forces the interpretation of TextTerm as a number
              ADD(@TextTerm, 0)
            FI
            PRINTLN L
            IGNORE
        OFF
      FI
    FI
  FI
FI

; Syntax error
IF LT(IndLev, 0)
  CONSOLELN "Syntax error in program " F "!"
  ABORT 1
FI

; Indentation increased - print line with old indentation
IF GT(IndLev, OldLev)
  NL = REPLICATE(" ", MUL(OldLev, 2))
ELSE
  ; Print line with current indentation
  NL = REPLICATE(" ", MUL(IndLev, 2))
FI

Line = NL PL

; Line too long: split
IF GT(STRLEN(Line), LineLength)

  TL = STRDUP(Line)
  RL = ""
  P = STRLEN(Line)

  ; If remark, split on spaces
  IF IN(LEFT(PL, 1), ";#")
    WHILE GT(P, 0)
      Car = RIGHT(TL, 1)
      DEC(@P)
      RL = Car RL
      TL = LEFT(TL, P)

      ; Line can be truncated only on spaces
      IF LE(P, LineLength)
        WHILE AND(P, STRNEQ(Car, " "))
          Car = RIGHT(TL, 1)
          DEC(@P)
          RL = Car RL
          TL = LEFT(TL, P)
        LOOP
        ; Space found
        IF P
          PRINTLN TL " \\"
          TL = RL
          RL = ""
          P = STRLEN(TL)
          IF LE(P, LineLength)
            BREAK
          FI
          CONTINUE
        FI
      FI
      ; A line without spaces? Don't truncate, keep it.
      IF NOT(P)
        TL = RL
      FI
    LOOP
  ELSE
    WHILE GT(P, 0)
      Car = CHOP(@TL)
      DEC(@P)
      RL = Car RL

      ; End of string: find start
      IF STREQ(Car, "\"")
        Car = CHOP(@TL)
        DEC(@P)
        RL = Car RL
        WHILE AND(P, \
                    OR(STRNEQ(Car, "\""), \
                       STREQ(SUBSTR(TL, P, 1), "\\") ) )
          Car = CHOP(@TL)
          DEC(@P)
          RL = Car RL
        LOOP
        IF AND(NOT(P), STRNEQ(LEFT(RL, 1), "\""))
          CONSOLELN "Unterminated string at line " N "."
          ABORT 1
        FI
      FI

      IF NOT(P)
        TL = RL
        P = 0
      ELSE
        IF LT(P, LineLength)
          IF IN(Car, ",() ")
            ; Line can be truncated here            

            TL = TL Car
            RL = RIGHT(RL, DEC(STRLEN(RL)))
            PRINTLN TL IIF(STREQ(Car, " "), "\\", " \\")
            TL = RL
            RL = ""
            P = STRLEN(TL)
            IF LE(P, LineLength)
              BREAK
            FI
            CONTINUE
          FI
        FI
      FI
    LOOP
  FI
  PRINTLN TL
ELSE
  PRINTLN Line
FI
Samples index Next example Previous example Contents Index
Midnight Lake iPhone Case Black Women Shoes Black Flat Shoes Leather Flats Black Patent Ballerinas Black Ballet Shoes Casual Shoes Black Shoes Women Balle Record Player Cufflinks Best iPhone XR Clear Cases iPhone XS/XS Max Leather Cases Sale Best iPhone 8/8 Plus Silicone Cases iPhone 7/7 Plus Cases & Screen Protector New Cases For iPhone 6/6 Plus iPhone 8 Case Sale iPhone Xr Case Online iPhone 7 Case UK Online iPhone X Case UK Sale iPhone X Case Deals iPhone Xs Case New Case For iPhone Xr UK Online Case For iPhone 8 UK Outlet Fashion Silver Cufflinks For Men Best Mens Cufflinks Outlet Online The Gold Cufflinks Shop Online Cheap Shirt Cufflinks On Sale Nice Wedding Cufflinks UK Online Top Black Cufflinks UK Online Mens Cufflinks Online Silver Cufflinks For Men Men Cufflinks UK Sale Gold Cufflinks UK Online Gold Cufflinks UK Silver Cufflinks UK Shirt Cufflinks Discount Online Mens Cufflinks Deals & Sales Girls Shoes For Dance Fashion Ballet Dance Shoes Best Ballet Flats Shoes UK Online Cheap Ballet Pointe Shoes UK Online Best Ballet Shoes Outlet Best Dance Shoes Sale Cheap Ballet Flats Sale UK Best Pointe Shoes Online UK Ballet Dance Shoes UK Shoes For Dance UK Best Ballet Slippers Shop Best Yoga Shoes Hotsell