#include <emsg: see ... '~$ sh aaa.sh.c -h'   (other opt:no/-m/-w/)>	/*
C='^[/][/*]SH_'     ;O=${0##*[/]};R=`dirname $0`;R=${R%/}/;R0=$R$O;R=$R${O%%.*}
O=${0##*.};Rs=$R.$O;Rm=$R.tmp.$O;Rh=$R.h;R=$Rs$Rh$Rm;Rp='printf %s\n ';Rc=:;O="
";[ "${R##*$R0*}" = '' ]&&$Rp"$0:NGsuffix"&&exit 1;R='sed -ne ';Cm=$R'"/[E]ND/!d
:l;n;p;bl"<$R0>$Rm;$Rp"$Rm"';RB=$($R"s/${C}OP//p"<$R0|(F=mw;while read -r a b;do
B=${a%:};F=`$Rp"$F"|$R"s#$B:*##1;p"`${a%_};$Rp"C$B=\$(cat<<'E'$O$b${O}E$O)";done
$Rp"R1=$F"));Rw=$R'"/$C$R/!d;:l;n;/${C}ED/q;p;bl"<$R0';Cw="(R=LS;$Rw;$Rw>&3;R=HD
$Rw;R=SC;$Rw>&3)"'>$Rh 3>$Rs;$Rp"$Rh $Rs"';Re=eval\ ;$Re"$RB";while getopts $R1\
 R;do case $R in \?)exit 1;;*)$Re"O$R=\$OPTARG";Rc=$Rc$O`$Re'$Rp"$C'$R\"`;;esac
done;[ "$Rc" = : ]&&Rc=$Cm;shift $((OPTIND-1));$Re"$C_$O$Rc";exit  #END GPLv3+*/

//SH_LS
/* Copyright (C) 2019 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/>.
 */
//SH_ED

//SH_HD		-----
#define foo 123
int brp_hw();
//SH_ED

/*SH_SC		-----*/
#include "brp.h"
#include <stdio.h>
int brp_hw(){
	printf("brp samplecode, %d\n", foo);
	return 0;
}
int main(int argc, char** argv){
	brp_hw();
	return 0;
}
//SH_ED

