#!/bin/bash # this script is for developers only set -e MAKE=/usr/bin/make true() { # {{{1 return 0 } hi() { # {{{1 local colors=(4 2 3 5 6 7 8 9) local re=() local i=0 for r in "$@"; do ((color=$i % ${#colors[@]})) || true color=${colors[$color]} r="${r/\#/\\#}" r="s#$r#[4${color}m\0#g" re[$i]="-e$r" ((i=i+1)) done sed -ur "${re[@]}" } hiecho() { # {{{1 echo """$@""" } # }}} stopfpm() { # {{{1 if [[ -f $1 ]]; then local pid=`cat $1 2>/dev/null || true` if [[ $pid -gt 0 ]]; then hiecho Stopping fpm $pid @ $1 kill $pid || true fi fi } xtest() { # {{{1 $MAKE ${MAKEOPTS} -f devel/test.mak clean all } prep() { # {{{1 $MAKE ${MAKEOPTS} -f devel/prepare.mak "$@" } mergepo() { # {{{1 prep local i find htdocs -iname '*.po' | while read -r i; do if [[ -f $i-merged ]]; then mv $i-merged $i fi done } po2php() { # {{{1 mergepo local phpfile find htdocs -iname '*.po' | while read -r i; do phpfile=${i/.po/.php} devel/po2php.awk < $i > $phpfile.tmp mv $phpfile.tmp $phpfile done } updatedeps() { # {{{1 local pwd=$(readlink -f "$(pwd)") local builddirname=${xcachesrcdir}-${phpbasename} local builddir=$(readlink -f $builddirname) if [[ -z $builddir ]]; then hiecho required $builddirname not found return 1 fi local sourceFile local sourceFilename find . -iname \*.c | LANG=C sort | while read -r sourceFile; do sourceFilename=${sourceFile#./} { case "$sourceFilename" in includes.c) echo '$(XCACHE_INCLUDES_I)' ;; esac echo ${sourceFilename%.c}.lo '$(builddir)/'${sourceFilename%.c}.lo: hiecho "Checking $sourceFilename ..." >&2 for dependency in $(gcc -DHAVE_XCACHE_TEST -DHAVE_XCACHE_DPRINT -DXCACHE_DEBUG -MM $sourceFile -I$PHPSDIR/$phpbasename/include/php/{,main,Zend,TSRM} -I. -I${builddir} -MG | sed 's#.*:##g' | sed 's#\\##g'); do dependency=$(readlink -f "$dependency") case "$dependency" in $pwd/*) dependency=${dependency#$pwd/} ;; $builddir/*) dependency="\$(builddir)/"${dependency#$builddir/} ;; esac case "$dependency" in *xc_const_string_opcodes_php*) for dependency in xcache/xc_const_string_*.h; do echo '$(srcdir)/'$dependency done ;; /*) ;; $sourceFilename) ;; xc_processor.h|\$\(builddir\)/xc_processor.h) echo '$(XCACHE_PROC_H)' ;; xc_processor.c.h|\$\(builddir\)/xc_processor.c.h) echo '$(XCACHE_PROC_C)' ;; *) if [[ -r $dependency ]]; then echo '$(srcdir)/'$dependency else hiecho "$dependency not found" >&2 fi esac done | LANG=C sort | uniq } | xargs done > Makefile.frag.deps } # }}}1 hiecho "Loading config devel/run.cfg" . devel/run.cfg PHPSDIR=${PHPSDIR:-$HOME/test} if [[ $# -eq 0 ]]; then set -- "${args[@]}" fi basename=$(basename $(pwd)) case "$basename" in *-*) # in build dir, starts from src dir dirs="${basename#*-}" xcachesrcdir=../${basename%%-*} cd $xcachesrcdir ;; *) # in src dir dirs=${dirs:-php5-debug-zts} xcachesrcdir=../$basename ;; esac touch devel.pid # ========================== do_phpize() { # {{{1 if [[ ! -x $PHPSDIR/$phpbasename/bin/phpize ]]; then hiecho $PHPSDIR/$phpbasename/bin/phpize not found exit fi export PATH=$PHPSDIR/$phpbasename/bin:$PATH local pedantic= case $phpbasename in php5|php5.4) pedantic=-pedantic-errors;; *) pedantic=-pedantic;; esac phpize --clean \ && phpize \ && CFLAGS="$CFLAGS -Dinline= -g -O0 $pedantic -Wno-variadic-macros -Wno-long-long -Wall -Wno-unused-parameter -Wno-unused-function -W -Wshadow -Werror=implicit-function-declaration -std=c89 -D_GNU_SOURCE -D_POSIX_SOURCE -Dinline=" ./configure \ --enable-xcache-cacher \ --enable-xcache-optimizer \ --enable-xcache-encoder \ --enable-xcache-decoder \ --enable-xcache-disassembler \ --enable-xcache-assembler \ --enable-xcache-coverager \ --enable-xcache-test \ --enable-xcache-dprint \ --enable-xcache-constant } do_make() { # {{{1 if [[ ! -f Makefile ]]; then do_phpize fi LANG=C $MAKE $MAKEOPTS "$@" 2>&1 \ | sed -ur \ -e 's#Werror=implicit-function-declaration#We/rror=i/mplicit-function-declaration#' \ -e 's#-pedantic-errors#-pedantic-e/rrors#' \ -e 's#\./xc_processor\.h#'$PWD'/xc_processor.h#' \ -e 's#\./xc_processor\.c\.h#'$PWD'/xc_processor.c.h#' \ | hi error implicit warn FAIL ret=${PIPESTATUS[0]} if [[ $ret -ne 0 ]]; then exit $ret fi } cleanfpm() { # {{{1 echo stopfpm $pidfile } # }}} run() { pidfile=$xcachesrcdir/devel.pid # prepare {{{1 case "$1" in phpize) if [[ -r Makefile ]]; then $MAKE $MAKEOPTS xcachesvnclean || true fi ;; esac rm -f php-src find -L . -type d -print0 | xargs -0 rmdir -p 2>/dev/null || true find -L . -type l -print0 | xargs -0 rm -fv lndir "$xcachesrcdir" >/dev/null || true find . -iname .\*.swp -print0 | xargs -0 rm -f ln -snf ~/src/php/${phpbasename%%-*} php-src for i in ~/src/php/$phpbasename/sapi/cgi/php{,-cgi}; do if [[ -r $i ]]; then ln -snf "$i" php-cgi fi done ln -snf ~/src/php/$phpbasename/sapi/cli/php php-cli f=~/src/php/$phpbasename/sapi/cli/php; [ -f "$f" ] && ln -snf "$f" php-cli f=~/src/php/$phpbasename/sapi/fpm/php-fpm; [ -f "$f" ] && ln -snf "$f" php-fpm case "$1" in phpized) CFLAGS=-DXCACHE_DEBUG do_phpize; return $?;; phpize) do_phpize; return $?;; make) shift; do_make "$@"; return $?;; *) do_make;; esac # }}}1 if [[ -z $1 ]]; then set -- devel/sample.cpp.php fi cmd=() phpApp=() tracer=() # run utils {{{1 case "$1" in retest) shift lastResult=$(ls php_test_results_*.txt | LANG=C sort | tail -n1) $MAKE $MAKEOPTS xcachetest "$@" TESTS="$(grep '^/.*\.phpt$' $lastResult | uniq | xargs)" return ;; test) shift case "$1" in *.phpt) $MAKE $MAKEOPTS xcachetest TEST_ARGS=-v TESTS="$*" return ;; */) $MAKE $MAKEOPTS xcachetest TESTS="$*" return ;; *) $MAKE $MAKEOPTS xcachetest return ;; esac ;; esac # }}} # pick tracer {{{1 case "$1" in ltr*) shift export USE_ZEND_ALLOC=0 tracer=(ltrace -s1024 -e malloc,realloc,free,write) ;; str*) shift tracer=(strace -s1024 -T) ;; gdb) shift #USE_ZEND_ALLOC=0 tracer=(gdb --args) ;; val*) shift export USE_ZEND_ALLOC=0 export ZEND_DONT_UNLOAD_MODULES=1 tracer=(valgrind -v --gen-suppressions=all) ;; esac # pick sapi {{{1 case "$phpbasename" in *-apache1*) cmd=($HOME/apache1/bin/httpd -X) ;; *-apache*) echo "Don't know how to run apache" exit 1 ;; *) case "$1" in dc) shift cmd=(./php-cli -c devel.ini) phpApp=(./bin/phpdc.phpr) ;; dboth) shift cmd=(./php-cli -c devel.ini) phpApp=(./bin/phpdc.phpr) set -- -c -d "$@" ;; dop) shift cmd=(./php-cli -c devel.ini) phpApp=(./bin/phpdc.phpr) set -- -c -d "$@" ;; fcgi) shift cmd=(./php-cgi -q -c devel.ini) set -- -b 1026 ;; fpm) shift cmd=(./php-fpm -c devel.ini -y devel.fpm -g $(readlink -f $pidfile)) set -- ;; *) cmd=(./php-cgi -q -c devel.ini) ;; esac "${cmd[@]}" -v || true esac # hack sample.cpp.php {{{1 case "$1" in *.cpp.php) < "$1" \ sed -r -e 's#__#____#g' \ | cpp -C -P -traditional-cpp -undef -ffreestanding -DPHP_VERSION=$phpVersion \ | sed -r -e 's#^ +##g' -e 's#\t +#\t#g' -e 's#____#__#g' > devel.php.tmp || exit $? if [[ ! -e devel.php ]] || ! cmp devel.php.tmp devel.php >/dev/null; then cat devel.php.tmp > devel.php else rm -f devel.php.tmp fi shift set -- devel.php "$@" ;; esac # run {{{1 set -- "${tracer[@]}" "${cmd[@]}" "${phpApp[@]}" "$@" case "${cmd[0]}" in *php-fpm*) stopfpm hiecho Starting fpm "$@" ... "$@" | tee output.php echo -n "Ctrl-C to stop" trap cleanfpm SIGINT SIGTERM exit cat > /dev/null || true stopfpm return ;; *) hiecho "$@" case "${tracer[@]}" in gdb*|val*) "$@" ;; *) "$@" | tee output.php ret=${PIPESTATUS[0]} echo exit = $ret >&2 return $ret ;; esac ;; esac # }}} } for phpbasename in "${dirs[@]}"; do phpVersion=${phpbasename%%-*} phpVersion=${phpVersion##php} phpVersion=${phpVersion/./} case "$phpVersion" in ??) phpVersion="${phpVersion}0";; ?) phpVersion="${phpVersion}00";; esac # devel actions case "$1" in prep*) shift; prep "$@"; exit;; tags) shift; rm -f tags; prep tags "$@"; exit;; po2php) po2php; exit;; mergepo) mergepo; exit;; dep*) updatedeps; exit;; xtest) xtest; exit;; stopfpm) stopfpm devel.pid; exit;; esac mkdir -p ${xcachesrcdir}-${phpbasename} cd ${xcachesrcdir}-${phpbasename} || exit lndir ${xcachesrcdir} >/dev/null || true pwd run "$@" done