Skip to content

Commit

Permalink
Merge pull request #3 from mzhurovich/optimize
Browse files Browse the repository at this point in the history
Function opimization routines + tests
  • Loading branch information
dkorolev committed Mar 8, 2015
2 parents 4a7cab3 + 3dac18f commit 7a69a48
Show file tree
Hide file tree
Showing 39 changed files with 939 additions and 208 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ coverage.info
**/*~

demo/binary

# In the `fncas` repository, Bricks are installed/updated from GitHub.
# To avoid conflicts, KnowSheet/Bricks should not be checked in.
Bricks
8 changes: 4 additions & 4 deletions KnowSheet/scripts/KnowSheetDir.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
# Prints its path.

dir=$(cd $(dirname $0) && pwd)
subdir=KnowSheet
subdir="KnowSheet"

while [ ! -d ${dir}/${subdir} ] ; do
while [ ! -d "${dir}/${subdir}" ] ; do
[ "$dir" == "/" ] && break
dir=$(dirname $dir)
dir=$(dirname "$dir")
done

[ -d "$dir/${subdir}" ] && echo "${dir}/${subdir}" || exit 1
[ -d "${dir}/${subdir}" ] && echo "${dir}/${subdir}" || exit 1
17 changes: 17 additions & 0 deletions KnowSheet/scripts/KnowSheetReadlink.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash
#
# `readlink -e` replacement compatible with Mac OS X `readlink` implementation.
# Credits to http://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in and https://github.com/tarruda/zsh-autosuggestions/issues/38#issuecomment-69258372

set -u -e

SOURCE="$1"
while [ -h "$SOURCE" ]; do # Resolve $SOURCE until the file is no longer a symlink.
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # If $SOURCE was a relative symlink, we need to resolve it
# relative to the path where the symlink file was located.
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"

echo "$DIR/$(basename "$1")"
16 changes: 10 additions & 6 deletions KnowSheet/scripts/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
.PHONY: test all indent clean check coverage

# Need to know where to invoke scripts from, since `Makefile` can be a relative path symlink.
KNOWSHEET_SCRIPTS_DIR=$(dir $(shell readlink -e $(lastword $(MAKEFILE_LIST))))
KNOWSHEET_SCRIPTS_DIR := $(patsubst %\,%,$(patsubst %/,%,$(dir $(shell readlink $(lastword $(MAKEFILE_LIST))))))
KNOWSHEET_SCRIPTS_DIR_FULL_PATH := $(shell "$(KNOWSHEET_SCRIPTS_DIR)/KnowSheetReadlink.sh" "$(KNOWSHEET_SCRIPTS_DIR)" )

CPLUSPLUS?=g++
CPPFLAGS=-std=c++11 -Wall -W
Expand All @@ -26,17 +27,20 @@ BIN=$(SRC:%.cc=.noshit/%)

OS=$(shell uname)
ifeq ($(OS),Darwin)
CPPFLAGS+= -x objective-c++ -fobjc-arc
CPPFLAGS+= -stdlib=libc++ -x objective-c++ -fobjc-arc
LDFLAGS+= -framework Foundation
endif

default: all
if [ -f test.cc ] ; then \
.noshit/test --bricks_runtime_arch=${OS} ; \
make test ;\
else \
find .noshit/ -executable -type f -exec "{}" ";" ; \
fi

test: .noshit/test
.noshit/test --bricks_runtime_arch=${OS}

debug:
ulimit -c unlimited && touch test.cc && rm -f core && make ./.noshit/test && (./.noshit/test && echo OK || gdb ./.noshit/test core)

Expand All @@ -50,10 +54,10 @@ clean:
${CPLUSPLUS} ${CPPFLAGS} -o $@ $< ${LDFLAGS}

indent:
${KNOWSHEET_SCRIPTS_DIR}/indent.sh
${KNOWSHEET_SCRIPTS_DIR_FULL_PATH}/indent.sh

check:
${KNOWSHEET_SCRIPTS_DIR}/check-headers.sh
${KNOWSHEET_SCRIPTS_DIR_FULL_PATH}/check-headers.sh

coverage:
${KNOWSHEET_SCRIPTS_DIR}/coverage-report.sh
${KNOWSHEET_SCRIPTS_DIR_FULL_PATH}/coverage-report.sh
9 changes: 5 additions & 4 deletions KnowSheet/scripts/check-all-headers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@

set -u -e

SCRIPT_DIR=$(dirname $(readlink -e "$BASH_SOURCE"))
RUN_DIR=$PWD
KNOWSHEET_SCRIPTS_DIR=$( dirname "${BASH_SOURCE[0]}" )
KNOWSHEET_SCRIPTS_DIR_FULL_PATH=$( "$KNOWSHEET_SCRIPTS_DIR/KnowSheetReadlink.sh" "$KNOWSHEET_SCRIPTS_DIR" )
RUN_DIR_FULL_PATH=$( "$KNOWSHEET_SCRIPTS_DIR/KnowSheetReadlink.sh" "$PWD" )

echo -e "\033[1m\033[34mTesting all headers to comply with the header-only paradigm.\033[0m"

for i in $(for i in $(find . -iname "*.h" | grep -v 3party) ; do dirname $i ; done | sort -u) ; do
for i in $(for i in $(find . -iname "*.h" | grep -v 3party) ; do dirname "$i" ; done | sort -u) ; do
echo -e "\033[1mDirectory\033[0m: $i"
cd $i && $SCRIPT_DIR/check-headers.sh && cd $RUN_DIR && continue
cd "$i" && "$KNOWSHEET_SCRIPTS_DIR_FULL_PATH/check-headers.sh" && cd "$RUN_DIR_FULL_PATH" && continue
echo -e "\033[1m\033[31mTerminating.\033[0m" && exit 1
done

Expand Down
24 changes: 13 additions & 11 deletions KnowSheet/scripts/check-headers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,30 @@ set -u -e
CPPFLAGS="-std=c++11 -g -Wall -W -DBRICKS_CHECK_HEADERS_MODE"
LDFLAGS="-pthread"

TMPDIR=.noshit
# NOTE: TMP_DIR must be resolved from the current working directory.

rm -rf $TMPDIR/headers
mkdir -p $TMPDIR/headers
TMP_DIR_NAME=".noshit"

rm -rf "$TMP_DIR_NAME/headers"
mkdir -p "$TMP_DIR_NAME/headers"

echo -e -n "\033[1mCompiling\033[0m: "
for i in $(ls *.h | grep -v ".cc.h$") ; do
echo -e -n "\033[36m"
echo -n "$i "
echo -e -n "\033[31m"
ln -sf $PWD/$i $PWD/$TMPDIR/headers/$i.g++.cc
ln -sf $PWD/$i $PWD/$TMPDIR/headers/$i.clang++.cc
g++ -I . $CPPFLAGS -c $PWD/$TMPDIR/headers/$i.g++.cc -o $PWD/$TMPDIR/headers/$i.g++.o $LDFLAGS
clang++ -I . $CPPFLAGS -c $PWD/$TMPDIR/headers/$i.clang++.cc -o $PWD/$TMPDIR/headers/$i.clang++.o $LDFLAGS
ln -sf "$PWD/$i" "$PWD/$TMP_DIR_NAME/headers/$i.g++.cc"
ln -sf "$PWD/$i" "$PWD/$TMP_DIR_NAME/headers/$i.clang++.cc"
g++ -I . $CPPFLAGS -c "$PWD/$TMP_DIR_NAME/headers/$i.g++.cc" -o "$PWD/$TMP_DIR_NAME/headers/$i.g++.o" $LDFLAGS
clang++ -I . $CPPFLAGS -c "$PWD/$TMP_DIR_NAME/headers/$i.clang++.cc" -o "$PWD/$TMP_DIR_NAME/headers/$i.clang++.o" $LDFLAGS
done
echo

echo -e -n "\033[0m\033[1mLinking\033[0m:\033[0m\033[31m "
echo -e '#include <cstdio>\nint main() { printf("OK\\n"); }\n' >$TMPDIR/headers/main.cc
g++ -c $CPPFLAGS -o $TMPDIR/headers/main.o $TMPDIR/headers/main.cc $LDFLAGS
g++ -o $TMPDIR/headers/main $TMPDIR/headers/*.o $LDFLAGS
echo -e '#include <cstdio>\nint main() { printf("OK\\n"); }\n' >"$TMP_DIR_NAME/headers/main.cc"
g++ -c $CPPFLAGS -o "$TMP_DIR_NAME/headers/main.o" "$TMP_DIR_NAME/headers/main.cc" $LDFLAGS
g++ -o "$TMP_DIR_NAME/headers/main" $TMP_DIR_NAME/headers/*.o $LDFLAGS
echo -e -n "\033[1m\033[32m"
$TMPDIR/headers/main
"$TMP_DIR_NAME/headers/main"

echo -e -n "\033[0m"
26 changes: 16 additions & 10 deletions KnowSheet/scripts/coverage-report.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,29 @@ set -u -e
CPPFLAGS="-std=c++11 -g -Wall -W -fprofile-arcs -ftest-coverage -DBRICKS_COVERAGE_REPORT_MODE"
LDFLAGS="-pthread"

TMPDIR=.noshit
# NOTE: TMP_DIR must be resolved from the current working directory.

mkdir -p $TMPDIR
KNOWSHEET_SCRIPTS_DIR=$( dirname "${BASH_SOURCE[0]}" )
RUN_DIR_FULL_PATH=$( "$KNOWSHEET_SCRIPTS_DIR/KnowSheetReadlink.sh" "$PWD" )

TMP_DIR_NAME=".noshit"
TMP_DIR_FULL_PATH="$RUN_DIR_FULL_PATH/.noshit"

mkdir -p "$TMP_DIR_NAME"

for i in *.cc ; do
echo -e "\033[0m\033[1m$i\033[0m: \033[33mGenerating coverage report.\033[0m"
BINARY=${i%".cc"}
rm -rf $TMPDIR/coverage/$BINARY
mkdir -p $TMPDIR/coverage/$BINARY
g++ $CPPFLAGS $i -o $TMPDIR/coverage/$BINARY/binary $LDFLAGS
./$TMPDIR/coverage/$BINARY/binary || exit 1
gcov $i >/dev/null
BINARY="${i%".cc"}"
rm -rf "$TMP_DIR_NAME/coverage/$BINARY"
mkdir -p "$TMP_DIR_NAME/coverage/$BINARY"
g++ $CPPFLAGS "$i" -o "$TMP_DIR_NAME/coverage/$BINARY/binary" $LDFLAGS
"./$TMP_DIR_NAME/coverage/$BINARY/binary" || exit 1
gcov "$i" >/dev/null
geninfo . --output-file coverage0.info >/dev/null
lcov -r coverage0.info /usr/include/\* \*/gtest/\* \*/3party/\* -o coverage.info >/dev/null
genhtml coverage.info --output-directory $TMPDIR/coverage/$BINARY >/dev/null
genhtml coverage.info --output-directory "$TMP_DIR_NAME/coverage/$BINARY" >/dev/null
rm -rf coverage.info coverage0.info *.gcov *.gcda *.gcno
echo -e -n "\033[0m\033[1m$i\033[0m: \033[36m"
echo $(readlink -e $TMPDIR/coverage/$BINARY/index.html)
echo -n "$TMP_DIR_FULL_PATH/coverage/$BINARY/index.html"
echo -e -n "\033[0m"
done
55 changes: 36 additions & 19 deletions KnowSheet/scripts/full-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,52 +11,69 @@ set -u -e
CPPFLAGS="-std=c++11 -g -Wall -W -fprofile-arcs -ftest-coverage -DBRICKS_COVERAGE_REPORT_MODE"
LDFLAGS="-pthread"