//---- usage block
//SH_OP d cat "$R0" | sed -e "/#END/q"
/*SH_OP h cat "$R0" | sed -ne "/${C}OP h/!d;:l;n;/${C}ED/q;p;bl"  #q...quit*/
/* brp - line oriented universal preprocessor using posix-sh
---basic usage
 this script works by just copying and pasting into your file top.
	~$ sh brp.sh.c	-d	#>> drop sh script
 all the codes are written at the top of this file.
 
 ~$ sh brp.sh.c	-m	#>> output tMp file (brp.tmp.c) and disp "brp.tmp.c"
 ~$ sh brp.sh.c	#>> same as above. noopt is statically fixed to -m.
	...-m opt (or noopt) works as
	1. delete the header script.
	2. write it to a tmpfile. (aaa.tmp.c etc)
	3. disp filename to stdout.

 ~$ sh brp.sh.c -w  #>> make brp.h + brp.c. if brp.sh.java, brp.h + brp.java
	... -w(output double file) opt  works as
	1. write SH_LS - SH_ED(LS_block) to both brp.h/brp.c
	2. HD_block -> add to brp.h,	SC_block -> add to brp.c
	3. disp filename to stdout.  (brp.h brp.c)

 your extension: add '//SH_OP z echo "12345"' to this file end and run.
	~$ sh brp.sh.c -z -w -z	#>> 12345 x2	...see also -H (7-8 pages).
//SH_ED

/*SH_OP H cat "$R0" | sed -ne "/${C}OP H/!d;:l;p;n;/${C}ED/q;bl"
---extended usage
 make code as follows

	#inc ... #END	(header script end)
 	//SH_OP a echo "hello"
 	//SH_OP b: z=100;echo "good-bye $2 $Ob $1 $z"   #Ob ...optarg of -b
 	//SH_OP x date
 	//SH_OP y echo "he said, "; eval "$Ca"		#Ca ... Command -a...

 and execute.
	~$ sh brp.sh.c -a		#>> hello
	~$ sh brp.sh.c -a -x -a		#>> hello y1999.m1.d31 hello
	~$ sh brp.sh.c -y		#>> he said, hello
	~$ sh brp.sh.c -b 123 a_1st a_2nd		#>> good-bye a_2nd 123 a_1st 100

---opt extend rule
	//SH_OP b: z=100;echo "good-bye $2 $Ob $1 $z $R0"
	   1  2 3                 4 
 
	1- dfl opthead is "//SH_OP" or "/*SH_OP". see below '$C'. 
	2- separate with blank char(spaces or tabs)
	3- optchar is [a-zA-Z0-9] + '_'(see below). add ':' if use optarg.
	4- write raw sh-script with ONE LINE.
	  1-2char var names R?, C?, O? are reserved.(R,C,O,Ra,R7,Cg,O5 ...)
	  optarg is set to $O? ( a: >> $Oa ,  v: >> $Ov etc)
	- description of reserved vars. 
	  $R0,Rm,Rs,Rh ... orig/tMp/src/header fname. ($Rm -> ./aaa.tmp.c etc)
		fname uses topname + last suffix. brp.xx.yy.py3 -> ./brp.py3
		original fname should avoid tmp/src/header fname.
		(sh sh_aaa.c -w >> sh_aaa.h / sh_aaa.c ...orig destroyed)  

	  $C? ... $Cm/$Cw etc. code buffer. (Ca='echo "foobar"')
	    //SH_OP a echo "hw";echo "$Rm"  ...sh brp.sh.c -a ...hw aaa.tmp.c
	    //SH_OP b printf "$Ca" ... sh brp.sh.c -b ... echo "hw";echo "$Rm"
	    //SH_OP c eval "$Ca"	... -c works as equals to -a
	  $C  ... comment sed-regex. dfl C='^[/][/*]SH_' ...//SH_xx or /*SH_yy
	     brp uses linecmt as directive. if you want to use other
	     pg-lang(python etc), edit srctop 'C=...' directly. use BRE-reg.
	      shell : C='^#ANYSTR_';	>>  #ANYSTR_LS, #ANYSTR_ED etc
	      python: C='^["]["]["]MARKER_'; >> """MARKER_OP   etc
	      basic : C="^[']SH_";
	     ...$C is used as follows. escape slash '/' plz. 
	     sed -e "/${C}ED/"  ...  bad:C='^/[/*]SH_'  good:C='^\/[/*]SH_'

 	  $O? ... optargs. //SH_OP a: echo "$Oa"  .. sh brp.sh.c -a 11 ..11
	  $O  ... newline(\n).	...eg) //SH_OP a echo "a${O}b" >> disp a(\n)b
	  $0,1,2 ..normal args. this pg uses getopts. checked opts are removed.

	- adopt new one if option setting is duplicate.
	    //SH_OP a echo "hw"	>> ignored. sh brp.sh.c -a  -> disp "gw"
	    //SH_OP a echo "gw"
	    //SH_OP w echo "123" >> overwrite dflopt. you cant remap old one.
	- if special optchar '_' is set, it works only once at the script
	  beginning. works as preprocesser.
	    //SH_OP _ echo "preset AA";AA=1;eval "$Ch"
	    //SH_OP a echo "$AA"	#>>~$ brp.sh.c -a ... disp "1" + help.
	- suffixes(LS,HD,SC,OP,ED) are fixed. 
	- linetop '#include...' is assert() for c/cpp. (run  ~$ gcc brp.sh.c)
	  you can delete if you want.



---appendix
	--- copy & paste top script ---
	#include <iostream>
	int main(void){
		std::cout << "hw" << std::endl;
	}

	//SH_OP b eval "$Cm";g++ "$Rm"; ./a.out
	
	...save as 'aaa.brp.cpp' and run 'sh aaa.brp.c -b'	>>> hw.
 
 --
	//COPT -L./ -lm -DTEST -O2 -Wall
	//SH_OP t buf=`sed -ne s#^//COPT##p`;eval "$Cm"|tr '\n' ' ';echo "$buf"
		>> gcc `sh aaa.sh.c -t`  -> gcc aaa.tmp.c -L./ -lm -DTEST ... 
 --
	//I_OPT -I./ -I./include
	//L_OPT -L./ -L./lib -lpthread -lm
	//SH_OP i cat "$R0" | sed -ne 's@^//I_OPT@@p' | tr '\n' ' '
	//SH_OP l cat "$R0" | sed -ne 's@^//L_OPT@@p' | tr '\n' ' '
	//SH_OP o eval "$Ci"; eval "$Cl"
		... sh aaa.sh.c -o >> show -I./include -L./lib -lpthread -lm

 --
	- one liner sample 
	  Cm='sed -ne "/[E]ND/{n;bl};d;:l;p;n;bl"<"$R0">"$Rm";echo "$Rm"'
	  >>
	  sed -ne '*see below*' < "$R0" > "$Rm"
	  echo "$Rm"
	  >>
	  cat 'foo.sh.c' | sed -ne '*see below*' > foo.tmp.c
	  echo "foo.tmp.c"
		
	- explain sed cmd
	  sed -ne '/[E]ND/{n;bl};d;:l;p;n;bl'
	  >>
	  sed -n(o print. print only when requested) -e(xpression as script)
	    'if (line==/END/){  .../[E]ND/
	  	  n(ext read) ...n (if not -n opt, print nowline & readnext)
	  	  goto label l ...b l (b=jump/goto. babc -> b abc -> goto abc)
	    }
	    del line (& read nextline & *goto top*) ...d (d cmd is hard worker)
	    label l:		... :l (label. ':' + 'lbl name') 
	    p(rint line)		... p
	    n(extline read)		... n
	    goto label l		... b l
	    '
	  >> del lines until fst hit 'END'. print all lines until EOF.
	  ...sed cmd is difficult but very powerful.Most requests can be solved 
	  by referring to the above.
	  
	- explain sed + sh
	  sed cant use shortest match, but shell is possible(shotest+longest).
	    str="aa_bb_cc"
	    echo "${str#*_}" 	#>> bb_cc (match aa_ and del)
	    echo "${str##*_}" 	#>> cc (longet)
	    echo "${str%_*}" 	#>> aa_bb (from tail)
	    echo "${str%%_*}" 	#>> aa
 	  The way to remember is '# is to the left of % at keyboard' or
 	  '# is often used at the beginning of comments'.
 		
 	  shell pattern(glob pattern) is very similar to sed-regex.
	    aa_bb_cc -> a_bb_cc
	    reg: s/^.//g  sh: ${str#?}	... any one char. reg:'.'    sh:'?'
	    
	    aa_bb_cc -> (del)
	    reg: ^[.]*  sh: ${str#*}	... all. sh can uses wild card.
	    
	    aa_bb_cc -> aa_
	    reg: [^a_]*  sh: ${str%%[!a_]*}	... not.  reg:'^'    sh:'!'
	    	...[], bracket works as same, 'one char'
	    
	    escape
	    sh: ${str%123"*"*}  ... "*" uses as literal. 0123*567 -> 0
	    
	  https://en.wikipedia.org/wiki/Glob_%28programming%29  ..or
	  see 'man sh' + input '/' + input 'pattern' + enter + 'n' + shift 'n'

 concept
	I wondered why to write dependencies or compile options to makefiles.
	The source code should contain all the necessary information.
	Because the programmer's will is written. I didn't like writing in
	separate files and increasing the workflow.
	
	- avoid info fragmentation (script/src/header/gcc opt/ini/config etc)
	- small. avoid disturbing the main code.
	- (consider readability)
	- portable. avoid vender lockin, bashism etc.
	- low learning cost. good usage help, dont need installation etc (todo)
	- others ... see unix philosophy.
 
 change log
 --
2021-05-11  Momi-g	<dmy@dmy.dmy>

	* brp.sh.c : v1.0.1 add mandoc, improve brp script 

2020-01-04  Momi-g	<dmy@dmy.dmy>

	* brp.sh.c : v1.0.0 releases. 

//SH_ED*/

