#include /* C='^[/][/*]SH_';O=${0##*[/]};R=`dirname $0`;R=${R%/}/;R0=$R$O;Rb=$R${O%%.*};O=" ";R=${0##*.};Rs=$Rb.$R;Rm=$Rb.tmp.$R;Rh=$Rb.h;R=$Rs$Rh$Rm;Rp='printf %s\n ';Rc=: [ "${R##*$0*}" = '' ]&&$Rp"$0:NG suffix"&&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 */ //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 . */ //SH_ED //SH_HD ----- #define foo 123 int brp_hw(); //SH_ED /*SH_SC -----*/ #include "brp.h" #include int brp_hw(){ printf("hello,world, %d\n", foo); return 0; } #ifdef MYTEST // gcc -DMYTEST aaa.c ...etc int main(){ brp_hw(); } #endif //SH_ED //---- usage block /*SH_OP h cat "$R0" | sed -ne "/${C}OP h/!d;:l;p;n;/${C}ED/q;bl" #q...quit*/ /* brp, embedded preprocessor. posix-shell script. (opt: -m/-w + yours ) basic usage --- this script works by just copying and pasting into your file. 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 -H if you need detail help (7-8 pages in total). //SH_ED //SH_OP H cat "$R0" | sed -ne "/${C}OP H/bl;d;:l;p;n;bl" extended usage --- add code as follows, ... #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 ...(license block) + //SH_OP x date + //SH_OP y echo "he said, "; eval "$Ca" #Ca ... Command -a... ...(Anywhere in this file except header script. keep linehead.) 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 oldopt. - 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 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 -- 2020-01-04 Momi-g * brp.sh.c : v1.0.0 releases. */