#!/bin/sh
# GPL_3+
cat << 'EEE' > /dev/null
/* Copyright (C) 2021 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

set -ue
# posix: 2.5.3 Shell Variables
#If the shell is not currently executing a script or function, the value of LINENO is unspecified. 
#--- from license: cc-by-sa 3.0 (code is changed from the orig)
# https://stackoverflow.com/questions/17804007	Q: dspjm  ->  A: devnull
PS4='${LINENO-noPsx+}: '
#--- end license:	cc-by-sa 3.0

d_input=""
main(){
cmd=$(cat << 'END'   # 'END'.. not expand $foo etc. 
# opt dfl  type	( +add command you want to test input opt)	
	-h  0		bool	'usage'
	-H  0		bool	'usage_H'
	-1  0		bool	'usage_1'
	-3  0		bool	'usage_3'
	-7  0		bool	'usage_7'
	-V  0		bool	'version_info'
	-D  ""		str		'read_D "$opt_D"'
END
)
buf=`$exdir/ckopt "$cmd"`  #..or.. "$cmd"  (colon, quiet err mode as getopts )
eval "$buf"

if [ $# = 0 ];then
	set -- /dev/stdin
fi

cmd="awk $d_input "' -v exdir="$exdir" "$code"'
# printf '%s\n' "$repnl"
# printf '%s\n' "$cmd"
# exit 0
eval "$cmd"<$1
}

code=$(cat<<'EEE'
BEGIN{
	gflg= -1
	idx=0
	eflg=0
	hname=0
	
	flname=exdir "/amn_cmn.ped"
	amn_cmn=""
	while( (getline buf<flname) > 0){ amn_cmn=amn_cmn "\n" buf }
	close(flname)
	amn_cmn="$(cat<<'E E'\n" amn_cmn "\nE E\n)\n"

	flname=exdir "/amn_cmd.ped"
	amn_cmd=""
	while( (getline buf<flname) > 0){ amn_cmd=amn_cmd "\n" buf }
	close(flname)
	amn_cmd="$(cat<<'E E'\n" amn_cmd "\nE E\n)\n"

	flname=exdir "/amn_cfunc.ped"
	amn_cfunc=""
	while( (getline buf<flname) > 0){ amn_cfunc=amn_cfunc "\n" buf }
	close(flname)
	amn_cfunc="$(cat<<'E E'\n" amn_cfunc "\nE E\n)\n"
	split("", darr)
	darr["mk"]   = "@"		#cmn_mk
	darr["hlop"]= "\047"	#cmn_hlop
	darr["hlcl"]= "\047"	#cmn_hlcl
	darr["tagop"]= "("		#cmn_tagop
	darr["tagcl"]= ")"		#cmn_tagcl
	darr["lbdlm"]= ":"		#cmn_tagcl
	darr["brstr"]= "--"		#cmn_brstr
	darr["ulstr"]= "_"		#cmn_ulstr
	darr["repnl"]= ""		#cmn_repnl

	darr["title"]= "no_title"
	darr["section"]= 1

	if(mk!=""   ){ darr["mk"]   =mk   ; Darr["mk"]   =1 }	#cmn_mk
	if(hlop!=""){ darr["hlop"]=hlop; Darr["hlop"]=1 }	#cmn_hlop
	if(hlcl!=""){ darr["hlcl"]=hlcl; Darr["hlcl"]=1 }	#cmn_hlcl
	if(tagop!=""){ darr["tagop"]=tagop; Darr["tagop"]=1 }	#cmn_tagop
	if(tagcl!=""){ darr["tagcl"]=tagcl; Darr["tagcl"]=1 }	#cmn_tagcl
	if(lbdlm!=""){ darr["lbdlm"]=lbdlm; Darr["lbdlm"]=1 }	#cmn_tagcl
	if(brstr!=""){ darr["brstr"]=brstr; Darr["brstr"]=1 }	#cmn_brstr
	if(ulstr!=""){ darr["ulstr"]=ulstr; Darr["ulstr"]=1 }	#cmn_ulstr
	if(repnl!=""){ darr["repnl"]=repnl; Darr["repnl"]=1 }	#cmn_ulstr

	if(title!=""){    darr["title"]   = title   ; Darr["title"]   =1 }
	if(section!="" ){ darr["section"] =	section	; Darr["section"] =1 }
	if(footer !="" ){ darr["footer"]  =	footer	; Darr["footer"]  =1 }
	if(footer_l!=""){ darr["footer_l"]=	footer_l; Darr["footer_l"]=1 }
	if(header!=""  ){ darr["header"]  =	header	; Darr["header"]  =1 }
	#footer, footer_l, headerは基本無し
}

isSH() && gflg== -1 {
	gflg=0
	for(k in darr){
		v=darr[k]
		gsub("'", "\\'", v)
		v="'" v "'"
		rg="\n[^\n]*#cmn_" k "\n"
		rep="\ncmn_" k "<- " v "\n"
		if(k=="repnl"){ rg="cmn_" k; rep=v }	#cmn_repnl
# print(k "@" v "@") > "/dev/stderr"
		sub(rg, rep, amn_cmn)
		sub(rg, rep, amn_cmd)
		sub(rg, rep, amn_cfunc)
	}
# print(darr["brstr"] 123) >"/dev/stderr"
# print(amn_cmn) >"/dev/stderr"
}

gflg== -1 {
	for(i=1;i<=NF;i++) {
		if( match($i,/[=]/)==0){continue}
		match($i,/^[^=]+/)
		k=substr($i, RSTART, RLENGTH)
		if( Darr[k] ){continue}
		if(0==match("title section footer footer_l header mk hlop hlcl tagop tagcl lbdlm brstr ulstr repnl", k) ) {
			printf( "ERR: key must be title,section,footer,footer_l,header,mk,hlop/cl,tagop/cl,lbdlm,brstr,ulstr,repnl: %s\n", $0) > "/dev/stderr"
			eflg=1
			exit(1)
		}
		sub(/^[^=]+=/, "", $i)
		v=$i
		if(match(v, /[ \t\n\r]/) ){
			printf( "ERR: detect \\s\\t\\n\\r in define words: %s\n", $0) > "/dev/stderr"
			eflg=1
			exit(1)
		}
#print(darr[k]) >"/dev/stderr"
		darr[k]=o2s(v) 
#print(i k v 123 darr[k]) >"/dev/stderr"
	}
	next
}

!hname{ sarr[gflg]=sarr[gflg] $0 "\n"; next }
hname {
		 if( hname=="_SYNO") { hname= "SYNOPSIS" }
	else if( hname=="_OPT" ) { hname= "OPTIONS"  }
	else if( hname=="_DESC") { hname= "DESCRIPTION" }
	else if( hname=="_EG"  ) { hname= "EXSAMPLE" }
	else if( hname=="_VER" ) { hname= "VERSION"  }
	else if( hname=="_SEE" ) { hname= "SEE_ALSO" }

	$1=""
	sub(/^[ \t]*/, "", $0)
	if(NF==0){ sarr[hname]=sarr[hname] darr["brstr"] "\n" }
	else { sarr[hname]=sarr[hname] darr["brstr"] "\n" $0 "\n" }
	idx++
	narr[idx]=hname
	gflg=hname
	next
}
END{
	if(eflg){ exit(eflg) }
	if( "_BRIEF" in sarr){
		sub(/\n$/, "", sarr["NAME"])
		buf = substr(sarr["_BRIEF"], length(darr["brstr"])+2)	#\n
		sarr["NAME"] = sarr["NAME"] " - " buf
	}
	printf(".TH %s %s %s %s %s\n", toupper(darr["title"]), darr["section"],
		darr["footer"], darr["footer_l"], darr["header"] )
	for(i=1;i in narr;i++){
		label=narr[i]
		if(label=="_BRIEF"){continue}
		str=sarr[label]
		output(label, str)
	}
}