TMPDIR=.noshit/fulltest
TMPDIR_FULL_PATH=$(readlink -e .)/.noshit/fulltest
# NOTE: FULL_TEST_DIR must be resolved from the current working directory.

GOLDEN_SUBDIR_NAME=golden
GOLDEN_FULL_PATH=$TMPDIR_FULL_PATH/$GOLDEN_SUBDIR_NAME
KNOWSHEET_SCRIPTS_DIR=$( dirname "${BASH_SOURCE[0]}" )
RUN_DIR_FULL_PATH=$( "$KNOWSHEET_SCRIPTS_DIR/KnowSheetReadlink.sh" "$PWD" )

FULL_TEST_DIR_NAME="zzz_full_test" # The `zzz` prefix guarantees the full test directory is down the list.
FULL_TEST_DIR_FULL_PATH="$RUN_DIR_FULL_PATH/$FULL_TEST_DIR_NAME"

ALL_TESTS_TOGETHER="everything"

GOLDEN_DIR_NAME="golden"
GOLDEN_FULL_PATH="$FULL_TEST_DIR_FULL_PATH/$GOLDEN_DIR_NAME"

# Concatenate all `test.cc` files in the right way, creating one test to rule them all.
mkdir -p $TMPDIR
echo "// Magic. Watch." > $TMPDIR/ALL_TESTS_TOGETHER.cc
mkdir -p "$FULL_TEST_DIR_NAME"
(
echo '// This file is auto-generated by KnowSheet/scripts/full-test.sh.' ;
echo '// It is updated by running `make run` in the top-level Bricks directory, along with the documentation.'
echo '// And it is checked in, much like the documentation, so that non-*nix systems can run all the tests.'
echo
echo '#include "port.h" // To have `std::{min/max}` work in Visual Studio, need port.h before STL headers.'
echo
echo '#include "dflags/dflags.h"'
echo '#include "3party/gtest/gtest-main-with-dflags.h"'
echo
) > "$FULL_TEST_DIR_NAME/$ALL_TESTS_TOGETHER.cc"

