···11-#!/usr/bin/env bash
22-# Split a generated C-file into the command used to generate it,
33-# and the outputted code itself.
44-55-# This is useful because it allows input and output to be inside the same file
66-77-# How it works:
88-# - The first line needs to start with '//' (and becomes the command).
99-# - Whitespace/padding between the comment and the generated code is ignored
1010-# - To write a command using multiple lines, end each line with backslash (\)
1111-1212-# Count the number of lines before the output text starts
1313-# commandLineCount FILE
1414-commandLineCount() {
1515- local n state
1616- n=0
1717- state="init"
1818- while IFS="" read -r p || [ -n "$p" ]; do
1919- case $state in
2020- init)
2121- if [[ $p =~ ^//.*\\$ ]]; then state="comment"
2222- elif [[ $p =~ ^//.* ]]; then state="padding"
2323- else break
2424- fi
2525- ;;
2626- comment) [[ ! $p =~ ^.*\\$ ]] && state="padding";;
2727- padding) [ -n "${p// }" ] && break;;
2828- esac
2929- n=$((n+1))
3030- done < "$1"
3131- printf '%s' "$n"
3232-}
3333-3434-# getInputCommand FILE
3535-getInputCommand() {
3636- n=$(commandLineCount "$1")
3737- head -n "$n" "$1" | awk '{ if (NR == 1) print substr($0, 3); else print $0 }'
3838-}
3939-4040-# getOutputText FILE
4141-getOutputText() {
4242- n=$(commandLineCount "$1")
4343- sed "1,${n}d" "$1"
4444-}