function isSH(label	,str ,buf ,dmy, rc){
	buf= darr["mk"] darr["tagop"]
	hname= ((index($0, darr["mk"])==1) && (index($0, buf)!=1))
	if(! hname){ return 0 }

	dmy= substr($1,  length(darr["mk"])+1)
	buf= toupper(o2s(dmy))
	hname=buf
	if(label==""){ return hname=buf}
	if(buf== toupper(label) ){ return hname=buf }
	return hname=0
}

function output(key, str	,buf ,dmy){
#print(darr["section"] key) > "/dev/stderr"
	buf=""
	if(key=="SYNOPSIS" && darr["section"]==1){
		buf="a=" amn_cmd exdir "/ped -re \"$a\"|sed -e '1,2d'"
		printf(".SH SYNOPSIS\n")
		printf("%s\n", str) | buf
		close(buf)
#printf("\n")
		return 0
	}
	if(key=="SYNOPSIS" && (darr["section"]==2||darr["section"]==3) ){
		buf="a=" amn_cfunc exdir "/ped -re \"$a\"|sed -e '1,2d'"
		printf(".SH SYNOPSIS\n")
		printf("%s\n", str) | buf
		close(buf)
#printf("\n")
		return 0
	}
# others
	buf="a=" amn_cmn exdir "/ped -re \"$a\"|sed -e '1,2d'"
	printf(".SH %s\n", key)
	printf("%s\n", str) | buf
	close(buf)
#printf("\n")
	return 0
}

