Skip to content

Instantly share code, notes, and snippets.

@imaami
Created December 20, 2023 19:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save imaami/5acdbca38b1f49468f680a1aa04493fe to your computer and use it in GitHub Desktop.
Save imaami/5acdbca38b1f49468f680a1aa04493fe to your computer and use it in GitHub Desktop.
Let GPT describe how your code sucks.
#!/usr/bin/env bash
#
# IMPORTANT: The HTTP authorization header must be found
# in ~/.openai in full, not just the API key.
#
# Usage: ./documentarist.sh [options] /path/to/file.c
#
# Requirements: dos2unix, cpp, clang-format, jq, curl
#
unset blind i name src sym tmp
declare -i blind=0 i=1
while (( i < $# )); do
tmp="${@:i:1}"
case "$tmp" in
--blind|-b)
blind=1
shift
;;
--symbol|-s)
shift
sym="${@:i:1}"
shift
;;
--symbol=*)
sym=${tmp:9}
shift
;;
-s*)
sym=${tmp:2}
shift
;;
*)
(( ++i ))
;;
esac
done
unset tmp
[[ -f "$1" ]] && name="${1##*/}" &&
tmp=$(mktemp -d) && [[ -d "$tmp" ]] || exit 1
src="$tmp/$name"
dos2unix < "$1" > "$src"
if (( blind )); then
cpp -fpreprocessed -dD -P -o "$src.i" "$src" 2>/dev/null
if [[ -f "$src.i" ]]; then
mv "$src.i" "$src"
fi
fi
[[ -f "$src" ]] || { rm -fr "$tmp"; exit 1; }
clang-format --style='{BasedOnStyle: webkit, IndentWidth: 8,
TabWidth: 8, UseTab: ForIndentation}' -i "$src"
if [[ "$sym" ]]; then
sym="$(sed -E 's/([[:blank:]]*\.)?[[:blank:]]*$//' <<< "$sym")"
if [[ "$sym" ]]; then
sym=",{\"role\":\"user\",\"content\":\"Document \`${sym//\"/\\\"}\`.\"}"
fi
fi
jq --rawfile source <(
printf '```\n/** @file %s\n */\n' "$name"
cat "$src"
printf '\n```'
) -Mnc --rawfile system <(cat << \EOF
You document C/C++ code using Doxygen syntax. You are given the code and told which function, type, macro, etc. to document. Write the requested documentation and print the documented declarations.
To be clear: you read code that contains full definitions, but you print only declarations with documentation added on top. For example
```
int foo (int *bar) {
*bar *= 9;
return *bar ^ ~0;
}
```
might become
```
/**
* @brief Toggle bar.
* @param bar The bar to modify.
* @return Result status.
* @retval 0 no error.
* @retval EFAULT @p bar is an invalid address.
*/
int foo (int *bar);
```
Important points:
- Not all things that you are asked to document will be functions. Pay attention to what the symbol actually is.
- Your output will be placed in header files. Do not waste space by repeating lines from the input other than the relevant declaration.
- Do not print a function body when documenting a function. Output stops after the argument list's closing parenthesis and a semicolon.
- Macro documentation can include a definition if it is short. Otherwise the documentation, macro name, and args list (if any) suffice.
- Each "@retval" describes one possible return value, no more. Add multiple "@retval" lines if necessary.
- "@retval" does not exclude "@return".
EOF
) '{
"model": "gpt-4",
"stream": false,
"messages": [
{"role":"system","content":$system},
{"role":"user","content":$source}'"$sym"'
]
}' \
| curl https://api.openai.com/v1/chat/completions -s -S -d @- \
-H @"$HOME/.openai" -H Content-Type:\ application/json \
| jq -r '.choices[0].message.content'
rm -fr "$tmp"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment