Introduction
做一个Bash的解析器,类似于IDE的代码自动对齐功能。原理不难,但是用Bash实现就是调试挺麻烦的。
Requirement
Write a bash script to indent code blocks in a bash source file.
Conditions:
- The source file will contain only printing characters, spaces, and newlines.
- The source file will contain only valid bash code. It is not necessary to check for invalid input.
- The source file will not contain function declarations.
- The source file may contain random indentation.
- The source file may contain nested blocks.
- In the source file keywords while/until/for/case/if/done/esac/elif/else/fi will be the first words on a line and will not be quoted.
Requirements:
- Read from standard input, write to standard output.
- Lines inside a while/until/for block should indented two spaces. If the block’s done is the first word on a line it should begin in the same column as the while/until/for .
- Lines inside a case block should indented two spaces. If the block’s esac is the first word on a line it should begin in the same column as the case .
- Lines inside an if block should indented two spaces. If the block’s elif/else/fi is the first word on a line it should begin in the same column as the if .
- Lines with # in the first column should not be indented.
- Lines not inside any block should not be indented.
Be sure your program includes all of the following:
- comments with your name, the date, and the assignment
- comments with instructions for using the program
- descriptive names and/or comments explaining variables & functions
- indentation of code blocks
- comments explaining any non-obvious control flow
Example
Before
# comment in first column
Final=$(date -d "2016-05-24 16:00" "+%j")
while true
do
Today=$(date "+%j")
Days=$((Final - Today))
if (( Days >= 14 ))
# comment not in first column
then party
elif (( Days >= 2 ))
then study
elif (( Days == 1 ))
then panic
else
break
fi
sleep 8h
done
vacation
After
# comment in first column
Final=$(date -d "2016-05-24 16:00" "+%j")
while true
do
Today=$(date "+%j")
Days=$((Final - Today))
if (( Days >= 14 ))
# comment not in first column
then party
elif (( Days >= 2 ))
then study
elif (( Days == 1 ))
then panic
else
break
fi
sleep 8h
done
vacation