function o2s(str	,buf){
	if(length(str)==0){return ""}
	cmd="printf \"$(cat<<'E E'\n" str "\nE E\n)\""
	cmd | getline buf
	close(cmd)
	return buf

	buf=""
	while(1){
		match(str, /[\\][0-3][0-7][0-7]/)
		if(RSTART==0){ str=buf str; break }
		buf=buf substr(str, 1, RSTART-1)
		dmy=substr(str, RSTART+1, 3)
		str=substr(str, RSTART+4)
		dmy=substr(dmy,1,1)*64 +substr(dmy,2,1)*8 +substr(dmy,3,1)
		buf=buf sprintf("%c", dmy)
	}
	return buf
}
EEE
)

read_D(){
	k=${1%%=*}
	buf=" title section footer footer_l header mk hlop hlcl tagop tagcl lbdlm brstr ulstr repnl title section footer footer_l header "
	if [ "${buf##* $k *}" != "" ];then
		printf "ERR: -Dtitle='abc' etc. allow keys:\n$buf\n" >/dev/stderr
		echo " ...bad key: $1">/dev/stderr
		exit 1
	fi
	v=${1#*=}
	set -- "$v"
	eval "$k="'"$1"'
	d_input="$d_input -v $k"'="$'"$k"'"'
}
	
version_info(){
cat << 'EEE'
amn v1.0.0
Copyright (C) 2021 Momi-g
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
EEE
exit 0
}

usage(){
cat << 'EEE'
HowTo (amn - manpage maker)
opt: -hH(elp), -V(er), -D(ef), -137(sample output)
---
eg) ~$ amn -1	#>> copy & run output code 
   
    ~$ echo "
@name myapp - amn     'ignores' '_blanks'/nl same as html
@synopsis mycomm [-a|-b] [-d word] words
	" | amn | man /dev/stdin

 amn makes a manpage from plain text. syntax is:
    @str   : section header, .SH, <h2> etc. set to BOL
    'str'  : bold (and you can use as space holder, '  str')
    '_str' : underline
    ''str'': no highlight. ''it's good'' == it@'s good
    --(\n) : break, <br>. amn skips newline and tab
    @(...) : other format/setting tag

 @SYNOPSIS block is highlighted automatilcally.
 see detail: ~$ amn -H  ..or..  ~$ amn -H |amn |man /dev/stdin
EEE
exit 0
}

