#!/bin/sh
# GPL_3+
cat << 'EEE' > /dev/null
/* Copyright (C) 2022 Momi-g
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
EEE

cat << 'EEE' > /dev/null
#SH_doc
title=ccmt section=1 repnl=\040
@name ccmt
@_brief grep c-lang cmt with visible/printf line oriented format
@_syno
	ccmt [-hHVBE] [files...]

@tl_dr
	@(code)@
	~$ printf '"//"\n /*-\n*/\n' | ccmt	#>> output /*-*/
	~$ ccmt a.txt b.txt		#>> cat a.txt b.txt|ccmt
	~$ ccmt <a.txt | while read -r a;do printf "$a"; done
	@()@

@_opt
	@(list_o)
	-h, -H, -V: usage, version
	-B: use BRE innercode for dbg (dfl)
	-E: use ERE innercode for dbg (use gnu-sed)
	files...: use src 'cat files...'. cat /dev/stdin is noarg.
	@()
@_desc
	`ccmt` grep c-lang cmt //, /**/. ccmt assumes the src doesnt holds 
	trigraphs ??X and long-line syntax \(\n). --
	output is 1-line == 1-cmt. non-printable chars is escaped as \001, \n and
	printf '$line' outputs raw comment strings.

@EXIT_STATUS
	always $? == 0. return !0 if the options is invalid.

@notes
	-
@conforming_to	posix-shell
@copyright
	Copyright (C) 2022 Momi-g --
	License GPLv3+ <https://gnu.org/licenses/gpl.html>
@_ver 2022-03-20 v1.0.1 (2022-03-18 v1.0.0)
@_see `sed(1)` --
	https://gcc.gnu.org/onlinedocs/gcc-3.2.3/cpp/Initial-processing.html
#SH_docE
EEE
f_usage(){
cat << 'EEE'
HowTo (ccmt - grep c-lang cmt)
opt: -v(inverse), -hHV(hHelp,version)
---
eg) ~$ printf 'aa //123\n bb'| ccmt	#>> //123
    ~$ printf 'aa /*\n -*/bb'| ccmt -v	#>> aa bb
EEE
exit 0
}

f_usage_H(){
 cat << 'E'|sed -e'1d;$d'
/*--copyfrom ccmt.1.txt*/
CCMT(1)                     General Commands Manual                    CCMT(1)



NAME
       ccmt - grep c-lang cmt with visible/printf line oriented format

SYNOPSIS
       ccmt [-hHVBE] [files...]

TL_DR
       ~$ printf '"//"\n /*-\n*/\n' | ccmt     #>> output /*-*/
       ~$ ccmt a.txt b.txt      #>> cat a.txt b.txt|ccmt
       ~$ ccmt <a.txt | while read -r a;do printf "$a"; done


OPTIONS
       -h, -H, -V
              usage, version

       -B     use BRE innercode for dbg (dfl)

       -E     use ERE innercode for dbg (use gnu-sed)

       files...
              use src 'cat files...'. cat /dev/stdin is noarg.

DESCRIPTION
       ccmt  grep c-lang cmt //, /**/. ccmt assumes the src doesnt holds  tri‐
       graphs ??X and long-line syntax \(\n).
       output is 1-line == 1-cmt. non-printable chars is escaped as  \001,  \n
       and printf '$line' outputs raw comment strings.

EXIT_STATUS
       always $? == 0. return !0 if the options is invalid.

NOTES
       -

CONFORMING_TO
       posix-shell

COPYRIGHT
       Copyright (C) 2022 Momi-g
       License GPLv3+ <https://gnu.org/licenses/gpl.html>

VERSION
       2022-03-20 v1.0.1 (2022-03-18 v1.0.0)

SEE_ALSO
       sed(1)
       https://gcc.gnu.org/onlinedocs/gcc-3.2.3/cpp/Initial-processing.html



                                                                       CCMT(1)
/*--copyend ccmt.1.txt*/
E
exit 0
}
f_version_info(){
cat << 'EEE'
ccmt v1.0.1
Copyright (C) 2022 Momi-g
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
EEE
exit 0
}

f_err(){ echo "`basename $0`:ERR: $*" >/dev/stderr; exit 1;}
f_msg(){ echo "`basename $0`:msg: $*" >/dev/stderr; }

set -e
#--

ccmt_main(){

	#--args
OPTIND=1
while getopts hHVBEv flg
do
	case $flg in
	h) f_usage;;
	H) f_usage_H;;
	V) f_version_info;;
#	v) opt_v=1;;
	B) opt_b=1;;
	E) opt_e=1;;
	'?') exit 1;;
	esac
done
shift $((OPTIND - 1))

	#--preset_dfl
incmd='cat /dev/stdin'
[ $# != 0 ] && incmd='cat "$@"'

# https://pubs.opengroup.org/onlinepubs/009695399/utilities/sed.html
# https://pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html

# ptn: yx...xy
# yx((a|b|y)*y|x*(a|b))*x+y
# yx(  [^x]*[y]  |  [x]*[^xy] )*  x+y		>> ERE only
# yx(  ([^x]*[y]){0,1}  ([x]*[^xy]){0,1} )*  x+y	>> conv to BRE
# yx(  ([^x]*[y])*  ([x]*[^xy])* )*  x+y		>> use repeat op '|' >> *

# HとGの二つしかメモリがないのでGの尻尾に突っこむ
# Hが終わったらGも同時に終わるので過程が飛ばされ結果だけが残る
cmd_b=$(cat << EEE
sed -ne '$ !{H;d;};H;g
:L

	## "..."
/^"\(\([\].\)*[^"\]*\)*"/{
s@^"\(\([\].\)*[^"\]*\)*"@@
b L
}

	## /*...*/	>>> yx(  [^x]*[y]  |  [x]*[^xy] )*  x+y
	# l >> invisible chars write with escstr, \a \001, \n etc
	# posix: '\n' isnt applicable >> means... read 1 line>>del eol \n >> ptn spc == no '\n' in ptnspc
