#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) 2017 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 /*-* @_name msgp.c/h @auther momi-g @brief printf() wrapper functions @_synopsys void pf1-3(const char* fmt, ...) void npf1-3(const char* fmt, ...) void epf(const char* fmt, ...) void nepf(condt char* fmt, ...) void dbg(...) pf_t pfset(FILE* p1, FILE* p2, FILE* p3, FILE* dg) pf_t pfget(void) pf_t pfpush(pf_t obj) @_eg #include "msgp.h" int main() { pf1("aa"); // automatically add '\n' npf2("bb"); // header 'n' no newline pf3("cc"); dbg("dd"); // >> disp: aa, bb, cc, dd pfset(NULL,stderr,NULL,PF_NOCHANGE); //>> pf1,pf2,pf3,dbg setting npf1("aa"); pf2("bb"); pf3("cc"); dbg("dbg is", 123, "valiable"); // >> disp: bb, dbg pf_t old = pfset(stdout, stdout, stdout, stderr); //>> dfl setting pf1("info: %s", old.tostring); epf("epf/nepf is always disp to stderr."); } // ~$ gcc src.c msgp.c @param fmt printf fmt. @param p1-dg output dst ptr + NULL(noout), PF_NOCHANGE(use before fp) @param obj output setting rtns before setting obj. use it to restore. @return pfset()/pfpush() rtns before setting. pfget() rtns current setting. @details dbg() is printf debug helper. not need args type(int, char* etc). eg) dbg(12,num,s,"comment",1.11); // noarg, dbg() is err. >>> DBG: src.c 7: main(): cnt:1 pid:17477 arg:(12,num,s,"comment",1.11) 12 = i:12 / d:-1.72631 / p:0xc / c:\014 '\f' / s:(mem_err) num = i:678 / d:-1.72631 / p:0x2a6 / c:\246 '?' / s:(mem_err) s = i:4636870 / d:-1.72631 / p:0x46c0c6 / c:\306 '?' / s:abc "comment" = i:4636911 / d:-1.72631 / p:0x46c0ef / c:\357 '?' / s:comment 1.11 = i:1546188227 / d:1.11 / p:0x5c28f5c3 / c:\303 '?' / s:(mem_err) the type of argument is not specified. guess type and convert. i/d/p/c/s == int/dbl/ptr/char/str dbg() are stricted output size. max 1024 byte(1024 char) at once. dbg() supports variable args. allows at least 0-9 args. dbg() uses SIGSEGV/longjmp. it may cause some troubles if your pg uses signals. @_note - @_conforming posix-2001+ @version 1.2.0, 2021-01-09 -*/ #ifndef b7b7ab95edd0 #define b7b7ab95edd0 #include #if ( _POSIX_C_SOURCE +0 < 200112L ) #error "needs compiler posix-2001 or upper(c99+)" #include "//dmy inc, preprocess stoper" #endif /*replace printf()*/ #define pf1(...) mpfl_b7b7(1, 1, __VA_ARGS__) #define pf2(...) mpfl_b7b7(2, 1, __VA_ARGS__) #define pf3(...) mpfl_b7b7(3, 1, __VA_ARGS__) #define epf(...) mpfl_b7b7(0, 1, __VA_ARGS__) #define npf1(...) mpfl_b7b7(1, 0, __VA_ARGS__) #define npf2(...) mpfl_b7b7(2, 0, __VA_ARGS__) #define npf3(...) mpfl_b7b7(3, 0, __VA_ARGS__) #define nepf(...) mpfl_b7b7(0, 0, __VA_ARGS__) /* setting*/ #define pfset(...) pfset_b7b7(#__VA_ARGS__ , __VA_ARGS__) #define pfget(...) pfget_b7f7(__VA_ARGS__) #define pfpush(...) pfpush_b7f7(__VA_ARGS__) #include //uint #include //FILE* type #define PF_MAXINFOLEN 255 struct pfsetdata { char tostring[PF_MAXINFOLEN + 1]; // for tostring, "stderr, stdout ..." FILE* arrfp[5]; // epf + pf1,pf2,pf3,dbg } typedef pf_t; void mpfl_b7b7(int tgt, int nflg, const char* fmt, ...); pf_t pfset_b7b7(const char* s, void* pf1, void* pf2, void* pf3, void* dbg); pf_t pfget_b7f7(void); pf_t pfpush_b7f7(pf_t pulldata); #define PF_NOOUT NULL #define PF_NOCHANGE &pfset_b7b7 //dbg print // from licence: cc-by-sa // https://stackoverflow.com/questions/2632300 Q: Ed Marty -> A: Matthew Slattery #define ARGCNT(...) ARGCNT_2(__VA_ARGS__,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1) #define ARGCNT_2(args,n16,n15,n14,n13,n12,n11,n10,n9,n8,n7,n6,n5,n4,n3,n2,num,...) ARGCNT_3(num) #define ARGCNT_3(a) ITERMCR_ ## a // https://stackoverflow.com/questions/44479282 Q: user1150609 -> A: H Walters #define ITERMCR_1(a) dbg_b7b7_middle( 1, #a,a) #define ITERMCR_2(a,...) dbg_b7b7_middle( 2, #a,a); ITERMCR_1(__VA_ARGS__) #define ITERMCR_3(a,...) dbg_b7b7_middle( 3, #a,a); ITERMCR_2(__VA_ARGS__) #define ITERMCR_4(a,...) dbg_b7b7_middle( 4, #a,a); ITERMCR_3(__VA_ARGS__) #define ITERMCR_5(a,...) dbg_b7b7_middle( 5, #a,a); ITERMCR_4(__VA_ARGS__) #define ITERMCR_6(a,...) dbg_b7b7_middle( 6, #a,a); ITERMCR_5(__VA_ARGS__) #define ITERMCR_7(a,...) dbg_b7b7_middle( 7, #a,a); ITERMCR_6(__VA_ARGS__) #define ITERMCR_8(a,...) dbg_b7b7_middle( 8, #a,a); ITERMCR_7(__VA_ARGS__) #define ITERMCR_9(a,...) dbg_b7b7_middle( 9, #a,a); ITERMCR_8(__VA_ARGS__) #define ITERMCR_10(a,...) dbg_b7b7_middle(10, #a,a); ITERMCR_9(__VA_ARGS__) #define ITERMCR_11(a,...) dbg_b7b7_middle(11, #a,a); ITERMCR_10(__VA_ARGS__) #define ITERMCR_12(a,...) dbg_b7b7_middle(12, #a,a); ITERMCR_11(__VA_ARGS__) #define ITERMCR_13(a,...) dbg_b7b7_middle(13, #a,a); ITERMCR_12(__VA_ARGS__) #define ITERMCR_14(a,...) dbg_b7b7_middle(14, #a,a); ITERMCR_13(__VA_ARGS__) #define ITERMCR_15(a,...) dbg_b7b7_middle(15, #a,a); ITERMCR_14(__VA_ARGS__) #define ITERMCR_16(a,...) dbg_b7b7_middle(16, #a,a); ITERMCR_15(__VA_ARGS__) // end licence: cc-by-sa //ref: http://idlysphere.blog66.fc2.com/blog-entry-181.html 可愛い。 //ref: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf >>A1.7 Punctuators(区切り子) //ref: https://bytes.com/topic/c/answers/218725-does-not-give-valid-preprocessing-token-why //ref: https://ja.stackoverflow.com/questions/34093 //ref: http://www.c-lang.org/detail/macro_detail.html #__line__ TYPE #define DBG_B7B7_MLEN 100 #define DBG_B7B7_BUFFSIZE 1024 #define dbg(...) dbg_sub( __VA_ARGS__+0) #define dbg_sub(...) dbg_b7b7_top(4, __FILE__, __LINE__, __func__, #__VA_ARGS__)\ ; ARGCNT(__VA_ARGS__)(__VA_ARGS__) ;dbg_b7b7_end(4) void dbg_b7b7_top(int plv, const char* fname, int nline, \ const char* fcname, const char* rawstr); void dbg_b7b7_middle(int agnum, char* rawlit, ...); void dbg_b7b7_end(int plv); // dbg() ... err //add void idbg_b7b7_top(void); void idbg_b7b7_end(void); #define idbg(...) idbg_b7b7_top();dbg_b7b7_top(4, __FILE__, __LINE__, __func__, #__VA_ARGS__)\ ; ARGCNT(__VA_ARGS__)(__VA_ARGS__) ;dbg_b7b7_end(4);idbg_b7b7_end(); #endif //SH_ED //SH_SC #include "*SH_bn*.h" #include #include #include #include //exit() #include #include //getpid() fd, STDERR_FILENO. FILE* ... stdout stream. #include //intptr_t type #include //siginfo_t static int GLdbgcounter = 0; char GLdbgbuffer[DBG_B7B7_BUFFSIZE+1]={}; static pf_t pfdata; //pfdata={NULL,{NULL, x 4} }; //glは自動でnil init static int GLdbgmode = 0; //add. idbg static char sbuf[PF_MAXINFOLEN+1]; #ifdef TEST #include "hcut.hpp" #include "msgp.h" #endif //------ static void pfdata_initck(void) { if(pfdata.tostring[0] == '\0') { strncpy(pfdata.tostring, "stdout, stdout, stdout, stderr", PF_MAXINFOLEN); pfdata.arrfp[0] = stderr; //epf(). fixed. static. nochange. pfdata.arrfp[1] = stdout; pfdata.arrfp[2] = stdout; pfdata.arrfp[3] = stdout; pfdata.arrfp[4] = stderr; } } // stdout系はマクロなのでまともに初期化子として扱えない。ヘッダで初期化出来ない。 // 全ての関連関数で監視して初利用でトラップ初期化しかない。 //printf() parser void mpfl_b7b7(int plv, int nlflg, const char* fmt, ...) { pfdata_initck(); FILE* fp = pfdata.arrfp[plv]; va_list vl; // vl = ... vl means pointer or lists of 3dot(many args) va_start(vl, fmt); if(fp == NULL) { goto MPFL_END; } vfprintf(fp, fmt, vl); if(nlflg==1) { fprintf(fp, "\n"); } fflush(fp); MPFL_END: va_end(vl); //macros end return; } //setting funcs pf_t pfset_b7b7(const char* s, void* p1, void* p2, void* p3, void* dg) { // constのカンマで数えられる。//pfset(0x1111,0x1032) etc. pfdata_initck(); pf_t rbuf=pfdata; char* bbuf[5]; //元をスプリットしとく bbuf[1]=strtok(pfdata.tostring, ", \t\n"); for(int i=2; i<5; i++) { bbuf[i]=strtok(NULL, ", \t\n"); } //更新もスプリットする char* inbuf=(char*) calloc(PF_MAXINFOLEN +1, sizeof(char)); strncpy(inbuf, s, PF_MAXINFOLEN); char* abuf[5]; abuf[1]=strtok(inbuf, ", \t\n"); for(int i=2; i<5; i++) { abuf[i]=strtok(NULL, ", \t\n"); } if(p1 == (void*)PF_NOCHANGE) { abuf[1] = bbuf[1]; p1=(void*)pfdata.arrfp[1] ;} if(p2 == (void*)PF_NOCHANGE) { abuf[2] = bbuf[2]; p2=(void*)pfdata.arrfp[2] ;} if(p3 == (void*)PF_NOCHANGE) { abuf[3] = bbuf[3]; p3=(void*)pfdata.arrfp[3] ;} if(dg == (void*)PF_NOCHANGE) { abuf[4] = bbuf[4]; dg=(void*)pfdata.arrfp[4] ;} sbuf[0] ='\0'; snprintf(sbuf, PF_MAXINFOLEN, "%s, %s, %s, %s", abuf[1], abuf[2], abuf[3], abuf[4] ); strcpy(pfdata.tostring, sbuf); pfdata.arrfp[1] = (FILE*)p1; pfdata.arrfp[2] = (FILE*)p2; pfdata.arrfp[3] = (FILE*)p3; pfdata.arrfp[4] = (FILE*)dg; free(inbuf); return rbuf; } pf_t pfget_b7f7(void) { pfdata_initck(); return pfdata; } pf_t pfpush_b7f7(pf_t obj) { pfdata_initck(); pf_t rbuf=pfdata; pfdata = obj; return rbuf; } //dbg funcs //add numonly void idbg_b7b7_top(void){ GLdbgmode= -1;}; void idbg_b7b7_end(void){ GLdbgmode= 0;}; #include static sigjmp_buf marktry; // try-catch sigsegv. sigjmp ... posix2001 upper static void dbg_siggrep(int flg, int signum); void dbg_b7b7_top(int plv, const char* fname, int nline , const char* fcname, const char* rawstr) { pfdata_initck(); FILE* fp = pfdata.arrfp[plv]; GLdbgcounter++; //global counter for debag info if(fp == NULL|| GLdbgbuffer[0]!='\0') { return; } int orest= DBG_B7B7_BUFFSIZE - 1; GLdbgbuffer[0]='\0'; snprintf( GLdbgbuffer, orest, "DBG: %s %d: %s(): cnt:%d pid:%d arg:(%.*s)\n", fname, nline, fcname, GLdbgcounter, getpid(), strlen(rawstr)-2, rawstr); return; } void dbg_b7b7_middle(int agnum, char* rawlit, ...) { if( GLdbgbuffer[0]=='\0') { return; } if(agnum==1 && strlen(rawlit)==2){return;} //dbg()系。要素があれば+0で3以上になる。 int cutsz=0; if(agnum==1){cutsz=2;} char sbuf[DBG_B7B7_MLEN+1]={0}; int orest = DBG_B7B7_MLEN; snprintf( sbuf, orest, "\t%.*s = ", strlen(rawlit)-cutsz, rawlit); orest=DBG_B7B7_MLEN - strlen(sbuf); va_list vl, vls; va_start(vl, rawlit); va_copy(vls, vl); int ri; double rd; char* rp; //int系. double系が先だとそっちに行くから。アクセス違反はsegvで逃げる。 ri = va_arg(vl, int); //local変数 int未満は全部intに格上げされる。 snprintf( &(sbuf[strlen(sbuf)]), orest, "i:%d / ", ri); orest=DBG_B7B7_MLEN - strlen(sbuf); //double系. va_copy(vl, vls); rd = va_arg(vl, double); snprintf( &(sbuf[strlen(sbuf)]), orest, "d:%g / ", rd); orest=DBG_B7B7_MLEN - strlen(sbuf); //ptr va_copy(vl, vls); rp = va_arg(vl, char*); // vl_add -> argpos_add -> argraw(int/char*) snprintf( &(sbuf[strlen(sbuf)]), orest, "p:%p / ", rp); orest=DBG_B7B7_MLEN - 1 - strlen(sbuf); //char // %hh + c ... int args. not char args. (promote args problem. see man printf) // edit escape chars \n>>\\n etc // va_start(vl, rawlit); // ri = va_arg(vl, int); char cbuf[2]= {(char)ri, 0}; char* msg; if(cbuf[0] == '\0') { msg = (char*)"\\0";} else if(cbuf[0] == '\a') { msg = (char*)"\\a";} else if(cbuf[0] == '\b') { msg = (char*)"\\b";} else if(cbuf[0] == '\t') { msg = (char*)"\\t"; } else if(cbuf[0] == '\n') { msg = (char*)"\\n";} else if(cbuf[0] == '\v') { msg = (char*)"\\v";} else if(cbuf[0] == '\f') { msg = (char*)"\\f";} else if(cbuf[0] == '\r') { msg = (char*)"\\r";} else if(1){ msg = cbuf; } // hh ... size select snprintf( &(sbuf[strlen(sbuf)]), orest, "c:\134%03hho '%s' / s:", ri, msg ); orest=DBG_B7B7_MLEN - strlen(sbuf); //string if(GLdbgmode != -1 ){ //add str skip mode. avoid SEGV trap err // http://www.nurs.or.jp/~sug/soft/super/longjmp.htm // try - catch signal stop if(sigsetjmp(marktry, SIGSEGV) == 0) { dbg_siggrep(1, SIGSEGV); //set trap // #include strncpy( &(sbuf[strlen(sbuf)] ), rp, orest); } else { strncpy( &(sbuf[strlen(sbuf)]), "(mem_err)", orest ); } dbg_siggrep(0, SIGSEGV); //reset trap }else{ strncpy( &(sbuf[strlen(sbuf)]), "(skip)", orest ); } va_end(vl); va_end(vls); //add + \n if(strlen(sbuf) >= DBG_B7B7_MLEN-1 ){ sbuf[DBG_B7B7_MLEN-1]='*'; } int len = strlen(GLdbgbuffer); strncpy( &(GLdbgbuffer[len]), sbuf, DBG_B7B7_BUFFSIZE-len-1); len = strlen(GLdbgbuffer); if( len+1 == DBG_B7B7_BUFFSIZE ){GLdbgbuffer[len-1]='\n';} else{GLdbgbuffer[len]='\n';} return; } void dbg_b7b7_end(int plv) { FILE* fp = pfdata.arrfp[plv]; if(fp==NULL) {goto lbl_RTN;} fprintf(fp, "%s\n", GLdbgbuffer); fflush(fp); // buff is an evil lbl_RTN:; GLdbgbuffer[0]='\0'; return; } static void dbg_sigfunc(int signum, siginfo_t* info, void* ctx) { //sighandle, sigcatch?, siginterrrupt?,sig"exception code(java)"? //in code, very,very, verrrry stricted. //1. use only "signal safe function" //2. use global(outer function) var, "volatile sig_atomic_t" //3. you can use auto var (stack, local memory?) //http://d.hatena.ne.jp/yupo5656/20040712/p2 siglongjmp(marktry, 1); // char msg[] = "sig_catch. err?\n"; // write(STDERR_FILENO, msg, strlen(msg) ); // #include } // (1/0, SIGSEGV) on, off. if get sig, rtn 1(dbg_sigfunc), else rtn 0. static void dbg_siggrep(int flg, int signum) { static struct sigaction sct_ss; //snapshot for save state. struct sigaction sct = {0}; sigemptyset(&(sct.sa_mask)); //clear. 0xFFFF -> block recall SIG when this method running. sigaddset(&sct.sa_mask, signum); // target signal if(flg==0) { // reset trap sigaction(signum, &sct_ss, NULL); //sct.sa_handler = SIG_DFL; //SIG_DFL or SIG_IGN } else { //set trap //signal select action 1.def 2.ign 3.func //3.func ...SA_SIGINFO+sa_sigaction or sct.sa_handler = *func. //sct.sa_handler = SIG_IGN; //set proc sig work enable(def) or disable(catch) . sct.sa_flags = SA_SIGINFO; //send sig state to myfunc(); sct.sa_flags |= SA_RESETHAND; //add one shot setting. // zzz.sa_flags = zzz.sa_flags | SA_RESTART; //default sigtrap drop blocking method. //sct.sa_flags |= SA_NOCLDWAIT; //if SIG_DEF. SIG_IGN ignore sa_flags. sct.sa_sigaction = dbg_sigfunc; // restricted type, (int, siginfo_t *, void *) sigaction(signum, &sct, &sct_ss); //run(set) trap NULL...oldsetting buf. } } #ifdef TEST HCUT_ADD(t_dbg) { dbg(1,10); int a=100; char* s = "unkokko"; dbg(3,10.2, 10.3, s, 'z', a); dbg(); } #endif /*SH_SMP sample #include "msgp.h" int main() { int a= 123 ; int b = 223; double c = 12.3; char* d = NULL; dbg(a,c,b,d); // return 0; epf("epf"); pf1("pf1"); npf1("npf1\n"); pf2("pf2"); pf3("pf3"); dbg("dbg", printf("abc%d\n",1) ); puts("--"); // FILE* fp = stdout; pf_t old=pfset(NULL,PF_NOCHANGE,fp,NULL); // pf1,pf2,pf3,dbg. NULL=noout pf_t now=pfget(); puts(old.tostring); // >> stdout,sout,sout,serr puts(now.tostring); // >> NULL,stdout(...PF_NOCHANGE),fp,NULL epf("epf"); pf1("pf1"); pf2("pf2"); pf3("pf3"); dbg("dbg"); puts("--"); // old = pfset(stdout,NULL,NULL, stdout); now = pfget(); puts(old.tostring); // >> NULL,stdout,fp,NULL puts(now.tostring); // >> stdout,NULL,NULL, stdout epf("epf"); pf1("pf1"); pf2("pf2"); pf3("pf3"); dbg("dbg"); puts("--"); // old = pfpush(old); now = pfget(); puts(old.tostring); // >> stdout,NULL,NULL, stdout ... save&load. puts(now.tostring); // >> NULL,stdout,fp,NULL epf("epf"); pf1("pf1"); pf2("pf2"); pf3("pf3"); dbg("dbg"); puts("--"); } /*SH_SMPE sampleend*/ #ifdef TEST HCUT_RUN("stderr", 1, /* keep newline. use for SH sed edit, -t test.*/ t_dbg); #endif /* change log -- 2021-01-18 Momi-g * msgp.sh.c ( dbg() macro ): improve __VA_ARGS__+0, allow dbg(void) api * (dbg_b7b7_top): fix msg to skip "+0" * (dbg_b7b7_middle): fix msg, add dbg(void) ck code * (t_dbg test): add test 2021-01-09 Momi-g * msgp.sh.c (pfset): fix pfset strcpy src/dst overlap bug * msgp.sh.c (hcut.hpp): adapt new unittest macro * msgp.sh.c (sh code): adapt new build script 2020-05-15 Momi-g * msgp.sh.c (dbg): rewrite code, fix va_arg double bug */ /*SH_ED*/ /*SH_OP _ a=`sed -ne "/${C}DF/!d;:l;n;/${C}DE/q;p;bl"<$R0`;eval "$a" #*/ /*SH_OP h $p"-t/s/b:test/smpl/bld /T:t+mem /f:functop" #*/ /*SH_OP f sed -ne 's@^HCUT_ADD(\([^)]*\).*@\1,@p'<$R0;sed -e '/^[a-z].*)/!d;/;/d'<$R0 #*/ /*SH_OP t $e"$CW";[ "$1" != "" ]&&$i4;cat $Rs $tf>$Rm;$p'cc -g $Rm `fA $Rm`'|fv #*/ /*SH_OP T $e"$Ct";$p"valgrind --leak-check=full ./a.out 2>&1|sed -e '/SUMMA/!d;n;n;n;n'"|fv #*/ /*SH_OP M $p"$i5"|fv #*/ /*SH_OP s $e"$CB";f0 "${C}SMP" "${C}SMPE"<$Rs>eg.c;$p'cc eg.c $Rs `fA eg.c`'|fv #*/ /*SH_OP b $e"$CW";$p'cc -c $Rs -O2 -Wall `fd`'|fv;$p"$bn.o" #*/ /*SH_OP B $e"$Cb";$p"rm lib$bn.a;ar r lib$bn.a `fo $Rs` $bn.o"|fv;$p"lib$bn.a" #*/ /*SH_OP U $e"$CB";fU $( ($p"lib$bn.a";fg "$Rh" "$Rs")|$n|grep '[.]a$'|$u) #*/ /*SH_OP S $e"$CW";$p'cc $Rs `fA $Rs $Rh` -g -pg -Wall -shared -fPIC -o lib'$bn'.so'|fv;$p"lib$bn.so" #*/ /*SH_OP W $e"$Cm$O$Cw";$i0;$i1;$cn<$Rh>$Rm;mv $Rm $Rh;$p"$Rs $tf" #*/ /*SH_DF #--name bn=`basename ${Rs%.*}` tf=${bn}_ts.${Rs##*.} #--cmd e="eval " p="$Rp" cn=$e'sed -e "s@\*${C##*]}bn\*@$bn@g"' n=$e"tr ' \t' '\n'|grep -v ^$" N=$e'(tr "\n" " ";$p)' u=$e'$n|sort -u|$N' f0()(sed -ne "/$1/!d;:l;n;/$2/d;p;bl"|$cn) f1()(sed -e "/$1/!d;:l;/$2/{p;d};n;bl"|$cn) fo()(a=$#;set `cat $@|(sed -ne 's/^#in.*"\(.*\.h\)".*$/\1/p';$p"$@")|$u` if [ $a = $# ];then $p"$@"|$n|sed -ne 's/\.h$/.o/p'|(grep -vF "$bn.o";ls)| sort|uniq -d|$u;else fo "$@";fi) fg()(sed -ne 's/.*\*SH_co\*\([^*]*\).*$/\1/p' "$@"|$u) fd()(find `dirname $0` -type d|sed -e 's/\(.*\)/ -I\1 -L\1 /g'|$N) fA()( (fo "$@";fg "$@";fd "$@")|$N) fU()(n=0;dir=`dirname $0`/tmpdir;mkdir $dir||exit 1;cd $dir||exit 1; 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 mv lib$bn.aa ../lib$bn.a cd ..;rm -r $dir ) fv()(while read -r a;do $e"cat</dev/stderr;$e"$a";done) i0=$e'f0 "^#ifdef TEST" "^#endif"<$Rm|$cn>$tf' i1=$e'sed -ne "/^#ifdef TEST/bl;p;d;:l;n;/^#endif/d;bl"<$Rs|$cn>$Rm;mv $Rm $Rs' i4=$e'sed -ne "p;/_RUN/bl;d;:l;/);/{c\\$O $1);$O p;d};n;bl"<$tf>$Rm;mv $Rm $tf' i5="valgrind -q --tool=massif --massif-out-file=./vmem.buf \ --stacks=yes --trace-children=yes ./a.out >/dev/null ms_print ./vmem.buf|sed -ne '/[KMG]B/bl;d;:l;/snap/q;p;n;bl';rm ./vmem.buf" /*SH_DE*/