echo "#include \"dflags/dflags.h\"" >> $TMPDIR/ALL_TESTS_TOGETHER.cc
echo "#include \"3party/gtest/gtest-main-with-dflags.h\"" >> $TMPDIR/ALL_TESTS_TOGETHER.cc

echo -n -e "\033[0m\033[1mTests:\033[0m\033[36m"
for i in $(find . -iname test.cc | grep -v 3party | grep -v "/.noshit/"); do
echo "#include \"$i\"" >> $TMPDIR/ALL_TESTS_TOGETHER.cc
for i in $(find . -iname "*test.cc" | grep -v 3party | grep -v "/.noshit/" | sort -g); do
echo "#include \"$i\"" >> "$FULL_TEST_DIR_NAME/$ALL_TESTS_TOGETHER.cc"
echo -n " $i"
done

# Allow this one test to rule them all to access all the `golden/` files.
mkdir -p $GOLDEN_FULL_PATH
for dirname in $(find . -iname $GOLDEN_SUBDIR_NAME -type d | grep -v 3party | grep -v "/.noshit/"); do
(cd $dirname; for filename in * ; do ln -sf $PWD/$filename $GOLDEN_FULL_PATH ; done)
mkdir -p "$GOLDEN_FULL_PATH"
echo -e "\n\n\033[0m\033[1mGolden files\033[0m: \033[35m"
for dirname in $(find . -iname "$GOLDEN_DIR_NAME" -type d | grep -v 3party | grep -v "/.noshit/" | grep -v "$FULL_TEST_DIR_NAME"); do
(cd $dirname; for filename in * ; do cp -v "$PWD/$filename" "$GOLDEN_FULL_PATH" ; done)
done
echo -e -n "\033[0m"