//----the below is out of HELP. mainly uses for C src-----

/*SH_doc*

[back][1]

#h NAME#	brp - line oriented universal preprocesser using posix-sh
#h SYNOPSIS#	**sh** *./yourcode* [-**mw**]
#h EXAMPLE
this script works by just copying a sh-script to your code head.
all the codes are written at the 10-lines. -[**mw**] is defined in it too.

- eg1 (src.abc.xyz)

```
#include <emsg: see ... '~$ sh aaa.sh.c -h'   (other opt:no/-m/-w/)>	/*
C='^[/][/*]SH_'     ;O=${0##*[/]};R=`dirname $0`;R=${R%/}/;R0=$R$O;R=$R${O%%.*}
O=${0##*.};Rs=$R.$O;Rm=$R.tmp.$O;Rh=$R.h;R=$Rs$Rh$Rm;Rp='printf %s\n ';Rc=:;O="
";[ "${R##*$R0*}" = '' ]&&$Rp"$0:NGsuffix"&&exit 1;R='sed -ne ';Cm=$R'"/[E]ND/!d
:l;n;p;bl"<$R0>$Rm;$Rp"$Rm"';RB=$($R"s/${C}OP//p"<$R0|(F=mw;while read -r a b;do
B=${a%:};F=`$Rp"$F"|$R"s#$B:*##1;p"`${a%_};$Rp"C$B=\$(cat<<'E'$O$b${O}E$O)";done
$Rp"R1=$F"));Rw=$R'"/$C$R/!d;:l;n;/${C}ED/q;p;bl"<$R0';Cw="(R=LS;$Rw;$Rw>&3;R=HD
$Rw;R=SC;$Rw>&3)"'>$Rh 3>$Rs;$Rp"$Rh $Rs"';Re=eval\ ;$Re"$RB";while getopts $R1\
 R;do case $R in \?)exit 1;;*)$Re"O$R=\$OPTARG";Rc=$Rc$O`$Re'$Rp"$C'$R\"`;;esac
done;[ "$Rc" = : ]&&Rc=$Cm;shift $((OPTIND-1));$Re"$C_$O$Rc";exit  #END GPLv3+*/
//SH_OP a echo "hw"
//SH_OP z pwd; ls -al
```
(run)~$ sh src.abc.xyz -a\	\	#>> hw##
(run)~$ sh src.abc.xyz -z\	\	#>> disp info

- eg2 (src.sh.c)

```
#inc...
	...#END
