2018-12-31 10:11:47 +08:00
|
|
|
#!/bin/bash
|
|
|
|
########################################################################
|
|
|
|
# Generates an "amalgamation build" for roaring. Inspired by similar
|
|
|
|
# script used by whefs.
|
|
|
|
########################################################################
|
|
|
|
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
|
|
|
|
|
|
|
|
echo "We are about to amalgamate all simdjson files into one source file. "
|
|
|
|
echo "See https://www.sqlite.org/amalgamation.html and https://en.wikipedia.org/wiki/Single_Compilation_Unit for rationale. "
|
|
|
|
|
|
|
|
AMAL_H="simdjson.h"
|
|
|
|
AMAL_C="simdjson.cpp"
|
|
|
|
|
2020-02-04 01:51:24 +08:00
|
|
|
SRCPATH="$SCRIPTPATH/src"
|
|
|
|
INCLUDEPATH="$SCRIPTPATH/include"
|
|
|
|
|
2019-12-17 08:09:18 +08:00
|
|
|
# this list excludes the "src/generic headers"
|
2018-12-31 10:50:10 +08:00
|
|
|
ALLCFILES="
|
2020-03-03 07:19:20 +08:00
|
|
|
simdjson.cpp
|
2018-12-31 10:50:10 +08:00
|
|
|
"
|
2018-12-31 10:11:47 +08:00
|
|
|
|
|
|
|
# order matters
|
|
|
|
ALLCHEADERS="
|
2020-03-03 06:23:19 +08:00
|
|
|
simdjson.h
|
2018-12-31 10:11:47 +08:00
|
|
|
"
|
|
|
|
|
2020-02-04 01:51:24 +08:00
|
|
|
found_includes=()
|
|
|
|
|
|
|
|
for file in ${ALLCFILES}; do
|
|
|
|
test -e "$SRCPATH/$file" && continue
|
|
|
|
echo "FATAL: source file [$SRCPATH/$file] not found."
|
2018-12-31 10:11:47 +08:00
|
|
|
exit 127
|
|
|
|
done
|
|
|
|
|
2020-02-04 01:51:24 +08:00
|
|
|
for file in ${ALLCHEADERS}; do
|
|
|
|
test -e "$INCLUDEPATH/$file" && continue
|
|
|
|
echo "FATAL: source file [$INCLUDEPATH/$file] not found."
|
|
|
|
exit 127
|
|
|
|
done
|
|
|
|
|
|
|
|
function doinclude()
|
|
|
|
{
|
|
|
|
file=$1
|
|
|
|
line="${@:2}"
|
|
|
|
if [ -f $INCLUDEPATH/$file ]; then
|
|
|
|
if [[ ! " ${found_includes[@]} " =~ " ${file} " ]]; then
|
|
|
|
found_includes+=("$file")
|
|
|
|
dofile $INCLUDEPATH/$file
|
|
|
|
fi;
|
|
|
|
elif [ -f $SRCPATH/$file ]; then
|
|
|
|
# generic includes are included multiple times
|
|
|
|
if [[ "${file}" == *'generic/'*'.h' ]]; then
|
|
|
|
dofile $SRCPATH/$file
|
|
|
|
elif [[ ! " ${found_includes[@]} " =~ " ${file} " ]]; then
|
|
|
|
found_includes+=("$file")
|
|
|
|
dofile $SRCPATH/$file
|
|
|
|
else
|
|
|
|
echo "/* $file already included: $line */"
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
# If we don't recognize it, just emit the #include
|
|
|
|
echo "$line"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2018-12-31 10:11:47 +08:00
|
|
|
function dofile()
|
|
|
|
{
|
2019-08-05 03:58:35 +08:00
|
|
|
# Last lines are always ignored. Files should end by an empty lines.
|
2019-03-03 06:18:45 +08:00
|
|
|
RELFILE=${1#"$SCRIPTPATH/"}
|
|
|
|
echo "/* begin file $RELFILE */"
|
2018-12-31 10:11:47 +08:00
|
|
|
# echo "#line 8 \"$1\"" ## redefining the line/file is not nearly as useful as it sounds for debugging. It breaks IDEs.
|
2019-12-17 08:09:18 +08:00
|
|
|
while IFS= read -r line || [ -n "$line" ];
|
2019-08-05 03:58:35 +08:00
|
|
|
do
|
2019-08-21 19:59:49 +08:00
|
|
|
if [[ "${line}" == '#include "'*'"'* ]]; then
|
|
|
|
file=$(echo $line| cut -d'"' -f 2)
|
|
|
|
|
|
|
|
if [[ "${file}" == '../'* ]]; then
|
2020-02-04 01:51:24 +08:00
|
|
|
file=$(echo $file| cut -d'/' -f 2-)
|
2019-08-21 19:59:49 +08:00
|
|
|
fi;
|
|
|
|
|
2020-02-04 01:51:24 +08:00
|
|
|
# we explicitly include simdjson headers, one time each (unless they are generic, in which case multiple times is fine)
|
|
|
|
doinclude $file $line
|
|
|
|
else
|
|
|
|
# Otherwise we simply copy the line
|
|
|
|
echo "$line"
|
|
|
|
fi
|
2019-08-05 03:58:35 +08:00
|
|
|
done < "$1"
|
2019-03-03 06:18:45 +08:00
|
|
|
echo "/* end file $RELFILE */"
|
2018-12-31 10:11:47 +08:00
|
|
|
}
|
|
|
|
timestamp=$(date)
|
|
|
|
echo "Creating ${AMAL_H}..."
|
|
|
|
echo "/* auto-generated on ${timestamp}. Do not edit! */" > "${AMAL_H}"
|
|
|
|
{
|
|
|
|
for h in ${ALLCHEADERS}; do
|
2020-02-04 01:51:24 +08:00
|
|
|
doinclude $h "ERROR $h not found"
|
2018-12-31 10:11:47 +08:00
|
|
|
done
|
|
|
|
} >> "${AMAL_H}"
|
|
|
|
|
|
|
|
|
|
|
|
echo "Creating ${AMAL_C}..."
|
|
|
|
echo "/* auto-generated on ${timestamp}. Do not edit! */" > "${AMAL_C}"
|
|
|
|
{
|
|
|
|
echo "#include \"${AMAL_H}\""
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
echo "/* used for http://dmalloc.com/ Dmalloc - Debug Malloc Library */"
|
|
|
|
echo "#ifdef DMALLOC"
|
|
|
|
echo "#include \"dmalloc.h\""
|
|
|
|
echo "#endif"
|
|
|
|
echo ""
|
|
|
|
|
2020-02-04 01:51:24 +08:00
|
|
|
for file in ${ALLCFILES}; do
|
|
|
|
dofile "$SRCPATH/$file"
|
2018-12-31 10:11:47 +08:00
|
|
|
done
|
|
|
|
} >> "${AMAL_C}"
|
|
|
|
|
|
|
|
|
|
|
|
DEMOCPP="amalgamation_demo.cpp"
|
|
|
|
echo "Creating ${DEMOCPP}..."
|
|
|
|
echo "/* auto-generated on ${timestamp}. Do not edit! */" > "${DEMOCPP}"
|
|
|
|
cat <<< '
|
|
|
|
#include <iostream>
|
|
|
|
#include "simdjson.h"
|
|
|
|
#include "simdjson.cpp"
|
|
|
|
int main(int argc, char *argv[]) {
|
2019-12-11 21:13:29 +08:00
|
|
|
if(argc < 2) {
|
|
|
|
std::cerr << "Please specify at least one file name. " << std::endl;
|
2019-07-31 06:10:48 +08:00
|
|
|
}
|
2019-02-23 04:42:44 +08:00
|
|
|
const char * filename = argv[1];
|
2020-03-29 02:43:41 +08:00
|
|
|
simdjson::dom::parser parser;
|
2020-03-07 10:14:34 +08:00
|
|
|
auto [doc, error] = parser.load(filename); // do the parsing
|
2020-02-14 05:30:12 +08:00
|
|
|
if (error) {
|
2020-03-06 03:05:37 +08:00
|
|
|
std::cout << "parse failed" << std::endl;
|
2020-02-25 06:13:10 +08:00
|
|
|
std::cout << "error code: " << error << std::endl;
|
2020-03-07 04:14:23 +08:00
|
|
|
std::cout << error << std::endl;
|
2018-12-31 10:11:47 +08:00
|
|
|
} else {
|
2020-03-06 03:05:37 +08:00
|
|
|
std::cout << "parse valid" << std::endl;
|
2018-12-31 10:11:47 +08:00
|
|
|
}
|
2019-12-11 21:13:29 +08:00
|
|
|
if(argc == 2) {
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
2019-11-09 06:39:45 +08:00
|
|
|
|
2020-03-06 03:05:37 +08:00
|
|
|
// parse_many
|
2019-11-09 06:39:45 +08:00
|
|
|
const char * filename2 = argv[2];
|
2020-03-07 10:14:34 +08:00
|
|
|
for (auto result : parser.load_many(filename2)) {
|
2020-03-21 04:14:47 +08:00
|
|
|
error = result.error();
|
2019-12-11 21:13:29 +08:00
|
|
|
}
|
2020-03-06 03:05:37 +08:00
|
|
|
if (error) {
|
|
|
|
std::cout << "parse_many failed" << std::endl;
|
|
|
|
std::cout << "error code: " << error << std::endl;
|
2020-03-07 04:14:23 +08:00
|
|
|
std::cout << error << std::endl;
|
2019-11-09 06:39:45 +08:00
|
|
|
} else {
|
2020-03-06 03:05:37 +08:00
|
|
|
std::cout << "parse_many valid" << std::endl;
|
2019-11-09 06:39:45 +08:00
|
|
|
}
|
2018-12-31 10:11:47 +08:00
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
|
|
|
' >> "${DEMOCPP}"
|
|
|
|
|
|
|
|
echo "Done with all files generation. "
|
|
|
|
|
|
|
|
echo "Files have been written to directory: $PWD "
|
|
|
|
ls -la ${AMAL_C} ${AMAL_H} ${DEMOCPP}
|
|
|
|
|
|
|
|
echo "Giving final instructions:"
|
|
|
|
|
|
|
|
|
|
|
|
CPPBIN=${DEMOCPP%%.*}
|
|
|
|
|
|
|
|
echo "Try :"
|
2019-11-22 00:22:06 +08:00
|
|
|
echo "c++ -O3 -std=c++17 -pthread -o ${CPPBIN} ${DEMOCPP} && ./${CPPBIN} ../jsonexamples/twitter.json ../jsonexamples/amazon_cellphones.ndjson"
|
2018-12-31 10:50:10 +08:00
|
|
|
|
|
|
|
SINGLEHDR=$SCRIPTPATH/singleheader
|
|
|
|
echo "Copying files to $SCRIPTPATH/singleheader "
|
|
|
|
mkdir -p $SINGLEHDR
|
2019-11-22 00:22:06 +08:00
|
|
|
echo "c++ -O3 -std=c++17 -pthread -o ${CPPBIN} ${DEMOCPP} && ./${CPPBIN} ../jsonexamples/twitter.json ../jsonexamples/amazon_cellphones.ndjson" > $SINGLEHDR/README.md
|
2018-12-31 10:50:10 +08:00
|
|
|
cp ${AMAL_C} ${AMAL_H} ${DEMOCPP} $SINGLEHDR
|
|
|
|
ls $SINGLEHDR
|
2018-12-31 10:11:47 +08:00
|
|
|
|
2019-11-22 00:22:06 +08:00
|
|
|
cd $SINGLEHDR && c++ -O3 -std=c++17 -pthread -o ${CPPBIN} ${DEMOCPP} && ./${CPPBIN} ../jsonexamples/twitter.json ../jsonexamples/amazon_cellphones.ndjson
|
2019-02-23 04:42:44 +08:00
|
|
|
|
2018-12-31 10:11:47 +08:00
|
|
|
lowercase(){
|
|
|
|
echo "$1" | tr 'A-Z' 'a-z'
|
|
|
|
}
|
|
|
|
|
|
|
|
OS=`lowercase \`uname\``
|