(
# Compile and run The Big Test.
cd $TMPDIR
cd "$FULL_TEST_DIR_NAME"

echo -e "\033[0m"
echo -n -e "\033[1mCompiling all tests together: \033[0m\033[31m"
g++ $CPPFLAGS -I ../.. ALL_TESTS_TOGETHER.cc -o ALL_TESTS_TOGETHER $LDFLAGS
g++ $CPPFLAGS -I .. "$ALL_TESTS_TOGETHER.cc" -o "$ALL_TESTS_TOGETHER" $LDFLAGS
echo -e "\033[32m\033[1mOK.\033[0m"

echo -e "\033[1mRunning the tests and generating coverage info.\033[0m"
./ALL_TESTS_TOGETHER || exit 1
echo -e "\033[32m\033[1mALL TESTS PASS.\033[0m"
"./$ALL_TESTS_TOGETHER" || exit 1
echo -e "\n\033[32m\033[1mALL TESTS PASS.\033[0m"

# Generate the resulting code coverage report.
gcov ALL_TESTS_TOGETHER.cc >/dev/null
gcov "$ALL_TESTS_TOGETHER.cc" >/dev/null
geninfo . --output-file coverage0.info >/dev/null
lcov -r coverage0.info /usr/include/\* \*/gtest/\* \*/3party/\* -o coverage.info >/dev/null
genhtml coverage.info --output-directory coverage/ >/dev/null
rm -rf coverage.info coverage0.info *.gcov *.gcda *.gcno
echo
echo -e -n "\033[0m\033[1mCoverage report\033[0m: \033[36m"
readlink -e coverage/index.html
echo -n "$FULL_TEST_DIR_FULL_PATH/coverage/index.html"
echo -e -n "\033[0m"
)
42 changes: 42 additions & 0 deletions KnowSheet/scripts/gen-docu.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash
#
# This script generates the documentation in GitHub markdown format.
# It scans all `docu_*.*` files, uses `.md` directly and takes the lines starting with double space from `.h`.
#
# Best practices:
#
# 1) Make `docu_*.cc` files that should be passing unit tests `docu_*_test.cc`.
# This ensures they will be run by the full test make target, and thus it would
# not so happen accidentally that some of the docu-mented code does not compile and/or pass tests.
#
# 2) Use header guards in those `docu_*_test.cc` files and `#include` them from the actual `test.cc`
# for that Bricks module.
# That would ensure that those `docu_*_test.cc` tests are run both by `make` from within that directory,
# and by the top-level `make` that runs all tests at once and generates the coverage report.
#
# 3) Use the two spaces wisely.
# If something should be in the docu, it should be indented.
# If it should not be, it should not be indented.
# The `docu_*.*` files are excluded from `make indent`.