usage_H(){
cat << 'EEE'
title=AMN section=1
repnl=\040	//dfl is '', change nl to \s for latin-langages
@name amn
@_brief man maker
@_syno amn [-hHV137] [-D key=str] [file|stdin]
@tl;dr
	make man:

	@(code)--
	~$ amn <<- EEE
	@name hw - hello, world
	@synopsis hw [-hH] file...
	@description disp 'hello', '_world'
	EEE
	
	~$ amn <<- EEE |man /dev/stdin 
	title=xyz section=3
	@name hw - hello, world
	@_syno
	#include "hw.h"
	int hw(int ac, char** av);
	@_desc use c-func parser in @synopsis if section is '_2' or '3'
	EEE
	@()--

	read from '_stdin' if ag1 '_file' isnt exist
	@(code)
	~$ anm src.txt
	~$ anm <src.txt
	~$ cat src.txt | anm | man /dev/stdin
	~$ cat src.txt | anm -D title=abc 
	@()
@_opt
	@(list_o)
	-h, -H, -V:	print usage, version info
	-1, -3, -7:	output sample command
	-D key=str: overwrite default settings
	@()
	opt '-D' '_key' are the below. val '_str' \[\abfnrtv], \ooo, \xhh is converted.
	null-char \0 causes undefined results. 
	@(pre)@
	'  mk   ': tag marker. used for charesc too. dfl=@'@@@'
	'  hlop ': bold/underline highlight block open. dfl=\047 (single quote)
	'  hlcl ': close. dfl=\047
	'  ulstr': underline flag. dfl=@'_@'. @'_str@' makes underline, '_str'
	'  tagop': tag open. @@(pre) etc. dfl=@'(@'
	'  tagcl': close. dfl=@')@'
	'  lbdlm': works only in @(list), -a@: info..., etc. dfl=@':@'
	'  brstr': break marker. dfl=@'--@'. --(\n) works as <br>.
	'  repnl': replace nl. dfl=@'@'(del). latin-type lang may need \s==\040
	@()
	--
	next keys change manpage setting
	@(pre)@
	'  title'   : manpage title. dfl=no_title
	'  section' : man section. dfl=1
	'  footer'  : dfl isnt set
	'  footer_l': dfl isnt set
	'  header'  : dfl isnt set
	@()
@_desc
	amn converts markup text to manpages. basic rule is close to html.
	@(pre)@
	  - tab, newline, emptylines are ignored
	  - spaces are merged to 1 char
	@()
	a typical example is the below:
	@(code)@
	---
	  title=hello section=1
	  header=GNU
	  @name hw
	  @_brief hello, world
	  @_syno hw [-h|-H] file ...
	  @options option list is --
	    @(list)
	    -h: escape quote, colon.. @'help@' @: etc
	    '-v': version
	    @() 
	  @_see ls(1), 'pwd(1)' '_puts(3)'
	---
	@()--
	
	amn accepts the following syntax:
	@(list)--
	'_key=str': from BOF to 1st @XXX is defination block. --
		- grep only XX=YY str. ignore others --
		- dont quote. mk=@'@@@' is bad. title=a\101c is valid. --
		- '_str' is sapareted with sp/tab. use \040 if needs space \s. --
		- '_str' is converted with printf('_str'). notice %% >> %. --
		- option -D'_key=str' overwrites defination block settings.	--
	'_@XXX': header, '@name' etc. make uppercase. must be BOL.
		XXX is converted with printf('XXX'). @conforming\040to etc.
	@_XXX: same as @XXX, but some words are reserved to alias/macros. --
		'  @_syno '@: @SYNOPSIS		--
		'  @_opt  '@: @OPTIONS		--
		'  @_desc '@: @DESCRIPTION	--
		'  @_eg   '@: @EXSAMPLE		--
		'  @_ver  '@: @VERSION		--
		'  @_see  '@: @SEE_ALSO		--
		'  @_brief'@: add description to @NAME	--
	'@(pre)...@()': <pre>..</pre>. highlighting, charesc, @@(raw) works
	'@(code)..@()': similar to @(pre) but any syntax/tag doesnt work

	'@(list)..@()': list. splits label and info with colon @'@:@'.
		if use colon char in infostr, use '@@:' . nl, --(\n) cant use in label. --
		''eg) it@@'s a 'la'@'_bel': m'sg' @@: --(\n)@(raw).RS@()  ..valid''	--

	'@(list_o)..@()': list for command options. highlight label automatically --
		''eg) -n, --num[=n]: set num >>>'' '-n', '--num'[='_n'] set num

	'@(raw)...@()': pass rawstr to groff. no needs to set \n at the block end. --
		''eg) abc@(raw).SH new_section@()123''

	'@()(\n)': works as block end if exists in the EOL. if block isnt open or
		not EOL, ignored/skipped. --
		''eg) abc@()123 >>> abc123, do nothing''

	@'str@'		: bold 'str'. keep inner sp/tabs. use '@@@', @@@@' to write '@', @@'
	@'_str@'	: underline '_str'. 1 char @'_@' works as bold
	@'@'str@'@'	: single quote x2, no highlighting. you dont need esc quote. --
		''eg) '@' 'abc' esc @@' @@@@ works too'@''' >>'' 'abc' esc ' @@ works too''
	'@@@''	: single quote. you can also use groff esc '@(raw) \(aa @()'
	'@@@@'	: atmark. you can also use groff '@(raw) @ @()'
	'@@:'	: colon. maybe uses only for @(list) or @(list_o). '@(raw) : @()'
	'--(\n)': 2-hyphen + nl. <br>. --(\s)(\n) doesnt work. 'groff_man' seems
		to merge blanklines at output, so you cant use multi-blankslines. --
	@()

	if @@(pre,code,list,list_o) end with @@(...)\n, deletes \n char. --
	if they end with @@(...)--\n, add a empty line before the block. --
	if @@(pre,code) block end with @@(...)@@\n, remove the leading tabs as
	shell heredoc '' '<<-' '' syntax. --
	if they end with @@(...)--@\n, add a empty lines and remove the leading tabs.	--
	if @@() end with @@()--\n or @@()--@@\n, add a empty line after block.	--
	if @@() end with @@()@@\n, work the same as @@()\n. (ignores end @@). --
	summary example is the below:

	@(code)--@
	aaa              aaa          |  aaa              aaa
	@(code)          \t   \s 000  |  @(code)@            000
	\t   \s 000  >>  \s \t   111  |          000  >>          111
	\s \t   111      zzz          |          111
	@()\n                         |  @()--            zzz
	zzz                           |  zzz
	- - - - - - - - - - - - - - - + - - - - - - - - - - - - - - -
	aaa              aaa          |  aaa              aaa
	@(code)--                     |  @(code)--@ 
	        000  >>          000  |          000  >>     000
	        111              111  |          111              111
	@()@             zzz          |  @()--@ 
	zzz                           |  zzz              zzz
	@()--@

	the @(list_o) label and @SYNOPSIS block are highlighted automatically.
	@@(list_o) label is assumed to be command options -a, --all[=str] etc. --
	@SYNOPSIS parser is changed by '-Dsection'='_num' setting
	@(list)
	section 1:	detect command format, "cmd [-a ag] file" etc. use --(\n)
		to split long command description@: --
		'    'eg) cmd [-a ag] --(\n)(\t) [-b] file
	section 2/3: detect C-func decreations "int myf(int num);" etc. use 
		simple (\n) to split long string. (allow --(\n) too)--
		this block works as @@(pre) block with C-func highlighting.
	@()--
	the parsers are heuristic but work for the most part.
	
@_eg
	@(code)--@
		--
		@name hw - hello, world
		@_desc disp --
		  'messages' ...
		
		--
		mk=#_@ brstr=???
		#_@name hw - hello, world
		#_@_desc disp ???
		  'messages' ...
	@()--@

@conforming_to	posix-sh, POSIX.1-2001+
@notes
	@(code)
if you needs to html converter, use mandoc.
~$ cat amn.1 | mandoc -Thtml -Ostyle=style.css > index.html
~$ cat amn.1 | mandoc -Tps > usage.pdf

groff-man has self html parser (man -H) but not so good 
~$ cat amn.1 | man -Hcat /dev/stdin >index.html
	@()
@copyright
	Copyright (C) 2021 Momi-g --
	License GPLv3+ <https://gnu.org/licenses/gpl.html>.

@_see
	'man-pages(7)', 'groff_man(7)', 'groff(7)', 'mandoc(1)'	--
	https://wiki.archlinux.org/title/Man_page (strongly recommend)	--
	--
	...you 'should' read man-pages(7)
EEE
exit 0
}

usage_F(){
cat << 'EEE'
title=AMN_DMY section=3
repnl=\040	//dfl is '', change nl to \s for latin-langages
@name amn_dmy - C function parser is testing...
@_syno
	#include "abc.h"
	int amn(int ac, char* av);

	int amn_dmy(const char* str);

	Feature Test Macro Requirements:
	// '_abc()': 20010101L <= _POSIX_C_SOURCE
@_desc
	dummy C function for test SYNOPSIS parser.--
	man sec 2,3 is used for C function and amn highlights 'SINO' block strings
	'#...' and decleation '_ident ...();' automatically.--
	@(list)
	'list test': 111
	'list check': 222
	@()
	code block...
	@(code)--@
		abc
		123
		xyz
	@()--@
	msg end
@notes -
@_see
'printf(3)', 'puts(3)'
EEE
exit 0
}

usage_1(){
cat << 'EEE'
./amn <<- E | man /dev/stdin 
@name myapp - amn     'ignores' '_blanks'/nl same as html
@synopsis mycomm [-a|-b] [-d word] words...
E

#...copy & run upper code
EEE
exit 0
}

usage_3(){
cat << 'EEE'
./amn <<- E | man /dev/stdin
title=hellword section=3
@name hw - use C-func parser to @synopsis if section is '_2' or '3'
@_syno int hw(int ac, char** av); //write '_anymsg'
E

#...copy & run upper code
EEE
exit 0
}

usage_7(){
cat << 'EEE'
title=へろー section=7
repnl=	//デフォルト ''を使用
@name amn - マルチバイトlangなメモ
@_desc
	amnは
	@(pre)--@
		- javadocコメントのような簡潔な記述を
		- latin系以外の文字でも記載できて
		- roffという標準的なシステムで処理して
		- プログラマのdoc作成の'_労力を最小限'に
	@()--
	することが目的です。そのためにamnは
	@(pre)--@
		- 改行の空白変換を無効orオプション扱い
		- man表示が大きく崩れないようにcharactor毎にzwspを挿入
		- bold, listなどの必要最小限のタグを導入
		- SYNOPSISの強調表示を自動化
	@()--
	の機能を担います。--
	--
	--以下、補足-- --
	manはバックエンドに(g)roffを使用する。roffはTeXと同じく書籍出版
	向けの組版プログラムのため ioがpsとかpdfとか出力機器に合わせて
	動作変更させたり ミリメートル単位で位置を決めたり？出来る高機能
	なappだが 1970年代に作られたため基本はlatin系が主対象。
	そのため改行が自動で空白に変換される。 --
	http://manpages.ubuntu.com/manpages/bionic/ja/man7/roff.7.html --
	--
	roff言語は非常に難解。\"がコメントで\(rsがエスケープなど。
	扱うにはDTPオペレータ並の技量が必要で、古いため資料も限られる。
	manはマクロ事前定義によりある程度簡単に扱えるが、それでも太字指定など
	面倒な記述が多い。--
	amnは内部パーサで--
	'	' plain text >> amn内部パーサ >> manマクロ >> groff言語 --
	と変換して冗長な記述を不要にしている。既存のapp不採用の理由は
	@(list)--
	- html: 不要タグが多すぎ、記述が冗長。外部htmlパーサが必要
	- md: 暗黙、不可視なルールが多すぎ。\s\s\nで<br>など。---前後で改行が必要
		などの行数が増えるシンタックスが多い。また外部md/htmlパーサが必要
	- tex: 外部パーサが必要。デカい重いオーバースペック。よく知らない。
	@()
	いずれも外部系は html/tex >> roff の非標準な外部パーサが必須であり、
	またSYNOPSISの自動ハイライト機能が見当たらなかったので諦めるしか
	なかったんです。--
	自動強調は非常に重要な機能です。doc書きは気力と時間を吸い取るので
	細かい指定が必要となると、もう書くのやーめた。となります。 --
	docは限界を越えて短く、分かりやすく、コンセプトを明解に伝えることに
	コストをかけるべきで、それを邪魔するものは全て敵と考えています。 --
	htmlやinfoなどの文書ツールよりも、ポータブルで軽くて最もよく使う
	manが信頼できるTLDRマニュアルだと思います。おしまい。
@notes -
@_see -
EEE
exit 0
}

func_rlp() {
# GPL_3+ license
# '(' ... for local scope
# func_rlp "$@"	
(
# normalize locale
export LC_ALL=C
export LANG=C

rlp_input='cat -'	
if [ "$#" != '0' ] ; then
	rlp_input='for ii
do
	printf "%s\000" "$ii"
done'
fi

# $0 is always holds absolute dirpath (posix reccomended)
# 2.5.2 Special Parameters >> $0

# ...awk for detect input err.
eval "$rlp_input" | od -An -to1 -w16 -v | awk -v bf="$0" '
BEGIN{err=1} 
$0 ~ /000/ {err=0}
{print $0}
END{
	if(NR > 0 && err == 1 ) {
		printf("%s: link search err. \134000 not found. sleep.\n", bf) > "/dev/stderr"
		for(;;){
			system("sleep 1000")
		}
	}
}' | sed -e 's/ 000/@/g' | tr -d '\n' | 
	tr ' ' '\134' | tr '@' '\n' | while read -r rlp_A
do
	# fname ... dir
	rlp_fin=`printf "$rlp_A"'@'`
	rlp_fin="${rlp_fin%?}"

	#	normalize name to have dir data	(aaa.txt -> ./aaa.txt etc)
	rlp_fin="${rlp_fin%/}"
	if [ "${rlp_fin#*/}" = "$rlp_fin" ] ; then
		rlp_fin="./$rlp_fin"
	fi
	
	rlp_ftail=''	#file name only
	# kick err files
	if ! [ -e "$rlp_fin" ] ; then
#		echo "$0: link search err. file not found. '$rlp_fname'" > /dev/stderr
		printf '//%s\000' "$rlp_fin"
		continue
	fi
	
	# split dir + name. -f ... cant get ln, pipe etc.
	if ! [ -d "$rlp_fin" ] ; then		# -d ! not dir == files
	#	split dir + filename. and resolve soft link
	# ls --show-control-chars
	#	表示不可能な文字をそのまま表示 (プログラムが  'ls'  で  なかった
	#	り、出力が端末以外の場合は、これがデフォルト動作になる)
	#	...つまり、端末に表示せず変数等に代入する時は正確なファイル名が取得できるはず。
	#	-Lオプションはサイズや日付データのみでファイル名は対象外

		rlp_fname="$rlp_fin"
		while :		# recheck for multiple link (a -> b -> c etc)
		do
		if ! [ -h "$rlp_fname" ] ; then		# -h ... exist & link
			break
		fi

# 2-clause BSD license
# https://sites.google.com/site/jdisnard/realpath
# use 'ls -l' to get link-dst infomation.
# '->' use as string spliter	... http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html
# need LANG=c ? safety?
#	rlp_LANGbk="$LANG"
#	LANG="c"
		rlp_base=`/bin/ls -l "$rlp_fname" ; printf @`	# $() removes end '\n' (posix)
		rlp_base="${rlp_base%??}"	# aaa\n@ -> aaa	... ls add \n (like echo)
		rlp_count=`printf '%s\n' "$rlp_fname" | tr -c '>-' ' ' |
			sed -e 's/->/@/g' | tr -d -c '@' | wc -c`	# check '->' string(filename, username etc)
		rlp_count=$((rlp_count+1))
		
		for ii in `seq 1 $rlp_count `	# ls -h... exist -> 
		do
			rlp_base="${rlp_base#*->}"
		done
		
# debug... ls -al
# /dev/stdin -> /proc/self/fd/0
# /proc/self/fd/0 -> pipe:[3082488]		<<< not file. inode system. needs kick
		test -e '/'"${rlp_base#*/}" || break	
		rlp_fname='/'"${rlp_base#*/}"	# remove head ' '	ls disp filename (linkfile)

		done	#while end
		
		# if files, rlp_ftail != '', 
		rlp_ftail="${rlp_fname##*/}"	# filename only
		rlp_fdir="${rlp_fname%/*}"	# dirname only
	else
		# fin is dir
		rlp_fdir="$rlp_fin"
	fi
	
	# normalized. check path reallink
	# pwd -P: get full realpath. posix. (2001-?)
	# echo @ ... command substitution deletes lineend '\n, \n\n ...'.
	# http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_03
	# pwd permission... dir exec may make some problem. run at subshell.
	
	(
	for ii in skip		# jump emulate
	do
		cd "$rlp_fdir"
		if [ "$?" = "1" ] ; then
			echo "$0: link search err. dir access failed. ($rlp_fdir)" > /dev/stderr
			printf '//%s\000' "$rlp_fdir"
			break
		fi		
		
		rlp_fpath=`pwd -P; printf '@'`
		if [ "$rlp_fpath" = '@' ] && [ "$err" != "" ] ; then
			echo "$0: link search err. pwd -P failed. ($rlp_fdir)" > /dev/stderr
			printf '//%s\000' "$rlp_fdir"
			break
		fi
	
		rlp_fpath="${rlp_fpath%??}"	# aaa\n@ -> aaa	... pwd add \n (like echo)
		rlp_fpath="${rlp_fpath%/}"	# if aaa/ -> aaa etc
		rlp_fname="$rlp_fpath"'/'"$rlp_ftail"	# dir has end '/' ... 'aaa/' etc
		printf '%s\000' "$rlp_fname"
	done
	)
done | od -An -to1 -w16 -v | tr -d '\n' |
sed -e 's# 000#@#g' | tr ' ' '\134' | tr '@' '\n' | awk -v name="$0" '
	$0 ~ /^.057.057/ {
		gsub(/^.057.057/, "", $0)
		cmd="printf \047" $0 "\012\047 >/dev/stderr"
		printf "%s: link check err. file not found: ", name > "/dev/stderr"
		system(cmd)
		printf "//"
		}
	{print $0}'
)
}

exdir=`func_rlp "$0"`
exdir=$(printf "$exdir"@)
exdir=$(dirname "$exdir")
main "$@"

# ./amn -H|./amn| mandoc -Tps > amn_1.pdf

cat<<'EEE'>/dev/null
 change log
 --
2021-08-15	Momi-g	<dmy@dmy.dmy>

	* amn(XXX.ped) : update ped pkg. fix ped rule. v1.0.2
	
	* amn(cmn.ped) : add @(code,pre) in @(list) infomsg.

2021-08-10	Momi-g	<dmy@dmy.dmy>

	* amn(END()) : fix title output >> toupper(title)

2021-08-08	Momi-g	<dmy@dmy.dmy>

	* amn(typo) : fix typo _breaf >> _brief
	
	* amn_cfunc.ped : fix sec 3 SYNOPSIS \s, \t ignore >> left

	* amn_cfunc.cmn(cmn_blk_h): exclude @(raw) from block header group
	
2021-08-07	Momi-g	<dmy@dmy.dmy>

	* amn(all) release v1.0.0

EEE
