indent.bac

'------------------------------------------------
' Small utility to indent BaCon code.
' (c) PvE - Nov 2014 - GPL.
'------------------------------------------------

' Get command line arguments
REPEAT
	option = CMDLINE("h?")
	SELECT CHR$(option)
		CASE "?";
		CASE "h"
			PRINT "Usage: indent <prog.bac>"
			END 1
	END SELECT
UNTIL option = -1

' Does the file exist?
IF NOT(FILEEXISTS(ARGUMENT$)) THEN
	PRINT "Error: file not found!"
	END 1
ENDIF

' Open the file
OPEN ARGUMENT$ FOR READING AS myfile

' Initialize
myposition = 0
nextposition = 0
label_active = FALSE

' Start file reading
WHILE NOT(ENDFILE(myfile))

	' Start with new line
	line$ = ""

	' Read line, concatenate multiline statements
	WHILE TRUE
		READLN data$ FROM myfile
		' Cleanup the line by chopping off TAB, space, NL, CR
		line$ = line$ & CHOP$(data$)
		' If there is a multiline statement, add a NL and a TAB
		IF RIGHT$(line$, 1) = "\\" THEN line$ = line$ & CHR$(10) & CHR$(9)
		ELSE BREAK
	WEND

	' Set my current position
	myposition = nextposition

	' Handle LABEL indentation
	IF LEN(line$) = 0 AND label_active THEN
		label_active = FALSE
		DECR myposition
		nextposition = myposition
	FI

	' Current line backwards indentation
	IF REGEX(line$, "^(CASE|UNTIL)[ \\t]|^(DEFAULT|FI|NEXT|WEND)|^ELSE$|^ELIF.+THEN$|^END.+") THEN
		' End with value should not indent backwards
		IF NOT(REGEX(line$, "^END.+[0-9]+")) THEN DECR myposition
		' Extra step back with ENDSELECT
		IF REGEX(line$, "SELECT$") THEN DECR myposition
		' Tab not out of screen?
		IF myposition < 0 THEN myposition = 0
		nextposition = myposition
	ENDIF

	' Next line indentation
	IF REGEX(line$, "^(CASE|ENUM|FOR|FUNCTION|GLOBAL RECORD|LABEL|RECORD|SELECT|SUB|WHILE|WITH)[ \\t]|^(DEFAULT|REPEAT|USEC|USEH)|^IF.+THEN$|^ELIF.+THEN$|^ELSE$") THEN
		INCR nextposition
		' The CASE right after SELECT should indent extra
		IF REGEX(line$, "^SELECT") THEN INCR nextposition
		' Set flag if we are in a LABEL
		IF LEFT$(line$, 5) = "LABEL" THEN label_active = TRUE
	FI

	' Print result on screen
	IF NOT(ENDFILE(myfile)) THEN
		IF LEN(line$) THEN
			FOR str$ IN line$ STEP CHR$(10)
				PRINT TAB$(myposition), str$
			NEXT
		ELSE
			PRINT
		FI
	ENDIF
WEND

CLOSE FILE myfile

Generated by GNU Enscript 1.6.5.90.