set -u -e

for fn in $(for i in $(find . -type f -iname "docu_*.*" | grep -v ".noshit" | grep -v "zzz_full_test"); do
echo -e "$(basename "$i")\t$i";
done | sort | cut -f2) ; do
echo $fn >/dev/stderr
case $fn in
*.cc)
echo '```cpp'
(grep '^ ' $fn || echo " // No documentation data in '$fn'.") | sed "s/^ //g"
echo '```'
;;
*.md)
cat $fn
;;
*)
echo "Unrecognized extension for file '$fn'."
exit 1
;;
esac
done
34 changes: 18 additions & 16 deletions KnowSheet/scripts/github-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,39 @@
set -u -e

# Command-line parameters.
GITHUB_REPO=${1:-Bricks}
GITHUB_USER=${2:-KnowSheet}
GITHUB_BRANCH=${3:-master}
GITHUB_REPO="${1:-Bricks}"
GITHUB_USER="${2:-KnowSheet}"
GITHUB_BRANCH="${3:-master}"

GITHUB_REPO_DASH_BRANCH="${GITHUB_REPO}-${GITHUB_BRANCH}"

# The URL to fetch a .tar.gz from.
URL=https://github.com/$GITHUB_USER/$GITHUB_REPO/archive/$GITHUB_BRANCH.tar.gz
URL="https://github.com/${GITHUB_USER}/${GITHUB_REPO}/archive/${GITHUB_BRANCH}.tar.gz"

# A temporary directory, expected to be .gitignore-d.
TMPDIR=.noshit
TMP_DIR_NAME=".noshit"

(
mkdir -p $TMPDIR
cd $TMPDIR
rm -rf $GITHUB_REPO $GITHUB_REPO-$GITHUB_BRANCH
echo -n "github.com/$GITHUB_USER/$GITHUB_REPO@$GITHUB_BRANCH: Fetch... "
curl -s -L $URL | tar xfz - || (echo "Failed, please check whether $URL can be fetched."; exit 1)
mv $GITHUB_REPO-$GITHUB_BRANCH $GITHUB_REPO
(
mkdir -p "$TMP_DIR_NAME"
cd "$TMP_DIR_NAME"
rm -rf "$GITHUB_REPO" "$GITHUB_REPO_DASH_BRANCH"
echo -n "github.com/${GITHUB_USER}/${GITHUB_REPO}@${GITHUB_BRANCH}: Fetch... "
curl -s -L "$URL" | tar xfz - || (echo "Failed, please check whether $URL can be fetched."; exit 1)
mv "$GITHUB_REPO_DASH_BRANCH" "$GITHUB_REPO"
echo -ne "\b\b\b\b\b\b\b\b\b"
)

if [ -d $GITHUB_REPO ] ; then
if diff -r $GITHUB_REPO $TMPDIR/$GITHUB_REPO ; then
if [ -d "$GITHUB_REPO" ] ; then
if diff -r "$GITHUB_REPO" "$TMP_DIR_NAME/$GITHUB_REPO" ; then
echo "Up to date."
else
echo "Conflict, please fix or reinstall."
echo "For a quick workaround, try renaming the current revision under another name:"
echo "mv $GITHUB_REPO $TMPDIR/$GITHUB_REPO-$(date +%Y%m%d-%H%M%S)"
echo "mv \"$GITHUB_REPO\" \"$TMP_DIR_NAME/${GITHUB_REPO}-$(date +%Y%m%d-%H%M%S)\""
echo "and then re-run the same command."
exit 1
fi
else
mv $TMPDIR/$GITHUB_REPO .
mv "$TMP_DIR_NAME/$GITHUB_REPO" .
echo "Installed."
fi
5 changes: 4 additions & 1 deletion KnowSheet/scripts/indent.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@
# Indents all *.cc and *.h files in the current directory and below
# according to .clang-format in this directory or above.

(find . -name "*.cc" ; find . -name "*.h") | grep -v "/.noshit/" | grep -v "/3party/" | xargs clang-format-3.5 -i
(find . -name "*.cc" ; find . -name "*.h") \
| grep -v "/.noshit/" | grep -v "/3party/" \
| grep -v "/docu_" \
| xargs clang-format-3.5 -i
Loading

0 comments on commit 7a69a48

Please sign in to comment.