//SH_LS
//this code license is XXX...
//SH_ED

//SH_HD
int myf(void);
//SH_ED

/*SH_SC*/
int myf(void){puts("hw");return 0;}
int main(int argc, char** argv){return myf();}
//SH_ED
```
(run)
#s ~$ sh src.sh.c -m\	\	#>> output tMpfile (brp.tmp.c) and disp "brp.tmp.c"##
#s ~$ sh src.sh.c\	\	#>> same as the above. noopt is statically fixed to -m##
#s ... -m opt (or noopt) works as

1. delete the header script.
2. write it to a tmpfile. (aaa.tmp.c etc)
3. disp filename to stdout.

#s ~$ sh brp.sh.c -w\	\	#>> make brp.h + brp.c. if brp.sh.java, brp.h + brp.java
#s ... -w(output double file) opt works as

1. write SH_LS - SH_ED(LS_block) to both brp.h/brp.c
2. add HD_block to brp.h and add SC_block to brp.c
3. disp filename to stdout. (brp.h, brp.c)

- eg3 (src.sh.c)

```
#inc..(header script)..#END
//SH_OP a echo "hello"
//SH_OP b: z=100;echo "good-bye $2 $Ob $1 $z"   #Ob ...optarg of -b

..(license block)..

//SH_OP x date
//SH_OP y echo "he said, "; eval "$Ca"		#Ca ... Command -a...
```
(run)
#s ~$ sh brp.sh.c -a\	\	#>> hello
#s ~$ sh brp.sh.c -a -x -a\	\	#>> hello y1999.m1.d31 hello
#s ~$ sh brp.sh.c -y\	\	#>> he said, hello
#s ~$ sh brp.sh.c -b 123 ag1 ag2\	\	#>> good-bye ag2 123 ag1 100

#h option setting format
```
	//SH_OP b: z=100;echo "good-bye $2 $Ob $1 $z $R0"
	    1  2 3                 4 

