모든 C 주석을 별도의 텍스트 파일로 인쇄하고 싶습니다.
- awk, sed, grep 또는 bash를 사용하세요.
- /* ... */(포함) 사이의 모든 여러 줄 C 주석을 출력합니다.
- // 주석이 포함된 출력 라인
- 선택사항: 줄 번호 인쇄
이 솔루션을 시도했지만 Ubuntu에서는 작동하지 않습니다
- C 스타일 여러 줄 주석 구문 분석
- https://stackoverflow.com/questions/57723357/how-can-i-grep-matching-a-comment-string
제가 요청한 목적은 소스 코드 주석을 좋은 문서화의 출발점으로 빠르게 사용할 수 있도록 하는 것입니다. 나는 전용 문서 프로그램(예: Doxygen)의 복잡하고 독점적인 내장 명령을 좋아하지 않습니다. 예를 들어, 각 소스 코드 함수에 적절하게 주석을 달고 피상적인 주석 줄을 제거하면 많은 시간이 절약되고 거의 완전한 참조가 제공됩니다. 이는 또한 더 나은 소스 코드 주석을 장려할 것입니다.
답변1
shell-magic을 사용하면 이미 많은 답변이 있지만 이미 가지고 있는 도구를 사용하면 더 쉽게 할 수 있다고 생각합니다. 즉, GCC입니다.
diff -u <(gcc -fpreprocessed -dD -E main.c) main.c | grep '^+' | cut -c 2-
어떻게 작동하나요?
gcc -fpreprocessed -dD -E main.c
파일에서 모든 주석을 제거하고 표준 출력에 넣습니다.diff -u <(...) main.c
stdout에서 입력을 받아 원본 데이터와 비교grep '^+'
로 시작하는 모든 줄을 필터링합니다+
. 즉, 이전에 식별된 댓글을 필터링합니다.cut -c 2-
+
출력에서 기호 제거
매우 복잡한 정규식, Perl 또는 awk 항목이 필요하지 않으며 다른 답변에서 놓쳤을 수 있는 모든 극단적인 경우도 포함합니다.
답변2
다음 사항을 고려하면 이는 생각만큼 간단하지 않습니다. s가 에 나타날 수 있다는 점을 puts("string with /*")
기억하세요 ."
ch = '"'
아니면 계속하세요:
printf("..."); /\
* yes, this is a comment */
/\
/ and this as well
또는트라이그램.
이러한 문제를 해결하기 위해 우리는 조정할 수 있습니다반대 질문에 대한 답변입니다주석을 제거하는 대신 인쇄하십시오.
perl -0777 -pe '
s{
(?<comment>
# /* ... */ C comments
/ (?<lc> # line continuation
(?<bs> # backslash in its regular or trigraph form
\\ | \?\?/
)
(?: \n | \r\n?) # handling LF, CR and CRLF line delimiters
)* \* .*? \* (?&lc)* /
| / (?&lc)* / (?:(?&lc) | [^\r\n])* # // C++/C99 comments
) |
"(?:(?&bs)(?&lc)*.|.)*?" # "strings" literals
| '\''(?&lc)*(?:(?&bs)(?&lc)*(?:\?\?.|.))?(?:\?\?.|.)*?'\'' # (w)char literals
| \?\?'\'' # trigraph form of ^
| .[^'\''"/?]* # anything else
}{$+{comment} eq "" ? "" : "$+{comment}\n"}exsg'
다른 질문의 인위적인 예에서는 대부분의 코너 케이스가 다뤄집니다.
#include <stdio.h>
int main()
{
printf("%d %s %s %c%c%c%c%c %s %s %d\n",
1-/* comment */-1,
/\
* comment */
"/* not a comment */",
/* multiline
comment */
// comment
/\
/ comment
// multiline\
comment
"// not a comment",
'"' /* comment */ , '"',
'\'','"'/* comment */,
'\
\
"', /* comment */
"\\
" /* not a comment */ ",
"??/" /* not a comment */ ",
'??''+'"' /* "comment" */);
return 0;
}
다음을 제공합니다:
/* comment */
/\
* comment */
/* multiline
comment */
// comment
/\
/ comment
// multiline\
comment
/* comment */
/* comment */
/* comment */
/* "comment" */
줄 번호를 얻으려면 입력을 한 번에 한 줄씩 처리하는 대신 주제가 전체 입력인 후루룩 소리 모드에서 실행하고 있기 때문에 약간 까다롭습니다. (?{code})
줄 구분 기호(C에서는 CR, LF 또는 CRLF)가 발견될 때마다 정규식 연산자를 사용하여 카운터를 증가시킴으로써 이를 수행할 수 있습니다 .
perl -0777 -pe '
s{
(?<comment>(?{$l=$n+1})
/
(?<lc> # line continuation
(?<bs> # backslash in its regular or trigraph form
\\ | \?\?/
) (?<nl>(?:\n|\r\n?) (?{$n++})) # handling LF, CR and CRLF line delimiters
)*
(?:
\* (?: (?&nl) | .)*? \* (?&lc)* / # /* ... */ C comments
| / (?:(?&lc) | [^\r\n])* # // C++/C99 comments
)
) |
"(?:(?&bs)(?&lc)*.|.)*?" # "strings" literals
| '\''(?&lc)*(?:(?&bs)(?&lc)*(?:\?\?.|.))?(?:\?\?.|.)*?'\'' # (w)char literals
| \?\?'\'' # trigraph form of ^
| (?&nl)
| .[^'\''"/?\r\n]* # anything else
}{$+{comment} eq "" ? "" : sprintf("%5d %s\n", $l, $+{comment})}exsg'
동일한 샘플에 대해 다음과 같이 가정합니다.
5 /* comment */
6 /\
* comment */
9 /* multiline
comment */
11 // comment
12 /\
/ comment
14 // multiline\
comment
17 /* comment */
18 /* comment */
21 /* comment */
26 /* "comment" */
답변3
이 작업은 awk
다음과 같이 수행할 수 있습니다.
#!/bin/awk
# Handles case where both /* and */ are on the same line
{ line_printed = 0; }
# Find the beginning of a multiline comment
/^[[:space:]]*\/\*/ {
multiline = 1;
# Remove leading spaces
sub(/^[[:space:]]+/,"");
printf "[%d] %s\n", NR, $0;
line_printed = 1;
}
# Find the end of a multiline comment
/\*\/[[:space:]]*$/ {
multiline = 0;
if (line_printed == 0)
printf "%s", $0;
print "\n"
next;
}
# The content between /* and */
{
if ( multiline == 1 && line_printed == 0 )
{
print $0;
next
}
}
# A single line comment
/^[[:space:]]*\/\// {
# Remove leading spaces
sub(/^[[:space:]]+/,"");
printf "[%d] %s\n\n", NR, $0;
}
이 스크립트를 다른 foo.awk
이름(또는 다른 이름, 확장자는 선택 사항)으로 저장하고 를 사용하십시오 awk -f foo.awk input.c
. 이 스크립트는 모든 주석(추가 줄 바꿈으로 구분)을 인쇄하고 각 주석 앞에 줄 번호를 추가합니다.
답변4
업데이트 2/15/24 - Raylib 사용법을 배우는 동안 소프트웨어 제품군에 포함된 C "파서"를 발견했습니다. 이 소프트웨어는 제가 필요로 했던 작업을 정확히 수행하는 것 같았습니다. 다음을 참조하세요.https://github.com/raysan5/raylib모든 구조, 정의, 함수, 콜백 등을 찾고 멋지게 형식을 지정하는 추가 이점이 있습니다.
전형적인 예
Function 232: DrawRectangleRounded() (4 input parameters)
Name: DrawRectangleRounded
Return type: void
Description: Draw rectangle with rounded edges
Param[1]: rec (type: Rectangle)
Param[2]: roundness (type: float)
Param[3]: segments (type: int)
Param[4]: color (type: Color)