m4n.sh 1012 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. die() {
  2. printf '%s: ' $(basename $0)
  3. printf "$@" >&2
  4. exit 1
  5. }
  6. get_file_type() {
  7. if (head -n1 $1 | grep -q m4npage); then
  8. echo m4n
  9. return
  10. fi
  11. if grep -q 'int main' $1; then
  12. echo utility
  13. return
  14. fi
  15. # TODO: detect other types
  16. echo function
  17. }
  18. m4n_m4n() {
  19. cat
  20. }
  21. utility_m4n() {
  22. cat <<-EOF
  23. m4npage($1, utility)
  24. brief(something)
  25. describe(is a program.)
  26. EOF
  27. }
  28. function_m4n() {
  29. cat <<-EOF
  30. m4npage($1, function)
  31. brief(something else)
  32. describe(is a function.)
  33. EOF
  34. }
  35. main() {
  36. while getopts O: opt; do
  37. case $opt in
  38. O)
  39. if ! command -v "${OPTARG}_m4" >/dev/null 2>/dev/null; then
  40. die 'invalid output type %s\n' "$OPTARG"
  41. fi
  42. om4=${OPTARG}_m4
  43. ;;
  44. ?) exit 1;;
  45. esac
  46. done
  47. shift $((OPTIND - 1))
  48. if [ $# -lt 1 ]; then
  49. die 'missing operand\n'
  50. elif [ $# -gt 1 ]; then
  51. die 'too many operands\n'
  52. fi
  53. type=$(get_file_type $1)
  54. if [ $type != "m4n" ]; then
  55. # TODO: handle -O output (default to M4N)
  56. ${type}_m4n $1
  57. else
  58. ${om4:-text_m4} $1 | m4
  59. fi
  60. }
  61. main "$@"