1- dfl opthead is "//SH_OP" or "/*SH_OP". see below '$C'. 
2- separate with blank char(spaces or tabs)
3- optchar allows only [a-zA-Z0-9] + '_'(see below). add ':' if you use optarg.
4- write raw sh-script with ONE LINE.
  1-2char var names R?, C?, O? are reserved.(R,C,O,Ra,R7,Cg,O5 ...)
  optarg is set to $O? ( a: >> $Oa ,  v: >> $Ov etc)

- reserved words
  $R0,Rm,Rs,Rh ... orig/tMp/src/header filename. ($Rm == ./aaa.tmp.c etc)
	filename uses topname+last suffix.	eg) $R0: ./brp.xx.yy.py3,	$Rm: ./brp.py3
	original filename should avoid tmp/src/header name.
	(sh sh_aaa.c -w >>> sh_aaa.h / **sh_aaa.c** ...orig destroyed)  

  $C? ... $Cm/$Cw etc. used for opt command buffer
    //SH_OP a echo "hw";echo "$Rm"		#>>sh brp.sh.c -a ...hw aaa.tmp.c
    //SH_OP b printf "$Ca"		#>> sh brp.sh.c -b ... echo "hw";echo "$Rm"
    //SH_OP c eval "$Ca"		#>> sh brp.sh.c -c ... works as equals to -a

  $C ... comment sed-regex. default is C='^[/][/*]SH_' ...//SH_xx or /*SH_yy
     brp uses linecmt as directive. if you want to use other
     pg-lang(python etc), edit srctop 'C=...' directly with BRE-regex.

      shell : C='^#ANYSTR_';	>>  #ANYSTR_LS, #ANYSTR_ED etc
      python: C='^["]["]["]MARKER_'; >> """MARKER_OP   etc
      BASIC : C="^[']SH_";		>>'SH_OP etc

     $C is used as below. escape slash '/' plz. 
      sed -e "/${C}ED/"  ...  bad:C='^/[/*]SH_'  good:C='^\/[/*]SH_'

  $O? ... optargs.		eg) //SH_OP a: echo "$Oa"  .. sh brp.sh.c -a 11 ..11
  $O  ... newline(\n).	eg) //SH_OP a echo "a${O}b" >> disp a(\n)b
  $0,1,2 ..normal args. this pg uses getopts. checked opts are removed.
	eg) //SH_OP a echo "$1"		#>> ~$ sh foo.sh.c -a -- hw		>> hw

- dupulicated defination
  adopt new one if option setting is duplicate.
    //SH_OP a echo "hw"	>> ignored. sh brp.sh.c -a  -> disp "gw"
    //SH_OP a echo "gw"
    //SH_OP w echo "123" >> overwrite dflopt. you cant remap old one

- preceding command
  if you set optchar '_'(0x5F underscore), it will run at first automatically.
  this optchar works as preprocesser.
  (set)
    //SH_OP _ echo "preset AA";AA=1
    /*SH_OP a echo "$AA"	#*/
    //SH_OP 1 echo "hw"
  (exec)
    ~$ brp.sh.c -a		#>> disp "preset AA", "1"
    ~$ brp.sh.c -a		#>> disp "preset AA", "hw"
    ~$ brp.sh.c 		#>> disp "preset AA" and drop brp.c/brp.h

- opt 'm/w' is defined at the header script and uses SH_xx (LS,HD,SC,ED)
- SH_xx (OP,LS,HD,SC,ED) suffixes are fixed
- linetop '#include...' is assert() for c/cpp. (run ~$ gcc brp.sh.c)
  you can delete if you want.
```
#h appendix
```
--- src.cpp
	#inc...(script)...#END
	
	#include <iostream>
	int main(void){ std::cout << "hw" << std::endl;}
	//SH_OP b eval "$Cm";g++ "$Rm"; ./a.out

(run)~$ sh aaa.brp.c -b	#>> hw
---

---src.c
	#inc...(script)...#END
	
	#include <stdio.h>
	int main(void){ puts("hw");}
	//add -L./ -lm -DTEST -O2 -Wall

	//SH_OP o buf=`sed -ne 's@^//add@@p'<$R0`
	//SH_OP b eval "$Co"; eval "$Cm"; gcc $Rm $buf

(run)~$ sh -x src.sh.c -b		#>> gcc src.tmp.c -L./ -lm -DTEST -O2 -Wall
---

-one liner sample 
  Cm='sed -ne "/[E]ND/{n;bl};d;:l;p;n;bl"<"$R0">"$Rm";echo "$Rm"'
  >>
  sed -ne '...' < "$R0" > "$Rm"
  echo "$Rm"
  >>
  cat 'foo.sh.c' | sed -ne '..see below..' > foo.tmp.c
  echo "foo.tmp.c"
	
-sed command
  sed -ne '/[E]ND/{n;bl};d;:l;p;n;bl'

  -n: no print. print only when requested
  -e: expression of sed-script

  >>(explain sed command with pseudo code)
  if (line==/END/){  .../[E]ND/
    n(ext read) ...n (if not -n opt, print nowline & readnext)
    goto label l ...b l (b=jump/goto. babc -> b abc -> goto abc)
  }
  del line ...d (del line & read nextline & *goto top*. d cmd is hard worker)
  label l:		... :l (label. ':' + 'label name') 
  p(rint line)		... p
  n(extline read)	... n
  goto label l		... b l
  
  ...sed cmd is difficult but very powerful. add option '--posix' to avoid
  bashism if you use gnused.  eg) ~$ sed --posix -e '/hello/p'
    https://www.gnu.org/software/sed/manual/sed.html (verbose but bashism)
    https://pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html
    ~$ man sed

-edit string with shell
  posix-sed cant use shortest match, but shell is possible(shotest+longest).
    str="aa_bb_cc"
    echo "${str#*_}" 	#>> bb_cc (match aa_ and del)
    echo "${str##*_}" 	#>> cc (longet)
    echo "${str%_*}" 	#>> aa_bb (from tail)
    echo "${str%%_*}" 	#>> aa

  The way to remember is '# is to the left of % at keyboard' or
  '# is often used at the beginning of comments'.
	
  shell pattern(glob pattern) is very similar to regex.
    aa_bb_cc -> a_bb_cc
    reg: s/^.//g  sh: ${str#?}	... any one char. reg:'.'    sh:'?'
    
    aa_bb_cc -> (del)
    reg: ^[.]*  sh: ${str#*}	... all. sh can uses wild card.
    
    aa_bb_cc -> aa_
    reg: [^a_]*  sh: ${str%%[!a_]*}	... not.  reg:'^'    sh:'!'
    	...[], bracket works as same, 'one char'
    
    escape
    sh: ${str%123"*"*}  ... "*" uses as literal. 0123*567 -> 0
  
  - see also
  https://en.wikipedia.org/wiki/Glob_%28programming%29
  ~$ man sh		#and input '/pattern' + enter + 'n' + shift 'n'
```
[back][1]

[1]: https://osdn.net/projects/brp/
/*SH_docE*/

/*SH_OP _ set -e;a=`sed -ne "/${C}DF/!d;:l;n;/${C}DE/q;p;bl"<$R0`;eval "$a"	#*/
//*SH_OP h $p"-tsbS:test/eg/.o/.so -LMP:mem,prof@a.out -f:funcs -o:normalout	GPLv3+"	 #*/
/*SH_OP	f sed -ne "/${C}DF/q;/;/d;/^[a-z].*)/p"<$R0 #*/
/*SH_OP t $e"$CW";ftt "$@";$p'cc -g -pg $tf $Rs `fOI $tf` `fg $tf` `fL`'|fv	#*/
/*SH_OP s $e"$CB";fgr0 "${C}SMP" "${C}SMPE"<$Rs|fbn>eg.c;$p'cc eg.c `fg eg.c`'|fv #*/

/*SH_OP L $p"valgrind --leak-check=full ./a.out 2>&1|sed -e '/SUMMA/!d;n;n;n;n'"|fv #*/
/*SH_OP M $p"fM ./a.out"|fv	 #*/
/*SH_OP P $p'valgrind --tool=callgrind --callgrind-out-file=log.out ./a.out;kcachegrind log.out'|fv	 #*/

/*SH_OP b $e"$CW";$p'cc -c $Rs -O2 -Wall -g `fg $Rs` `fI $Rs`'|fv;$p"$bn.o"	#*/
/*SH_OP B $e"$Cb";$p"ar -r lib$bn.a $bn.o `fO $Rs`"|fv;$p"lib$bn.a"	#*/
/*SH_OP A $e"$CB";$p'fA lib$bn.a `fg $Rh $Rs|fu|grep '[.]a$'|fU`'|fv;$p"lib$bn.a" #*/
/*SH_OP S $e"$Cb";$p"cc -shared -fPIC -o lib$bn.so $bn.o `foi $Rs` `fg $Rs`"|fv;$p"lib$bn.so" #*/
/*SH_OP W $e"$Cm$O$Cw">/dev/null;$i0;$i1;$p"$Rs $Rh $tf"	#*/
/*SH_OP o $p'sed -e "/#END/q"<$R0>$bn.h;fmd $R0'|fv		#*/

/*SH_DF

#-- noob
fmd()(
fgr0 "${C}doc" "${C}docE"<$1>$Rm
cat $Rm|sed -e '
s/^\(#*\)#h[ \t]*\([^#]*\)#*[ \t]*\(.*\)$/\n\n\1# \2\n\n\3/1
s/^#b[ \t]*\([^#]*\)#*[ \t]*\(.*\)$/\n\n\1\n\n\2/1
s/\([^#\\]\)##$/\1  /1' | sed -e 'N;s/\(\n#s[ \t]*\)/  \n/1;P;D'>$bn.md
rm $Rm
fhtml $bn.md $bn
echo "index.html" >/dev/stderr
)

fhtml(){ md2h $bn.md $bn; }


fman()(
pandoc -h>/dev/null 2>&1 || exit 0
# --from license: cc-by-sa 4.0 (code is changed from the orig)
# --https://gpanders.com/blog/write-your-own-man-pages/ (auth:Gregory Anders)
cat $bn.md|pandoc -s -f markdown -t man -M title="$bn" \
-M section="$2" -M date=`date '+%Y-%m-%d'` > $bn.$2
# --end license:	cc-by-sa 4.0
)

#-- vars
bn=`basename ${Rs%.*}`; tf=${Rs%/*}/${bn}.ts.${Rs##*.}; e="eval "; p="$Rp"
#-- mod
fv()(while read -r a;do $e"cat<<E$O# $a${O}E"|sed -e 's@-L.*-L[^ ]*@-L(omit)@g'>/dev/stderr;$e"$a";done)

fbn()(sed -e "s@\*${C##*]}bn\*@$bn@g"|frf)
fsn()(tr -s ' \t' '\n')
fsl()(tr -s '\n' ' ')
fu()(fsn|sort -u)
fU()(fu|fsl;$p)

fgr()(sed -e "/$1/!d;:l;/$2/{p;d};n;bl")	#切出
fgr0()(sed -ne "/$1/!d;:l;n;/$2/d;p;bl")	#抜き切出
fgR()(sed -ne "/$1/bl;p;d;:l;n;/$2/d;bl")	#切すて
fg()(sed -ne "s/.*\*${C##*]}co\*\([^*]*\).*$/\1/p" "$@"|fsn|awk '!a[$0]{a[$0]=1;print}'|fsl)

# fO src.o from inc"src.abc" etc. kick self
fO()(set -- `fdp "$@"|awk '$0~/[.](h|hpp)$/{print}'|sed -e 's/[.][^.]*$/.o/'|fU`
	buf="";for i;do test -f $i&&buf="$buf $i";done;$p"$buf"
)
fI()(fdp "$@"|sed -e 's/[^/]*$//g'|fu|sed -e '/./s/^/ -I/g'|fU)
fL()(find -L `dirname $R0` -type d|sed -e 's/^/-L/g'|fU)

# inc""系.h,hpp,oをパス付きで羅列 OIはfdpが重複するので高速化でまとめる
fOI()(
set -- `fdp "$@"`
s="-I./ "`$p"$@"|sed -e 's/[^/]*$//g'|fu|sed -e 's/^/ -I/g'|fU`
set -- `$p"$@"|awk '$0~/[.](h|hpp)$/{print}'|sed -e 's/[.][^.]*$/.o/'|fU`
buf="";for i;do test -f $i&&buf="$buf $i";done;
$p"$buf $s"
)

# 依存inc""を再帰的に取得./以下全て self系はkick
fdp()( l="$*"; paths="$@"; all=""; used=""
 while :;do
	all=`$p$all $paths|fU`	#差分を追加 repの始末 差分たちからaaa.hを取得 partial path
	buf=`(cat $paths|sed -ne 's@^[ \t]*#inc[^"]*.\([a-zA-Z0-9._]*\)".*@\1@p')|sort -u`
	ch=`$p$used $buf|tr -s ' ' '\n'|sort|uniq -u`	#使用済は外す
	used="$used $ch"	#リスト更新
	paths=`fsvy $ch|sort -u`	#ls検索 name系のみのはず
	buf=`$p"$all" "$paths"|fU`	#増えたらloop
	[ ${#all} = ${#buf} ]&&break
 done
# initを除く
 set -- $all
 for i;do a=${i##*[/]}; a=${a%%.*};[ "${l##*$a*}" = "$l" ]&&set -- "$@" $i;shift;done
 $p"$@"
)

# corecode:search + depthck + uniq
fsvy()(c="find -L ./ -false"
	for i; do c="$c -o -path '*'$i";done; l=`$e"$c"`
	for i; do $p"$l"|grep -F "$i"|awk '{sv=$0;print gsub("[/]","") " " sv}'|
	sort -k 1.1,1n -k 2.2,2|awk '{print $2;exit}'; done
)

# libをまとめる
fA()(n=0;dir=`dirname $0`/tmpdir;mkdir $dir;cd $dir;
 for i;do
 	n=$((n+1))
 	cp ../$i $i
 	ar -x $i
 	for ii in *.o;do mv "$ii" "p${n}_$ii";done
 	ar -r lib$bn.aa *.o
 	rm *.o
 done
 $p'mv lib$bn.aa ../lib$bn.a'|fv
 cd ..;rm -r $dir
)

#-- yacc
# /*SH_OP y $e"$CW";fy
# /*SH_OP Y $e"$Cy";fU $( ($p"lib$bn.a";fg $Rs $Rh)|$n|grep '[.]a$'|$U)
fy()(
cat<<'EEE'|fv
f0 "${C}YACC" "${C}YACCE"<$Rs>myyacc.y
f0 "${C}LEX" "${C}LEXE"<$Rs>mylex.l
lex mylex.l; yacc -p zz -dv myyacc.y
cat y.tab.c lex.yy.c > $Rs
gcc -c y.tab.c lex.yy.c -lfl `fA $Rs $Rh`
rm mylex.l myyacc.y lib$bn.a
ar r lib$bn.a `fo $Rs` y.tab.o lex.yy.o
$p"lib$bn.a"
EEE
)

#-- longcmd
frf()(awk -v r="${C##*]}rf" 'match($0,r){
 s=substr($0, RSTART+RLENGTH+1)
 gsub(/.[^*]*$/, "", s);split(s, a)
 m="[ -f %s ]&&echo \"/*--copyfrom %s*\"/&&cat %s&&echo \"/*--copyend %s*\"/"
 for(i=1;v=a[i];i++){ system( sprintf(m, v,v,v,v))}
 next
 }
 {print}'
)

ftt()(a="`sed -ne 's@^HCUT_ADD(\([^)]*\).*@\1, @p' $tf|tr -d '\n'`NULL"
	if [ $# != 0 ];then	a=""; for i;do a="$a $i,";done; a="$a NULL"; fi
	sed -ne "p;/_RUN/bl;d;:l;/);/{c\\$O $a);$O p;d};n;bl"<$tf>$Rm;mv $Rm $tf)
i0=$e'fgr0 "^#ifdef TEST" "^#endif"<$R0|fbn>$tf'
i1=$e'fgR "^#ifdef TEST" "^#endif"<$Rs|fbn>$Rm;mv $Rm $Rs;fbn<$Rh>$Rm;mv $Rm $Rh'
fM()(
 valgrind -q --tool=massif --massif-out-file=./vmem.buf --stacks=yes --trace-children=yes $1>/dev/null
 ms_print ./vmem.buf|sed -ne '/[KMG]B/bl;d;:l;/snap/q;p;n;bl';rm ./vmem.buf)

/*SH_DE*/