\@^/[*]\(\([^*]*/\)*\([*]*[^*/]\)*\)*[*]\{1,\}/@{
h
s@\(\(^/[*]\(\([^*]*/\)*\([*]*[^*/]\)*\)*[*]\{1,\}/\)\)\(.*\)@\1@
l;g
s@^/[*]\(\([^*]*/\)*\([*]*[^*/]\)*\)*[*]\{1,\}/@@
h;b L
}

	## //...
\@^//[^\n]*\n@{
h
s@\(^//[^\n]*\n\).*@\1@
l;g
s@^//[^\n]*\n@@
h;b L
}

	## . rest
/./{
s@^.@@
b L
}
'
EEE
)

cmd_bv=$(cat << EEE
sed -ne '$ !{H;d;};H;g;
:l

	## "..."
/^"\(\([\].\)*[^"\]*\)*"/{
x
s@\(^"\(\([\].\)*[^"\]*\)*"\)\(.*\)@\4\1@
x
s@^"\(\([\].\)*[^"\]*\)*"@@
b l
}

	## /*...*/	>>> yx(  [^x]*[y]  |  [x]*[^xy] )*  x+y
\@^/[*]\(\([^*]*/\)*\([*]*[^*/]\)*\)*[*]\{1,\}/@{
x
s@^/[*]\(\([^*]*/\)*\([*]*[^*/]\)*\)*[*]\{1,\}/@@
x
s@^/[*]\(\([^*]*/\)*\([*]*[^*/]\)*\)*[*]\{1,\}/@@
b l
}

	## //...
\@^//[^\n]*\n@{
x
s@^//[^\n]*\n@@
x
s@^//[^\n]*\n@@
b l
}

	## . rest
/./{
x
s@\(^.\)\(.*\)@\2\1@
x
s@.@@
b l
}

x;p;q'
EEE
)

###########----
#ERE
cmd_e=$(cat << EEE
sed -nre '$ !{H;d;};H;g;
:L

	## "..."
/^"([\].|[^"\])*"/{
s@^"([\].|[^"\])*"@@
b L
}

	## /*...*/	>>> yx(  [^x]*[y]  |  [x]*[^xy] )*  x+y
\@^/[*]([^*]*[/]|[*]*[^*/])*[*]+[/]@{
h
s@(^/[*]([^*]*[/]|[*]*[^*/])*[*]+[/]).*@\1@
l;g
s@^/[*]([^*]*[/]|[*]*[^*/])*[*]+[/]@@
h;b L
}

	## //...
\@^//[^\n]*\n@{
h
s@(^//[^\n]*\n).*@\1@
l;g
s@^//[^\n]*\n@@
h;b L
}

	## . rest
/./{
s@^.@@
b L
}
'
EEE
)

cmd_ev=$(cat << EEE
sed -ne '$ !{H;d;};H;g;
:l

	## "..."
/^"([\].|[^"\])*"/{
s@(^"([\].|[^"\])*")(.*)@\1@p
x
s@"([\].|[^"\])*"@@
h
b l
}

	## /*...*/	>>> yx(  [^x]*[y]  |  [x]*[^xy] )*  x+y
\@^/[*]([^*]*[/]|[*]*[^*/])*[*]+[/]@{
s@^/[*]([^*]*[/]|[*]*[^*/])*[*]+[/]@@
h
b l
}

	## //...
\@^//[^\n]*\n@{
s@^//[^\n]*\n@@
h
b l
}

	## . rest
/./{
s@(^.).*@\1@p
x
s@.@@
h
b l
}

q'
EEE
)

#dfl:
cmd="$cmd_b"

gnu=0
echo |sed -re '' >/dev/null 2>&1 && gnu=1
[ "$opt_v" = 1 ] && cmd="$cmd_bv"
[ $gnu = 1 ] && [ "$opt_e" = "1" ] && cmd="$cmd_e"
[ $gnu = 1 ] && [ "$opt_e" = "1" ] && [ "$opt_v" = 1 ] && cmd="$cmd_ev"
cmd="$incmd|$cmd|sed -ne '"'/[\]$/{H;d;}
/[$]$/{H;s/.*//;x; s/^\n//g; s/[\]\n//g; s/[$]$//; p;d;}
a\
fatal error@postedit
'"'"
#printf '%s\n' "$cmd";exit 0
eval "$cmd"
}


ccmt_main "$@"	#SH_MAIN

cat << EEE >/dev/null
/*
 change log
 --
2022-03-20 Momi-g	<dmy@dmy.dmy>

	* ccmt (all): fix bre/ere regex, doc. v1.0.1.

2022-03-18 Momi-g	<dmy@dmy.dmy>

	* ccmt (none): init v1.0.0

*/
EEE
