summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/yatr.yaml100
-rw-r--r--.gitignore71
-rw-r--r--.travis.yml34
-rw-r--r--.yatr.yml85
-rw-r--r--LICENSE2
-rw-r--r--Makefile.am879
-rw-r--r--README.md6
-rw-r--r--blogc.spec.in120
-rwxr-xr-xbuild-aux/build-debian.sh153
-rwxr-xr-xbuild-aux/build-static-all.sh12
-rwxr-xr-xbuild-aux/build-static.sh7
-rwxr-xr-xbuild-aux/build-windows.sh16
-rwxr-xr-xbuild-aux/check-make-embedded.sh5
-rwxr-xr-xbuild-aux/clang-analyzer.sh28
-rwxr-xr-xbuild-aux/travis-build.sh21
-rwxr-xr-xbuild-aux/travis-deploy.sh67
-rwxr-xr-xbuild-aux/valgrind.sh16
-rw-r--r--configure.ac168
-rw-r--r--debian/blogc-git-receiver.install2
-rw-r--r--debian/blogc-make.install3
-rw-r--r--debian/blogc-runserver.install2
-rw-r--r--debian/blogc.install6
-rw-r--r--debian/changelog5
-rw-r--r--debian/control41
-rw-r--r--debian/copyright61
-rwxr-xr-xdebian/rules16
-rw-r--r--debian/source/format1
-rw-r--r--m4/ax_pthread.m4485
-rw-r--r--maint/README.md93
-rwxr-xr-xmaint/download_release.py49
-rw-r--r--man/blogc-git-receiver.1.ronn112
-rw-r--r--man/blogc-make.1.ronn219
-rw-r--r--man/blogc-pagination.7.ronn22
-rw-r--r--man/blogc-runserver.1.ronn8
-rw-r--r--man/blogc-source.7.ronn13
-rw-r--r--man/blogc-template.7.ronn128
-rw-r--r--man/blogc-toctree.7.ronn87
-rw-r--r--man/blogc.1.ronn57
-rw-r--r--man/blogcfile.5.ronn207
-rw-r--r--man/index.txt16
-rw-r--r--src/blogc-git-receiver.c501
-rw-r--r--src/blogc-git-receiver/main.c44
-rw-r--r--src/blogc-git-receiver/post-receive.c91
-rw-r--r--src/blogc-git-receiver/post-receive.h14
-rw-r--r--src/blogc-git-receiver/pre-receive-parser.c84
-rw-r--r--src/blogc-git-receiver/pre-receive-parser.h17
-rw-r--r--src/blogc-git-receiver/pre-receive.c318
-rw-r--r--src/blogc-git-receiver/pre-receive.h14
-rw-r--r--src/blogc-git-receiver/settings.c110
-rw-r--r--src/blogc-git-receiver/settings.h19
-rw-r--r--src/blogc-git-receiver/shell-command-parser.c101
-rw-r--r--src/blogc-git-receiver/shell-command-parser.h14
-rw-r--r--src/blogc-git-receiver/shell.c190
-rw-r--r--src/blogc-git-receiver/shell.h15
-rw-r--r--src/blogc-make/atom.c137
-rw-r--r--src/blogc-make/atom.h19
-rw-r--r--src/blogc-make/ctx.c409
-rw-r--r--src/blogc-make/ctx.h84
-rw-r--r--src/blogc-make/exec-native.c192
-rw-r--r--src/blogc-make/exec-native.h20
-rw-r--r--src/blogc-make/exec.c498
-rw-r--r--src/blogc-make/exec.h35
-rw-r--r--src/blogc-make/httpd.c121
-rw-r--r--src/blogc-make/httpd.h19
-rw-r--r--src/blogc-make/main.c134
-rw-r--r--src/blogc-make/reloader.c116
-rw-r--r--src/blogc-make/reloader.h20
-rw-r--r--src/blogc-make/rules.c1078
-rw-r--r--src/blogc-make/rules.h36
-rw-r--r--src/blogc-make/settings.c203
-rw-r--r--src/blogc-make/settings.h29
-rw-r--r--src/blogc-make/utils.c128
-rw-r--r--src/blogc-make/utils.h20
-rw-r--r--src/blogc-runserver.c386
-rw-r--r--src/blogc-runserver/httpd-utils.c105
-rw-r--r--src/blogc-runserver/httpd-utils.h19
-rw-r--r--src/blogc-runserver/httpd.c413
-rw-r--r--src/blogc-runserver/httpd.h15
-rw-r--r--src/blogc-runserver/main.c153
-rw-r--r--src/blogc-runserver/mime.c164
-rw-r--r--src/blogc-runserver/mime.h15
-rw-r--r--src/blogc.c297
-rw-r--r--src/blogc/content-parser.h25
-rw-r--r--src/blogc/debug.c80
-rw-r--r--src/blogc/filelist-parser.c67
-rw-r--r--src/blogc/filelist-parser.h16
-rw-r--r--src/blogc/funcvars.c62
-rw-r--r--src/blogc/funcvars.h19
-rw-r--r--src/blogc/loader.c318
-rw-r--r--src/blogc/loader.h22
-rw-r--r--src/blogc/main.c393
-rw-r--r--src/blogc/renderer.h24
-rw-r--r--src/blogc/rusage.c86
-rw-r--r--src/blogc/rusage.h36
-rw-r--r--src/blogc/sysinfo.c153
-rw-r--r--src/blogc/sysinfo.h38
-rw-r--r--src/blogc/template-parser.h58
-rw-r--r--src/blogc/toctree.c103
-rw-r--r--src/blogc/toctree.h26
-rw-r--r--src/common/compat.c39
-rw-r--r--src/common/compat.h14
-rw-r--r--src/common/config-parser.c442
-rw-r--r--src/common/config-parser.h31
-rw-r--r--src/common/error.h47
-rw-r--r--src/common/file.c66
-rw-r--r--src/common/file.h20
-rw-r--r--src/common/sort.c44
-rw-r--r--src/common/sort.h18
-rw-r--r--src/common/stdin.c28
-rw-r--r--src/common/stdin.h16
-rw-r--r--src/common/utils.h110
-rw-r--r--src/content-parser.c (renamed from src/blogc/content-parser.c)749
-rw-r--r--src/content-parser.h174
-rw-r--r--src/datetime-parser.c (renamed from src/blogc/datetime-parser.c)68
-rw-r--r--src/datetime-parser.h (renamed from src/blogc/datetime-parser.h)6
-rw-r--r--src/debug.c80
-rw-r--r--src/debug.h (renamed from src/blogc/debug.h)6
-rw-r--r--src/error.c (renamed from src/common/error.c)75
-rw-r--r--src/error.h34
-rw-r--r--src/file.c81
-rw-r--r--src/file.h21
-rw-r--r--src/loader.c212
-rw-r--r--src/loader.h21
-rw-r--r--src/renderer.c (renamed from src/blogc/renderer.c)309
-rw-r--r--src/renderer.h24
-rw-r--r--src/source-parser.c (renamed from src/blogc/source-parser.c)106
-rw-r--r--src/source-parser.h (renamed from src/blogc/source-parser.h)10
-rw-r--r--src/template-parser.c (renamed from src/blogc/template-parser.c)249
-rw-r--r--src/template-parser.h53
-rw-r--r--src/utf8.c (renamed from src/common/utf8.c)26
-rw-r--r--src/utf8.h (renamed from src/common/utf8.h)8
-rw-r--r--src/utils.c (renamed from src/common/utils.c)300
-rw-r--r--src/utils.h102
-rwxr-xr-xtests/blogc-git-receiver/check_post_receive.sh.in116
-rwxr-xr-xtests/blogc-git-receiver/check_pre_receive.sh.in304
-rw-r--r--tests/blogc-git-receiver/check_pre_receive_parser.c134
-rw-r--r--tests/blogc-git-receiver/check_settings.c91
-rwxr-xr-xtests/blogc-git-receiver/check_shell.sh.in95
-rw-r--r--tests/blogc-git-receiver/check_shell_command_parser.c215
-rw-r--r--tests/blogc-make/check_atom.c552
-rwxr-xr-xtests/blogc-make/check_blogc_make.sh.in2463
-rw-r--r--tests/blogc-make/check_exec.c318
-rw-r--r--tests/blogc-make/check_rules.c104
-rw-r--r--tests/blogc-make/check_settings.c394
-rw-r--r--tests/blogc-make/check_utils.c468
-rw-r--r--tests/blogc-runserver/check_httpd_utils.c132
-rw-r--r--tests/blogc-runserver/check_mime.c92
-rwxr-xr-xtests/blogc/check_blogc.sh.in638
-rw-r--r--tests/blogc/check_filelist_parser.c131
-rw-r--r--tests/blogc/check_funcvars.c80
-rw-r--r--tests/blogc/check_loader.c1050
-rw-r--r--tests/blogc/check_renderer.c1435
-rw-r--r--tests/blogc/check_rusage.c127
-rw-r--r--tests/blogc/check_source_parser.c761
-rw-r--r--tests/blogc/check_sysinfo.c261
-rw-r--r--tests/blogc/check_sysinfo2.c49
-rw-r--r--tests/blogc/check_template_parser.c1331
-rw-r--r--tests/blogc/check_toctree.c234
-rw-r--r--tests/check_content_parser.c (renamed from tests/blogc/check_content_parser.c)938
-rw-r--r--tests/check_datetime_parser.c (renamed from tests/blogc/check_datetime_parser.c)210
-rw-r--r--tests/check_error.c (renamed from tests/common/check_error.c)57
-rw-r--r--tests/check_loader.c771
-rw-r--r--tests/check_renderer.c1158
-rw-r--r--tests/check_source_parser.c542
-rw-r--r--tests/check_template_parser.c1184
-rw-r--r--tests/check_utf8.c101
-rw-r--r--tests/check_utils.c (renamed from tests/common/check_utils.c)763
-rw-r--r--tests/common/check_config_parser.c1037
-rw-r--r--tests/common/check_sort.c148
-rw-r--r--tests/common/check_stdin.c58
-rw-r--r--tests/common/check_utf8.c105
171 files changed, 7669 insertions, 25913 deletions
diff --git a/.github/workflows/yatr.yaml b/.github/workflows/yatr.yaml
deleted file mode 100644
index 897c41e..0000000
--- a/.github/workflows/yatr.yaml
+++ /dev/null
@@ -1,100 +0,0 @@
-name: yatr
-on:
- - push
-
-jobs:
- yatr:
- runs-on: "${{ matrix.image }}"
-
- strategy:
- fail-fast: false
- matrix:
- target:
- - distcheck
- - valgrind
- - check-make-embedded
- compiler:
- - gcc
- - clang
- image:
- - ubuntu-20.04
- include:
- - target: distcheck
- compiler: clang
- image: macos-10.15
- - target: clang-analyzer
- compiler: clang
- image: ubuntu-20.04
- - target: dist-srpm
- compiler: gcc
- image: ubuntu-20.04
- - target: deb-bullseye-amd64
- compiler: gcc
- image: ubuntu-22.04
- - target: deb-bookworm-amd64
- compiler: gcc
- image: ubuntu-22.04
- - target: deb-sid-amd64
- compiler: gcc
- image: ubuntu-22.04
- - target: deb-focal-amd64
- compiler: gcc
- image: ubuntu-22.04
- - target: deb-jammy-amd64
- compiler: gcc
- image: ubuntu-22.04
- - target: deb-kinetic-amd64
- compiler: gcc
- image: ubuntu-22.04
- - target: static
- compiler: gcc
- image: ubuntu-20.04
- - target: static-all
- compiler: gcc
- image: ubuntu-20.04
- - target: win32
- compiler: gcc
- image: ubuntu-20.04
- - target: win64
- compiler: gcc
- image: ubuntu-20.04
-
- steps:
- - name: Check out code
- uses: actions/checkout@v2
-
- - name: Install dependencies
- run: |
- if [[ "x${{ matrix.image }}" = xubuntu-* ]]; then
- sudo gem install ronn
- sudo apt-get update -y
- if [[ "x${{ matrix.target }}" = *check* ]] || [[ "x${{ matrix.target }}" = xvalgrind ]] || [[ "x${{ matrix.target }}" = xdeb-* ]]; then
- sudo apt-get install -y libcmocka-dev
- fi
- if [[ "x${{ matrix.target }}" = xvalgrind ]]; then
- sudo apt-get install -y valgrind
- fi
- if [[ "x${{ matrix.target }}" = xclang-analyzer ]]; then
- sudo apt-get install -y clang-tools
- fi
- if [[ "x${{ matrix.target }}" = xwin32 ]]; then
- sudo apt-get install -y gcc-mingw-w64-i686
- fi
- if [[ "x${{ matrix.target }}" = xwin64 ]]; then
- sudo apt-get install -y gcc-mingw-w64-x86-64
- fi
- if [[ "x${{ matrix.target }}" = xdeb-* ]]; then
- sudo apt-get install -y cowbuilder debhelper pbuilder reprepro
- fi
- elif [[ "x${{ matrix.image }}" = xmacos-* ]]; then
- gem install ronn
- brew install automake coreutils cmocka pkg-config
- fi
-
- - name: Run yatr
- env:
- CC: "${{ matrix.compiler }}"
- TARGET: "${{ matrix.target }}"
- DISTFILES_URL: "${{ secrets.DISTFILES_URL }}"
- DISABLE_PUBLISHER: "${{ matrix.compiler != 'gcc' && matrix.target != 'clang-analyzer' }}"
- run: curl -sSf https://yatr.rgm.io/run.sh | bash
diff --git a/.gitignore b/.gitignore
index 261a0e9..52794d8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,81 +26,39 @@ Makefile.in
*.lo
/aclocal.m4
/configure
-/configure~
/config.*
/autom4te.cache
/libtool
/stamp-h1
.dirstamp
/build-aux/*
-!/build-aux/build-*.sh
-!/build-aux/check-make-embedded.sh
-!/build-aux/clang-analyzer.sh
!/build-aux/git-version-gen
-!/build-aux/valgrind.sh
-
-# debian
-debian/.debhelper
-debian/autoreconf.*
-debian/*.log
-debian/*.substvars
-debian/debhelper-build-stamp
-debian/files
-debian/blogc/
-debian/blogc-git-receiver/
-debian/blogc-make/
-debian/blogc-runserver/
-debian/tmp/
+!/build-aux/travis-build.sh
+!/build-aux/travis-deploy.sh
# installed .m4 files
/m4/*.m4
-!/m4/ax_pthread.m4
!/m4/pkg.m4
# man pages
-/blogc*.[157]
+/blogc*.[17]
blogc*.html
# binaries
/blogc
/blogc-git-receiver
-/blogc-make
/blogc-runserver
# tests
-/tests/blogc/check_blogc.sh
-/tests/blogc/check_content_parser
-/tests/blogc/check_datetime_parser
-/tests/blogc/check_filelist_parser
-/tests/blogc/check_funcvars
-/tests/blogc/check_loader
-/tests/blogc/check_renderer
-/tests/blogc/check_rusage
-/tests/blogc/check_source_parser
-/tests/blogc/check_sysinfo
-/tests/blogc/check_sysinfo2
-/tests/blogc/check_template_parser
-/tests/blogc/check_toctree
-/tests/blogc-git-receiver/check_pre_receive_parser
-/tests/blogc-git-receiver/check_pre_receive.sh
-/tests/blogc-git-receiver/check_post_receive.sh
-/tests/blogc-git-receiver/check_settings
-/tests/blogc-git-receiver/check_shell_command_parser
-/tests/blogc-git-receiver/check_shell.sh
-/tests/blogc-make/check_atom
-/tests/blogc-make/check_blogc_make.sh
-/tests/blogc-make/check_exec
-/tests/blogc-make/check_rules
-/tests/blogc-make/check_settings
-/tests/blogc-make/check_utils
-/tests/blogc-runserver/check_httpd_utils
-/tests/blogc-runserver/check_mime
-/tests/common/check_config_parser
-/tests/common/check_error
-/tests/common/check_sort
-/tests/common/check_stdin
-/tests/common/check_utf8
-/tests/common/check_utils
+/tests/check_content_parser
+/tests/check_datetime_parser
+/tests/check_error
+/tests/check_loader
+/tests/check_renderer
+/tests/check_source_parser
+/tests/check_template_parser
+/tests/check_utf8
+/tests/check_utils
# tarballs
blogc-*.tar.*
@@ -117,8 +75,3 @@ blogc-*.rpm
*.plist
/build/
-/root/
-
-/maint/releases/
-
-.gdb_history
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..15c4906
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,34 @@
+dist: trusty
+sudo: required
+language: c
+
+addons:
+ apt:
+ packages:
+ - libcmocka-dev
+ - libmagic-dev
+ - libevent-dev
+ - rpm
+ - valgrind
+
+compiler:
+ - clang
+ - gcc
+
+env:
+ - TARGET=valgrind
+ - TARGET=distcheck
+ - TARGET=dist-srpm
+
+matrix:
+ exclude:
+ - compiler: clang
+ env: TARGET=dist-srpm
+
+install: gem install ronn
+
+before_script: ./autogen.sh
+
+script:
+ - ./build-aux/travis-build.sh
+ - ./build-aux/travis-deploy.sh
diff --git a/.yatr.yml b/.yatr.yml
deleted file mode 100644
index 244b9fa..0000000
--- a/.yatr.yml
+++ /dev/null
@@ -1,85 +0,0 @@
-default_configure_args:
- - "CFLAGS=-Wall -g -O0"
- - --disable-silent-rules
- - --disable-valgrind
- - --enable-ronn
- - --enable-tests
- - --enable-git-receiver
- - --enable-make
- - --enable-runserver
-
-targets:
- dist-srpm:
- configure_args:
- - --disable-tests
- archive_filter: "*.src.rpm"
- clang-analyzer:
- configure_args:
- - --enable-silent-rules
- - --disable-tests
- task_script: build-aux/clang-analyzer.sh
- archive_extract_filter: "*.tar.xz"
- publish_on_failure: true
- valgrind:
- configure_args:
- - --enable-valgrind
- check-make-embedded:
- configure_args:
- - --disable-git-receiver
- - --disable-runserver
- - --enable-make-embedded
- task_script: build-aux/check-make-embedded.sh
- static:
- configure_args:
- - "CFLAGS=-Wall -g -O2"
- - --disable-tests
- - --disable-git-receiver
- - --disable-runserver
- - --enable-make-embedded
- task_script: build-aux/build-static.sh
- static-all:
- configure_args:
- - "CFLAGS=-Wall -g -O2"
- - --disable-tests
- - --prefix=/
- task_script: build-aux/build-static-all.sh
- win32:
- configure_args:
- - CC=
- - "CFLAGS=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4"
- - --host=i686-w64-mingw32
- - --target=i686-w64-mingw32
- - --disable-tests
- - --disable-git-receiver
- - --disable-make
- - --disable-runserver
- task_script: build-aux/build-windows.sh
- win64:
- configure_args:
- - CC=
- - "CFLAGS=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4"
- - --host=x86_64-w64-mingw32
- - --target=x86_64-w64-mingw32
- - --disable-tests
- - --disable-git-receiver
- - --disable-make
- - --disable-runserver
- task_script: build-aux/build-windows.sh
- deb-bullseye-amd64:
- task_script: build-aux/build-debian.sh
- archive_extract_filter: "blogc-deb-*.tar.xz"
- deb-bookworm-amd64:
- task_script: build-aux/build-debian.sh
- archive_extract_filter: "blogc-deb-*.tar.xz"
- deb-sid-amd64:
- task_script: build-aux/build-debian.sh
- archive_extract_filter: "blogc-deb-*.tar.xz"
- deb-focal-amd64:
- task_script: build-aux/build-debian.sh
- archive_extract_filter: "blogc-deb-*.tar.xz"
- deb-jammy-amd64:
- task_script: build-aux/build-debian.sh
- archive_extract_filter: "blogc-deb-*.tar.xz"
- deb-kinetic-amd64:
- task_script: build-aux/build-debian.sh
- archive_extract_filter: "blogc-deb-*.tar.xz"
diff --git a/LICENSE b/LICENSE
index 705f3e1..0f0ff43 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2014-2020, Rafael G. Martins
+Copyright (c) 2014-2016, Rafael G. Martins
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/Makefile.am b/Makefile.am
index 571cb41..2582881 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3,14 +3,11 @@
ACLOCAL_AMFLAGS = -I m4
AM_DISTCHECK_CONFIGURE_FLAGS = \
- CFLAGS="-Wall -g -O0" \
- --enable-git-receiver \
- --enable-make \
- --enable-ronn \
- --enable-runserver \
--enable-tests \
- --disable-silent-rules \
+ --disable-ronn \
--disable-valgrind \
+ --enable-git-receiver \
+ --enable-runserver \
$(NULL)
@@ -18,10 +15,8 @@ AM_DISTCHECK_CONFIGURE_FLAGS = \
EXTRA_DIST = \
build-aux/git-version-gen \
- build-aux/valgrind.sh \
$(top_srcdir)/.version \
autogen.sh \
- blogc.spec \
LICENSE \
README.md \
$(NULL)
@@ -37,49 +32,22 @@ BUILT_SOURCES = \
$(NULL)
noinst_HEADERS = \
- src/blogc/content-parser.h \
- src/blogc/datetime-parser.h \
- src/blogc/debug.h \
- src/blogc/filelist-parser.h \
- src/blogc/funcvars.h \
- src/blogc/loader.h \
- src/blogc/renderer.h \
- src/blogc/rusage.h \
- src/blogc/sysinfo.h \
- src/blogc/source-parser.h \
- src/blogc/template-parser.h \
- src/blogc/toctree.h \
- src/blogc-git-receiver/post-receive.h \
- src/blogc-git-receiver/pre-receive.h \
- src/blogc-git-receiver/pre-receive-parser.h \
- src/blogc-git-receiver/settings.h \
- src/blogc-git-receiver/shell.h \
- src/blogc-git-receiver/shell-command-parser.h \
- src/blogc-make/atom.h \
- src/blogc-make/ctx.h \
- src/blogc-make/exec.h \
- src/blogc-make/exec-native.h \
- src/blogc-make/httpd.h \
- src/blogc-make/reloader.h \
- src/blogc-make/rules.h \
- src/blogc-make/settings.h \
- src/blogc-make/utils.h \
- src/blogc-runserver/httpd.h \
- src/blogc-runserver/httpd-utils.h \
- src/blogc-runserver/mime.h \
- src/common/compat.h \
- src/common/config-parser.h \
- src/common/error.h \
- src/common/file.h \
- src/common/sort.h \
- src/common/stdin.h \
- src/common/utf8.h \
- src/common/utils.h \
+ src/content-parser.h \
+ src/datetime-parser.h \
+ src/debug.h \
+ src/error.h \
+ src/file.h \
+ src/loader.h \
+ src/renderer.h \
+ src/source-parser.h \
+ src/template-parser.h \
+ src/utf8.h \
+ src/utils.h \
$(NULL)
noinst_LTLIBRARIES = \
libblogc.la \
- libblogc_common.la \
+ libblogc_utils.la \
$(NULL)
noinst_PROGRAMS = \
@@ -93,240 +61,120 @@ if BUILD_GIT_RECEIVER
bin_PROGRAMS += \
blogc-git-receiver \
$(NULL)
-
-noinst_LTLIBRARIES += \
- libblogc_git_receiver.la \
- $(NULL)
-endif
-
-if BUILD_MAKE
-bin_PROGRAMS += \
- blogc-make \
- $(NULL)
-
-noinst_LTLIBRARIES += \
- libblogc_make.la \
- $(NULL)
endif
if BUILD_RUNSERVER
bin_PROGRAMS += \
blogc-runserver \
$(NULL)
-
-noinst_LTLIBRARIES += \
- libblogc_runserver.la \
- $(NULL)
endif
check_PROGRAMS = \
$(NULL)
-check_SCRIPTS = \
- $(NULL)
-
libblogc_la_SOURCES = \
- src/blogc/content-parser.c \
- src/blogc/datetime-parser.c \
- src/blogc/debug.c \
- src/blogc/filelist-parser.c \
- src/blogc/funcvars.c \
- src/blogc/loader.c \
- src/blogc/renderer.c \
- src/blogc/rusage.c \
- src/blogc/sysinfo.c \
- src/blogc/source-parser.c \
- src/blogc/template-parser.c \
- src/blogc/toctree.c \
+ src/content-parser.c \
+ src/datetime-parser.c \
+ src/error.c \
+ src/file.c \
+ src/loader.c \
+ src/renderer.c \
+ src/source-parser.c \
+ src/template-parser.c \
$(NULL)
libblogc_la_CFLAGS = \
$(AM_CFLAGS) \
+ -I$(top_srcdir)/src \
$(NULL)
libblogc_la_LIBADD = \
$(LIBM) \
- libblogc_common.la \
$(NULL)
-libblogc_common_la_SOURCES = \
- src/common/compat.c \
- src/common/config-parser.c \
- src/common/error.c \
- src/common/file.c \
- src/common/sort.c \
- src/common/stdin.c \
- src/common/utf8.c \
- src/common/utils.c \
+libblogc_utils_la_SOURCES = \
+ src/utf8.c \
+ src/utils.c \
$(NULL)
-libblogc_common_la_CFLAGS = \
+libblogc_utils_la_CFLAGS = \
$(AM_CFLAGS) \
+ -I$(top_srcdir)/src \
$(NULL)
blogc_SOURCES = \
- src/blogc/main.c \
+ src/blogc.c \
+ src/debug.c \
$(NULL)
blogc_CFLAGS = \
$(AM_CFLAGS) \
+ -I$(top_srcdir)/src \
$(NULL)
blogc_LDADD = \
libblogc.la \
- libblogc_common.la \
+ libblogc_utils.la \
$(NULL)
-if BUILD_MAKE_EMBEDDED
-blogc_SOURCES += \
- src/blogc-make/main.c \
- $(NULL)
-
-blogc_LDADD += \
- libblogc_make.la \
- $(NULL)
-endif
-
if BUILD_GIT_RECEIVER
blogc_git_receiver_SOURCES = \
- src/blogc-git-receiver/main.c \
+ src/blogc-git-receiver.c \
$(NULL)
blogc_git_receiver_CFLAGS = \
$(AM_CFLAGS) \
+ -I$(top_srcdir)/src \
$(NULL)
blogc_git_receiver_LDADD = \
- libblogc_git_receiver.la \
- libblogc_common.la \
- $(NULL)
-
-libblogc_git_receiver_la_SOURCES = \
- src/blogc-git-receiver/post-receive.c \
- src/blogc-git-receiver/pre-receive.c \
- src/blogc-git-receiver/pre-receive-parser.c \
- src/blogc-git-receiver/settings.c \
- src/blogc-git-receiver/shell.c \
- src/blogc-git-receiver/shell-command-parser.c \
- $(NULL)
-
-libblogc_git_receiver_la_CFLAGS = \
- $(AM_CFLAGS) \
- $(NULL)
-
-libblogc_git_receiver_la_LIBADD = \
- libblogc_common.la \
- $(NULL)
-endif
-
-
-if BUILD_MAKE
-blogc_make_SOURCES = \
- src/blogc-make/main.c \
- $(NULL)
-
-blogc_make_CFLAGS = \
- $(AM_CFLAGS) \
- $(PTHREAD_CFLAGS) \
- $(NULL)
-
-blogc_make_LDADD = \
- $(PTHREAD_LIBS) \
- libblogc_make.la \
- libblogc_common.la \
- $(NULL)
-endif
-
-if BUILD_MAKE_LIB
-libblogc_make_la_SOURCES = \
- src/blogc-make/atom.c \
- src/blogc-make/ctx.c \
- src/blogc-make/exec.c \
- src/blogc-make/exec-native.c \
- src/blogc-make/httpd.c \
- src/blogc-make/reloader.c \
- src/blogc-make/rules.c \
- src/blogc-make/settings.c \
- src/blogc-make/utils.c \
- $(NULL)
-
-libblogc_make_la_CFLAGS = \
- $(AM_CFLAGS) \
- $(PTHREAD_CFLAGS) \
- $(NULL)
-
-libblogc_make_la_LIBADD = \
- $(PTHREAD_LIBS) \
- libblogc_common.la \
+ libblogc_utils.la \
$(NULL)
endif
if BUILD_RUNSERVER
blogc_runserver_SOURCES = \
- src/blogc-runserver/main.c \
+ src/blogc-runserver.c \
$(NULL)
blogc_runserver_CFLAGS = \
$(AM_CFLAGS) \
- $(PTHREAD_CFLAGS) \
+ -I$(top_srcdir)/src \
+ $(LIBEVENT_CFLAGS) \
+ $(SQUAREBALL_CFLAGS) \
$(NULL)
blogc_runserver_LDADD = \
- $(PTHREAD_LIBS) \
- libblogc_runserver.la \
- libblogc_common.la \
- $(NULL)
-
-libblogc_runserver_la_SOURCES = \
- src/blogc-runserver/httpd.c \
- src/blogc-runserver/httpd-utils.c \
- src/blogc-runserver/mime.c \
- $(NULL)
-
-libblogc_runserver_la_CFLAGS = \
- $(AM_CFLAGS) \
- $(PTHREAD_CFLAGS) \
- $(NULL)
-
-libblogc_runserver_la_LIBADD = \
- $(PTHREAD_LIBS) \
- libblogc_common.la \
+ $(LIBEVENT_LIBS) \
+ $(MAGIC_LIBS) \
+ libblogc_utils.la \
$(NULL)
endif
## Build rules: man pages
-# README: all the prebuilt manpages that are hidden behind --enable-*
-# options should be added here, otherwise they may be not included
-# in the distfiles.
EXTRA_DIST += \
man/blogc.1.ronn \
man/blogc-git-receiver.1.ronn \
- man/blogc-make.1.ronn \
man/blogc-runserver.1.ronn \
- man/blogcfile.5.ronn \
man/blogc-source.7.ronn \
man/blogc-template.7.ronn \
- man/blogc-toctree.7.ronn \
man/blogc-pagination.7.ronn \
man/index.txt \
blogc-git-receiver.1 \
- blogc-make.1 \
blogc-runserver.1 \
- blogcfile.5 \
$(NULL)
dist_man_MANS = \
blogc.1 \
blogc-source.7 \
blogc-template.7 \
- blogc-toctree.7 \
blogc-pagination.7 \
$(NULL)
@@ -336,13 +184,6 @@ dist_man_MANS += \
$(NULL)
endif
-if BUILD_MAKE_LIB
-dist_man_MANS += \
- blogc-make.1 \
- blogcfile.5
- $(NULL)
-endif
-
if BUILD_RUNSERVER
dist_man_MANS += \
blogc-runserver.1 \
@@ -353,7 +194,7 @@ MAINTAINERCLEANFILES += \
$(dist_man_MANS) \
$(NULL)
-if BUILD_MANPAGE
+if USE_RONN
blogc.1: man/blogc.1.ronn
$(AM_V_GEN)$(RONN) \
@@ -371,14 +212,6 @@ blogc-git-receiver.1: man/blogc-git-receiver.1.ronn
--manual "$(PACKAGE_NAME) Manual" \
$(top_srcdir)/man/blogc-git-receiver.1.ronn > blogc-git-receiver.1
-blogc-make.1: man/blogc-make.1.ronn
- $(AM_V_GEN)$(RONN) \
- --roff \
- --pipe \
- --organization "Rafael G. Martins" \
- --manual "$(PACKAGE_NAME) Manual" \
- $(top_srcdir)/man/blogc-make.1.ronn > blogc-make.1
-
blogc-runserver.1: man/blogc-runserver.1.ronn
$(AM_V_GEN)$(RONN) \
--roff \
@@ -387,14 +220,6 @@ blogc-runserver.1: man/blogc-runserver.1.ronn
--manual "$(PACKAGE_NAME) Manual" \
$(top_srcdir)/man/blogc-runserver.1.ronn > blogc-runserver.1
-blogcfile.5: man/blogcfile.5.ronn
- $(AM_V_GEN)$(RONN) \
- --roff \
- --pipe \
- --organization "Rafael G. Martins" \
- --manual "$(PACKAGE_NAME) Manual" \
- $(top_srcdir)/man/blogcfile.5.ronn > blogcfile.5
-
blogc-source.7: man/blogc-source.7.ronn
$(AM_V_GEN)$(RONN) \
--roff \
@@ -411,14 +236,6 @@ blogc-template.7: man/blogc-template.7.ronn
--manual "$(PACKAGE_NAME) Manual" \
$(top_srcdir)/man/blogc-template.7.ronn > blogc-template.7
-blogc-toctree.7: man/blogc-toctree.7.ronn
- $(AM_V_GEN)$(RONN) \
- --roff \
- --pipe \
- --organization "Rafael G. Martins" \
- --manual "$(PACKAGE_NAME) Manual" \
- $(top_srcdir)/man/blogc-toctree.7.ronn > blogc-toctree.7
-
blogc-pagination.7: man/blogc-pagination.7.ronn
$(AM_V_GEN)$(RONN) \
--roff \
@@ -435,9 +252,6 @@ blogc.1:
blogc-git-receiver.1:
$(AM_V_GEN)echo "error: ronn not found. failed to build man page: $@"; exit 1
-blogc-make.1:
- $(AM_V_GEN)echo "error: ronn not found. failed to build man page: $@"; exit 1
-
blogc-runserver.1:
$(AM_V_GEN)echo "error: ronn not found. failed to build man page: $@"; exit 1
@@ -447,9 +261,6 @@ blogc-source.7:
blogc-template.7:
$(AM_V_GEN)echo "error: ronn not found. failed to build man page: $@"; exit 1
-blogc-toctree.7:
- $(AM_V_GEN)echo "error: ronn not found. failed to build man page: $@"; exit 1
-
blogc-pagination.7:
$(AM_V_GEN)echo "error: ronn not found. failed to build man page: $@"; exit 1
@@ -458,646 +269,191 @@ endif
## Build rules: tests
-if BUILD_TESTS
-
-if BUILD_GIT_RECEIVER
-if USE_BGR_DEPS
-check_SCRIPTS += \
- tests/blogc-git-receiver/check_post_receive.sh \
- tests/blogc-git-receiver/check_pre_receive.sh \
- tests/blogc-git-receiver/check_shell.sh \
- $(NULL)
-endif
-endif
-
-if BUILD_MAKE
-check_SCRIPTS += \
- tests/blogc-make/check_blogc_make.sh \
- $(NULL)
-endif
-
-check_SCRIPTS += \
- tests/blogc/check_blogc.sh \
- $(NULL)
-
if USE_CMOCKA
check_PROGRAMS += \
- tests/blogc/check_content_parser \
- tests/blogc/check_datetime_parser \
- tests/blogc/check_filelist_parser \
- tests/blogc/check_renderer \
- tests/blogc/check_source_parser \
- tests/blogc/check_template_parser \
- tests/blogc/check_toctree \
- tests/common/check_config_parser \
- tests/common/check_error \
- tests/common/check_sort \
- tests/common/check_utf8 \
- tests/common/check_utils \
- $(NULL)
-
-if USE_LD_WRAP
-check_PROGRAMS += \
- tests/blogc/check_funcvars \
- tests/blogc/check_loader \
- tests/blogc/check_sysinfo \
- tests/blogc/check_sysinfo2 \
- tests/common/check_stdin \
- $(NULL)
-
-tests_blogc_check_funcvars_SOURCES = \
- tests/blogc/check_funcvars.c \
- $(NULL)
-
-tests_blogc_check_funcvars_CFLAGS = \
- $(CMOCKA_CFLAGS) \
- $(NULL)
-
-tests_blogc_check_funcvars_LDFLAGS = \
- -no-install \
- -Wl,--wrap=bc_file_get_contents \
- $(NULL)
-
-tests_blogc_check_funcvars_LDADD = \
- $(CMOCKA_LIBS) \
- libblogc.la \
- libblogc_common.la \
- $(NULL)
-
-tests_blogc_check_loader_SOURCES = \
- tests/blogc/check_loader.c \
- $(NULL)
-
-tests_blogc_check_loader_CFLAGS = \
- $(CMOCKA_CFLAGS) \
- $(NULL)
-
-tests_blogc_check_loader_LDFLAGS = \
- -no-install \
- -Wl,--wrap=bc_file_get_contents \
- $(NULL)
-
-tests_blogc_check_loader_LDADD = \
- $(CMOCKA_LIBS) \
- libblogc.la \
- libblogc_common.la \
- $(NULL)
-
-tests_blogc_check_sysinfo_SOURCES = \
- tests/blogc/check_sysinfo.c \
- $(NULL)
-
-tests_blogc_check_sysinfo_CFLAGS = \
- $(CMOCKA_CFLAGS) \
- $(NULL)
-
-tests_blogc_check_sysinfo_LDFLAGS = \
- -no-install \
- -Wl,--wrap=bc_file_get_contents \
- -Wl,--wrap=getenv \
- $(NULL)
-
-if HAVE_NETDB_H
-tests_blogc_check_sysinfo_LDFLAGS += \
- -Wl,--wrap=gethostbyname \
- $(NULL)
-endif
-
-if HAVE_UNISTD_H
-tests_blogc_check_sysinfo_LDFLAGS += \
- -Wl,--wrap=gethostname \
- $(NULL)
-endif
-
-if HAVE_TIME_H
-tests_blogc_check_sysinfo_LDFLAGS += \
- -Wl,--wrap=time \
- -Wl,--wrap=gmtime \
- $(NULL)
-endif
-
-tests_blogc_check_sysinfo_LDADD = \
- $(CMOCKA_LIBS) \
- libblogc.la \
- libblogc_common.la \
- $(NULL)
-
-tests_blogc_check_sysinfo2_SOURCES = \
- tests/blogc/check_sysinfo2.c \
- $(NULL)
-
-tests_blogc_check_sysinfo2_CFLAGS = \
- $(CMOCKA_CFLAGS) \
- $(NULL)
-
-tests_blogc_check_sysinfo2_LDFLAGS = \
- -no-install \
- -Wl,--wrap=bc_file_get_contents \
- $(NULL)
-
-tests_blogc_check_sysinfo2_LDADD = \
- $(CMOCKA_LIBS) \
- libblogc.la \
- libblogc_common.la \
- $(NULL)
-
-tests_common_check_stdin_SOURCES = \
- tests/common/check_stdin.c \
- $(NULL)
-
-tests_common_check_stdin_CFLAGS = \
- $(CMOCKA_CFLAGS) \
- $(NULL)
-
-tests_common_check_stdin_LDFLAGS = \
- -no-install \
- -Wl,--wrap=fgetc \
- $(NULL)
-
-tests_common_check_stdin_LDADD = \
- $(CMOCKA_LIBS) \
- libblogc_common.la \
- $(NULL)
-
-if HAVE_SYS_RESOURCE_H
-if HAVE_SYS_TIME_H
-check_PROGRAMS += \
- tests/blogc/check_rusage \
+ tests/check_content_parser \
+ tests/check_datetime_parser \
+ tests/check_error \
+ tests/check_loader \
+ tests/check_renderer \
+ tests/check_source_parser \
+ tests/check_template_parser \
+ tests/check_utf8 \
+ tests/check_utils \
$(NULL)
-tests_blogc_check_rusage_SOURCES = \
- tests/blogc/check_rusage.c \
+tests_check_error_SOURCES = \
+ tests/check_error.c \
$(NULL)
-tests_blogc_check_rusage_CFLAGS = \
+tests_check_error_CFLAGS = \
$(CMOCKA_CFLAGS) \
$(NULL)
-tests_blogc_check_rusage_LDFLAGS = \
+tests_check_error_LDFLAGS = \
-no-install \
- -Wl,--wrap=getrusage \
$(NULL)
-tests_blogc_check_rusage_LDADD = \
+tests_check_error_LDADD = \
$(CMOCKA_LIBS) \
libblogc.la \
- libblogc_common.la \
+ libblogc_utils.la \
$(NULL)
-endif
-endif
-
-endif
-tests_blogc_check_content_parser_SOURCES = \
- tests/blogc/check_content_parser.c \
+tests_check_loader_SOURCES = \
+ tests/check_loader.c \
$(NULL)
-tests_blogc_check_content_parser_CFLAGS = \
+tests_check_loader_CFLAGS = \
$(CMOCKA_CFLAGS) \
$(NULL)
-tests_blogc_check_content_parser_LDFLAGS = \
+tests_check_loader_LDFLAGS = \
-no-install \
+ -Wl,--wrap=blogc_file_get_contents \
+ -Wl,--wrap=blogc_fprintf \
$(NULL)
-tests_blogc_check_content_parser_LDADD = \
+tests_check_loader_LDADD = \
$(CMOCKA_LIBS) \
libblogc.la \
- libblogc_common.la \
+ libblogc_utils.la \
$(NULL)
-tests_blogc_check_datetime_parser_SOURCES = \
- tests/blogc/check_datetime_parser.c \
+tests_check_content_parser_SOURCES = \
+ tests/check_content_parser.c \
$(NULL)
-tests_blogc_check_datetime_parser_CFLAGS = \
+tests_check_content_parser_CFLAGS = \
$(CMOCKA_CFLAGS) \
$(NULL)
-tests_blogc_check_datetime_parser_LDFLAGS = \
+tests_check_content_parser_LDFLAGS = \
-no-install \
$(NULL)
-tests_blogc_check_datetime_parser_LDADD = \
+tests_check_content_parser_LDADD = \
$(CMOCKA_LIBS) \
libblogc.la \
- libblogc_common.la \
+ libblogc_utils.la \
$(NULL)
-tests_blogc_check_filelist_parser_SOURCES = \
- tests/blogc/check_filelist_parser.c \
+tests_check_datetime_parser_SOURCES = \
+ tests/check_datetime_parser.c \
$(NULL)
-tests_blogc_check_filelist_parser_CFLAGS = \
+tests_check_datetime_parser_CFLAGS = \
$(CMOCKA_CFLAGS) \
$(NULL)
-tests_blogc_check_filelist_parser_LDFLAGS = \
+tests_check_datetime_parser_LDFLAGS = \
-no-install \
$(NULL)
-tests_blogc_check_filelist_parser_LDADD = \
+tests_check_datetime_parser_LDADD = \
$(CMOCKA_LIBS) \
libblogc.la \
- libblogc_common.la \
+ libblogc_utils.la \
$(NULL)
-tests_blogc_check_renderer_SOURCES = \
- tests/blogc/check_renderer.c \
+tests_check_renderer_SOURCES = \
+ tests/check_renderer.c \
$(NULL)
-tests_blogc_check_renderer_CFLAGS = \
+tests_check_renderer_CFLAGS = \
$(CMOCKA_CFLAGS) \
$(NULL)
-tests_blogc_check_renderer_LDFLAGS = \
+tests_check_renderer_LDFLAGS = \
-no-install \
$(NULL)
-tests_blogc_check_renderer_LDADD = \
+tests_check_renderer_LDADD = \
$(CMOCKA_LIBS) \
libblogc.la \
- libblogc_common.la \
+ libblogc_utils.la \
$(NULL)
-tests_blogc_check_source_parser_SOURCES = \
- tests/blogc/check_source_parser.c \
+tests_check_source_parser_SOURCES = \
+ tests/check_source_parser.c \
$(NULL)
-tests_blogc_check_source_parser_CFLAGS = \
+tests_check_source_parser_CFLAGS = \
$(CMOCKA_CFLAGS) \
$(NULL)
-tests_blogc_check_source_parser_LDFLAGS = \
+tests_check_source_parser_LDFLAGS = \
-no-install \
$(NULL)
-tests_blogc_check_source_parser_LDADD = \
+tests_check_source_parser_LDADD = \
$(CMOCKA_LIBS) \
libblogc.la \
- libblogc_common.la \
+ libblogc_utils.la \
$(NULL)
-tests_blogc_check_template_parser_SOURCES = \
- tests/blogc/check_template_parser.c \
+tests_check_template_parser_SOURCES = \
+ tests/check_template_parser.c \
$(NULL)
-tests_blogc_check_template_parser_CFLAGS = \
+tests_check_template_parser_CFLAGS = \
$(CMOCKA_CFLAGS) \
$(NULL)
-tests_blogc_check_template_parser_LDFLAGS = \
+tests_check_template_parser_LDFLAGS = \
-no-install \
$(NULL)
-tests_blogc_check_template_parser_LDADD = \
+tests_check_template_parser_LDADD = \
$(CMOCKA_LIBS) \
libblogc.la \
- libblogc_common.la \
+ libblogc_utils.la \
$(NULL)
-tests_blogc_check_toctree_SOURCES = \
- tests/blogc/check_toctree.c \
+tests_check_utf8_SOURCES = \
+ tests/check_utf8.c \
$(NULL)
-tests_blogc_check_toctree_CFLAGS = \
+tests_check_utf8_CFLAGS = \
$(CMOCKA_CFLAGS) \
$(NULL)
-tests_blogc_check_toctree_LDFLAGS = \
+tests_check_utf8_LDFLAGS = \
-no-install \
$(NULL)
-tests_blogc_check_toctree_LDADD = \
+tests_check_utf8_LDADD = \
$(CMOCKA_LIBS) \
- libblogc.la \
- libblogc_common.la \
+ libblogc_utils.la \
$(NULL)
-tests_common_check_config_parser_SOURCES = \
- tests/common/check_config_parser.c \
+tests_check_utils_SOURCES = \
+ tests/check_utils.c \
$(NULL)
-tests_common_check_config_parser_CFLAGS = \
+tests_check_utils_CFLAGS = \
$(CMOCKA_CFLAGS) \
$(NULL)
-tests_common_check_config_parser_LDFLAGS = \
+tests_check_utils_LDFLAGS = \
-no-install \
$(NULL)
-tests_common_check_config_parser_LDADD = \
+tests_check_utils_LDADD = \
$(CMOCKA_LIBS) \
- libblogc_common.la \
- $(NULL)
-
-tests_common_check_error_SOURCES = \
- tests/common/check_error.c \
- $(NULL)
-
-tests_common_check_error_CFLAGS = \
- $(CMOCKA_CFLAGS) \
+ libblogc_utils.la \
$(NULL)
-tests_common_check_error_LDFLAGS = \
- -no-install \
- $(NULL)
-
-tests_common_check_error_LDADD = \
- $(CMOCKA_LIBS) \
- libblogc_common.la \
- $(NULL)
-
-tests_common_check_sort_SOURCES = \
- tests/common/check_sort.c \
- $(NULL)
-
-tests_common_check_sort_CFLAGS = \
- $(CMOCKA_CFLAGS) \
- $(NULL)
-
-tests_common_check_sort_LDFLAGS = \
- -no-install \
- $(NULL)
-
-tests_common_check_sort_LDADD = \
- $(CMOCKA_LIBS) \
- libblogc_common.la \
- $(NULL)
-
-tests_common_check_utf8_SOURCES = \
- tests/common/check_utf8.c \
- $(NULL)
-
-tests_common_check_utf8_CFLAGS = \
- $(CMOCKA_CFLAGS) \
- $(NULL)
-
-tests_common_check_utf8_LDFLAGS = \
- -no-install \
- $(NULL)
-
-tests_common_check_utf8_LDADD = \
- $(CMOCKA_LIBS) \
- libblogc_common.la \
- $(NULL)
-
-tests_common_check_utils_SOURCES = \
- tests/common/check_utils.c \
- $(NULL)
-
-tests_common_check_utils_CFLAGS = \
- $(CMOCKA_CFLAGS) \
- $(NULL)
-
-tests_common_check_utils_LDFLAGS = \
- -no-install \
- $(NULL)
-
-tests_common_check_utils_LDADD = \
- $(CMOCKA_LIBS) \
- libblogc_common.la \
- $(NULL)
-
-if BUILD_RUNSERVER
-if USE_LD_WRAP
-check_PROGRAMS += \
- tests/blogc-runserver/check_httpd_utils \
- tests/blogc-runserver/check_mime \
- $(NULL)
-
-tests_blogc_runserver_check_httpd_utils_SOURCES = \
- tests/blogc-runserver/check_httpd_utils.c \
- $(NULL)
-
-tests_blogc_runserver_check_httpd_utils_CFLAGS = \
- $(CMOCKA_CFLAGS) \
- $(NULL)
-
-tests_blogc_runserver_check_httpd_utils_LDFLAGS = \
- -no-install \
- -Wl,--wrap=read \
- $(NULL)
-
-tests_blogc_runserver_check_httpd_utils_LDADD = \
- $(CMOCKA_LIBS) \
- libblogc_runserver.la \
- libblogc_common.la \
- $(NULL)
-
-tests_blogc_runserver_check_mime_SOURCES = \
- tests/blogc-runserver/check_mime.c \
- $(NULL)
-
-tests_blogc_runserver_check_mime_CFLAGS = \
- $(CMOCKA_CFLAGS) \
- $(NULL)
-
-tests_blogc_runserver_check_mime_LDFLAGS = \
- -no-install \
- -Wl,--wrap=access \
- $(NULL)
-
-tests_blogc_runserver_check_mime_LDADD = \
- $(CMOCKA_LIBS) \
- libblogc_runserver.la \
- libblogc_common.la \
- $(NULL)
-endif
-endif
-
-if BUILD_GIT_RECEIVER
-check_PROGRAMS += \
- tests/blogc-git-receiver/check_pre_receive_parser \
- tests/blogc-git-receiver/check_shell_command_parser \
- $(NULL)
-
-if USE_LD_WRAP
-check_PROGRAMS += \
- tests/blogc-git-receiver/check_settings \
- $(NULL)
-
-tests_blogc_git_receiver_check_settings_SOURCES = \
- tests/blogc-git-receiver/check_settings.c \
- $(NULL)
-
-tests_blogc_git_receiver_check_settings_CFLAGS = \
- $(CMOCKA_CFLAGS) \
- $(NULL)
-
-tests_blogc_git_receiver_check_settings_LDFLAGS = \
- -no-install \
- -Wl,--wrap=realpath \
- $(NULL)
-
-tests_blogc_git_receiver_check_settings_LDADD = \
- $(CMOCKA_LIBS) \
- libblogc_git_receiver.la \
- libblogc_common.la \
- $(NULL)
-endif
-
-tests_blogc_git_receiver_check_pre_receive_parser_SOURCES = \
- tests/blogc-git-receiver/check_pre_receive_parser.c \
- $(NULL)
-
-tests_blogc_git_receiver_check_pre_receive_parser_CFLAGS = \
- $(CMOCKA_CFLAGS) \
- $(NULL)
-
-tests_blogc_git_receiver_check_pre_receive_parser_LDFLAGS = \
- -no-install \
- $(NULL)
-
-tests_blogc_git_receiver_check_pre_receive_parser_LDADD = \
- $(CMOCKA_LIBS) \
- libblogc_git_receiver.la \
- libblogc_common.la \
- $(NULL)
-
-tests_blogc_git_receiver_check_shell_command_parser_SOURCES = \
- tests/blogc-git-receiver/check_shell_command_parser.c \
- $(NULL)
-
-tests_blogc_git_receiver_check_shell_command_parser_CFLAGS = \
- $(CMOCKA_CFLAGS) \
- $(NULL)
-
-tests_blogc_git_receiver_check_shell_command_parser_LDFLAGS = \
- -no-install \
- $(NULL)
-
-tests_blogc_git_receiver_check_shell_command_parser_LDADD = \
- $(CMOCKA_LIBS) \
- libblogc_git_receiver.la \
- libblogc_common.la \
- $(NULL)
-endif
-
-if BUILD_MAKE_LIB
-check_PROGRAMS += \
- tests/blogc-make/check_atom \
- tests/blogc-make/check_rules \
- tests/blogc-make/check_settings \
- tests/blogc-make/check_utils \
- $(NULL)
-
-if USE_LD_WRAP
-check_PROGRAMS += \
- tests/blogc-make/check_exec \
- $(NULL)
-
-tests_blogc_make_check_exec_SOURCES = \
- tests/blogc-make/check_exec.c \
- $(NULL)
-
-tests_blogc_make_check_exec_CFLAGS = \
- $(CMOCKA_CFLAGS) \
- $(NULL)
-
-tests_blogc_make_check_exec_LDFLAGS = \
- -no-install \
- -Wl,--wrap=access \
- $(NULL)
-
-tests_blogc_make_check_exec_LDADD = \
- $(CMOCKA_LIBS) \
- libblogc_make.la \
- libblogc_common.la \
- $(NULL)
-endif
-
-tests_blogc_make_check_atom_SOURCES = \
- tests/blogc-make/check_atom.c \
- $(NULL)
-
-tests_blogc_make_check_atom_CFLAGS = \
- $(CMOCKA_CFLAGS) \
- $(NULL)
-
-tests_blogc_make_check_atom_LDFLAGS = \
- -no-install \
- $(NULL)
-
-tests_blogc_make_check_atom_LDADD = \
- $(CMOCKA_LIBS) \
- libblogc_make.la \
- libblogc_common.la \
- $(NULL)
-
-tests_blogc_make_check_rules_SOURCES = \
- tests/blogc-make/check_rules.c \
- $(NULL)
-
-tests_blogc_make_check_rules_CFLAGS = \
- $(CMOCKA_CFLAGS) \
- $(NULL)
-
-tests_blogc_make_check_rules_LDFLAGS = \
- -no-install \
- $(NULL)
-
-tests_blogc_make_check_rules_LDADD = \
- $(CMOCKA_LIBS) \
- libblogc_make.la \
- libblogc_common.la \
- $(NULL)
-
-tests_blogc_make_check_settings_SOURCES = \
- tests/blogc-make/check_settings.c \
- $(NULL)
-
-tests_blogc_make_check_settings_CFLAGS = \
- $(CMOCKA_CFLAGS) \
- $(NULL)
-
-tests_blogc_make_check_settings_LDFLAGS = \
- -no-install \
- $(NULL)
-
-tests_blogc_make_check_settings_LDADD = \
- $(CMOCKA_LIBS) \
- libblogc_make.la \
- libblogc_common.la \
- $(NULL)
-
-tests_blogc_make_check_utils_SOURCES = \
- tests/blogc-make/check_utils.c \
- $(NULL)
-
-tests_blogc_make_check_utils_CFLAGS = \
- $(CMOCKA_CFLAGS) \
- $(NULL)
-
-tests_blogc_make_check_utils_LDFLAGS = \
- -no-install \
- $(NULL)
-
-tests_blogc_make_check_utils_LDADD = \
- $(CMOCKA_LIBS) \
- libblogc_make.la \
- libblogc_common.la \
- $(NULL)
-endif
-
-endif
-
endif
TESTS = \
- $(check_PROGRAMS) \
- $(check_SCRIPTS) \
- $(NULL)
-
-CLEANFILES += \
- $(check_SCRIPTS) \
- $(NULL)
+ $(check_PROGRAMS)
## Helpers: dist-srpm
-if BUILD_SRPM
+if USE_RPMBUILD
dist-srpm: blogc.spec dist-xz
$(RPMBUILD) \
--define "_srcrpmdir $(top_builddir)" \
@@ -1120,9 +476,12 @@ dist-hook:
if USE_VALGRIND
valgrind: all
$(MAKE) check TESTS_ENVIRONMENT=" \
- VALGRIND=$(VALGRIND) \
- $(BASH) -e $(top_srcdir)/build-aux/valgrind.sh"
-endif
+ $(VALGRIND) \
+ --tool=memcheck \
+ --leak-check=full \
+ --leak-resolution=high \
+ --num-callers=20 \
+ --error-exitcode=1 \
+ --show-possibly-lost=no"
-
-.PHONY: dist-srpm valgrind
+endif
diff --git a/README.md b/README.md
index 2194f2c..74b96f8 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# blogc
-![Build Status](https://github.com/blogc/blogc/workflows/yatr/badge.svg)
+[![Build Status](https://travis-ci.org/blogc/blogc.svg?branch=master)](https://travis-ci.org/blogc/blogc)
A blog compiler.
@@ -14,11 +14,11 @@ If installing from Git repository, [ronn](https://github.com/rtomayko/ronn) and
Inside the source directory, run the following commands:
$ ./autogen.sh # if installing from git
- $ ./configure [--enable-git-receiver] [--enable-make] [--enable-runserver]
+ $ ./configure [--enable-git-receiver] [--enable-runserver]
$ make
# make install
-The `./configure` options listed above will enable building of helper tools. To learn more about these tools, please read the man pages.
+The `./configure` options listed above will enable building of helper tools. To learn more about these tools, please read the man pages. Be aware that [`blogc-runserver(1)`](https://blogc.rgm.io/man/blogc-runserver.1.html) depends on [libmagic](https://github.com/file/file) and [libevent](http://libevent.org/), but this tool can be replaced by any HTTP server you want to use.
To create your first blog, please clone our example repository and adapt it to your needs:
diff --git a/blogc.spec.in b/blogc.spec.in
index d4fd841..aa0cba6 100644
--- a/blogc.spec.in
+++ b/blogc.spec.in
@@ -6,66 +6,43 @@ Group: Applications/Text
Summary: A blog compiler
URL: @PACKAGE_URL@
Source0: https://github.com/blogc/blogc/releases/download/v@PACKAGE_VERSION@/blogc-@PACKAGE_VERSION@.tar.xz
-BuildRequires: gcc, bash, coreutils, diffutils
%if ! 0%{?el6}
-BuildRequires: git, tar, make
-%endif
-%if ! 0%{?el8}
-BuildRequires: libcmocka-devel
+BuildRequires: libevent-devel >= 2.0, file-devel
%endif
%description
-blogc(1) is a blog compiler. It compiles source files and templates into
+blogc(1) is a blog compiler. It converts source files and templates into
blog/website resources.
-%if ! 0%{?el6}
%package git-receiver
Summary: A simple login shell/git hook to deploy blogc websites
Group: System Environment/Shells
Requires: git, tar, make
-Requires: %{name}-make = %{version}-%{release}
%description git-receiver
blogc-git-receiver is a simple login shell/git hook to deploy blogc websites.
-%endif
-
-%package make
-Summary: A simple build tool for blogc
-Group: Development/Tools
-Requires: %{name} = %{version}-%{release}
-Requires: %{name}-runserver = %{version}-%{release}
-
-%description make
-blogc-make is a simple build tool for blogc websites.
+%if ! 0%{?el6}
%package runserver
Summary: A simple HTTP server to test blogc websites
Group: Development/Tools
+Requires: libevent >= 2.0, file-libs
%description runserver
blogc-runserver is a simple HTTP server to test blogc websites.
+%endif
%prep
%setup -q -n @PACKAGE_NAME@-@PACKAGE_VERSION@
%build
-%define _lto_cflags %{nil}
%if 0%{?el6}
-%configure --disable-git-receiver --enable-make --enable-runserver --enable-tests
-%else
-%if 0%{?el8}
-%configure --enable-git-receiver --enable-make --enable-runserver --disable-tests
+%configure --enable-git-receiver --disable-runserver
%else
-%configure --enable-git-receiver --enable-make --enable-runserver --enable-tests
-%endif
+%configure --enable-git-receiver --enable-runserver
%endif
make %{?_smp_mflags}
-%if ! 0%{?el8}
-%check
-make check
-%endif
-
%install
rm -rf $RPM_BUILD_ROOT
%make_install
@@ -74,103 +51,24 @@ rm -rf $RPM_BUILD_ROOT
%{_mandir}/man*/blogc.*
%{_mandir}/man*/blogc-source.*
%{_mandir}/man*/blogc-template.*
-%{_mandir}/man*/blogc-toctree.*
%{_mandir}/man*/blogc-pagination.*
%{_bindir}/blogc
%doc README.md
%license LICENSE
-%if ! 0%{?el6}
%files git-receiver
%{_mandir}/man*/blogc-git-receiver.*
%{_bindir}/blogc-git-receiver
%license LICENSE
-%endif
-
-%files make
-%{_mandir}/man*/blogc-make.*
-%{_mandir}/man*/blogcfile.*
-%{_bindir}/blogc-make
-%license LICENSE
+%if ! 0%{?el6}
%files runserver
%{_mandir}/man*/blogc-runserver.*
%{_bindir}/blogc-runserver
%license LICENSE
+%endif
%changelog
-* Sat Jan 02 2021 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.20.1-1
-- New release.
-
-* Tue Sep 15 2020 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.20.0-1
-- New release.
-
-* Sun May 31 2020 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.19.0-1
-- New release.
-
-* Tue Sep 10 2019 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.18.0-1
-- New release.
-
-* Thu May 2 2019 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.17.0-1
-- New release.
-
-* Sun Apr 21 2019 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.16.1-1
-- New release.
-
-* Sat Apr 13 2019 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.16.0-1
-- New release.
-
-* Tue Feb 26 2019 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.15.1-1
-- New release.
-
-* Mon Feb 11 2019 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.15.0-1
-- New release.
-
-* Tue Jan 15 2019 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.14.1-1
-- New release.
-
-* Thu Jul 26 2018 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.14.0-1
-- New release.
-
-* Sun Jul 22 2018 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.13.10-1
-- New release.
-
-* Tue Jun 12 2018 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.13.9-1
-- New release.
-
-* Sun Jun 10 2018 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.13.8-1
-- New release.
-
-* Sun Jun 10 2018 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.13.7-1
-- New release.
-
-* Mon May 14 2018 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.13.6-1
-- New release.
-
-* Sun May 13 2018 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.13.5-1
-- New release.
-
-* Tue Mar 20 2018 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.13.4-1
-- New release.
-
-* Wed Mar 14 2018 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.13.3-1
-- New release.
-
-* Mon Mar 12 2018 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.13.2-1
-- New release.
-
-* Thu Feb 22 2018 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.13.1-1
-- New release.
-
-* Sun Nov 19 2017 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.13.0-1
-- New release.
-
-* Sun Oct 30 2016 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.12.0-1
-- New release.
-
-* Sun Jul 17 2016 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.11.1-1
-- New release.
-
* Tue Jul 5 2016 Rafael G. Martins <rafael@rafaelmartins.eng.br> 0.11.0-1
- New release.
diff --git a/build-aux/build-debian.sh b/build-aux/build-debian.sh
deleted file mode 100755
index 44e9869..0000000
--- a/build-aux/build-debian.sh
+++ /dev/null
@@ -1,153 +0,0 @@
-#!/bin/bash
-
-set -exo pipefail
-
-export DEBEMAIL="rafael+deb@rafaelmartins.eng.br"
-export DEBFULLNAME="Automatic Builder (github-actions)"
-export DEB_BUILD_OPTIONS="noddebs"
-
-export DIST="$(echo "${TARGET}" | cut -d- -f2)"
-
-MY_P="${PN}_${PV}"
-ARCH="$(echo "${TARGET}" | cut -d- -f3)"
-
-REV=
-case ${DIST} in
- bullseye)
- REV="1~11bullseye"
- ;;
- bookworm)
- REV="1~12bookworm"
- DEB_BUILD_OPTIONS="${DEB_BUILD_OPTIONS} nocheck"
- ;;
- sid)
- REV="1~sid"
- DEB_BUILD_OPTIONS="${DEB_BUILD_OPTIONS} nocheck"
- ;;
- focal)
- REV="1~11.0focal"
- ;;
- jammy)
- REV="1~12.0jammy"
- ;;
- kinetic)
- REV="1~12.1kinetic"
- DEB_BUILD_OPTIONS="${DEB_BUILD_OPTIONS} nocheck"
- ;;
- *)
- echo "error: unsupported dist: ${DIST}"
- exit 1
- ;;
-esac
-
-download_pbuilder_chroot() {
- local index="$(wget -q -O- https://distfiles.rgm.io/pbuilder-chroots/LATEST/)"
- local archive="$(echo "${index}" | sed -n "s/.*\(pbuilder-chroot-${DIST}-${ARCH}-.*\)\.sha512.*/\1/p" | head -n 1)"
- local p="$(echo "${index}" | sed -n "s/.*pbuilder-chroot-${DIST}-${ARCH}-\(.*\)\.tar.*\.sha512.*/pbuilder-chroots-\1/p" | head -n 1)"
-
- pushd "${SRCDIR}" > /dev/null
-
- wget -c "https://distfiles.rgm.io/pbuilder-chroots/${p}/${archive}"{,.sha512}
- sha512sum --check --status "${archive}.sha512"
-
- sudo rm -rf /tmp/pbuilder
- mkdir /tmp/pbuilder
- fakeroot tar --checkpoint=1000 -xf "${archive}" -C /tmp/pbuilder
-
- popd > /dev/null
-}
-
-download_orig() {
- local i=0
- local out=0
- local url="https://distfiles.rgm.io/${PN}/${P}/${P}.tar.xz"
-
- while [[ $i -lt 20 ]]; do
- set +ex
- ((i++))
- echo "waiting for ${P}.tar.xz: $i/20"
- wget -q --spider --tries 1 "${url}"
- out=$?
- set -ex
-
- if [[ $out -eq 0 ]]; then
- wget -c "${url}"
- mv "${P}.tar.xz" "${BUILDDIR}/${MY_P}.orig.tar.xz"
- return
- fi
-
- if [[ $out -ne 8 ]]; then
- exit $out
- fi
-
- sleep 30
- done
-
- echo "failed to find orig distfile. please check if that task succeeded."
- exit 1
-}
-
-create_reprepro_conf() {
- echo "Origin: blogc"
- echo "Label: blogc"
- echo "Codename: ${DIST}"
- echo "Architectures: source amd64"
- echo "Components: main"
- echo "Description: Apt repository containing blogc snapshots"
- echo
-}
-
-download_orig
-
-rm -rf "${BUILDDIR}/${P}"
-tar -xf "${BUILDDIR}/${MY_P}.orig.tar.xz" -C "${BUILDDIR}"
-cp -r "${SRCDIR}/debian" "${BUILDDIR}/${P}/"
-
-pushd "${BUILDDIR}/${P}" > /dev/null
-
-## skip build silently when new version is older than last changelog version (version bump)
-if ! dch \
- --distribution "${DIST}" \
- --newversion "${PV}-${REV}" \
- "Automated build for ${DIST}"
-then
- exit 0
-fi
-
-download_pbuilder_chroot
-
-sudo cowbuilder \
- --update \
- --basepath "/tmp/pbuilder/${DIST}-${ARCH}/base.cow"
-
-RES="${BUILDDIR}/deb/${DIST}"
-mkdir -p "${RES}"
-
-pdebuild \
- --pbuilder cowbuilder \
- --buildresult "${RES}" \
- --debbuildopts -sa \
- -- --basepath "/tmp/pbuilder/${DIST}-${ARCH}/base.cow"
-
-popd > /dev/null
-
-mkdir -p "${BUILDDIR}/deb-repo/conf"
-create_reprepro_conf > "${BUILDDIR}/deb-repo/conf/distributions"
-
-pushd "${BUILDDIR}/deb-repo" > /dev/null
-
-for i in "../deb/${DIST}"/*.changes; do
- reprepro include "${DIST}" "${i}"
-done
-
-popd > /dev/null
-
-tar \
- -cJf "blogc-deb-repo-${DIST}-${ARCH}-${PV}.tar.xz" \
- --exclude ./deb-repo/conf \
- --exclude ./deb-repo/db \
- ./deb-repo
-
-tar \
- -cJf "blogc-deb-${DIST}-${ARCH}-${PV}.tar.xz" \
- ./deb
diff --git a/build-aux/build-static-all.sh b/build-aux/build-static-all.sh
deleted file mode 100755
index 0cba1a3..0000000
--- a/build-aux/build-static-all.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-
-set -ex
-
-${MAKE_CMD:-make} LDFLAGS="-all-static"
-${MAKE_CMD:-make} DESTDIR="${PWD}/root" install
-install -m 644 ../LICENSE root/LICENSE
-echo "${PV}" > root/VERSION
-
-pushd root > /dev/null
-tar -cvJf "../${PN}-${TARGET}-amd64-${PV}.tar.xz" *
-popd > /dev/null
diff --git a/build-aux/build-static.sh b/build-aux/build-static.sh
deleted file mode 100755
index cacca1b..0000000
--- a/build-aux/build-static.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-
-set -ex
-
-${MAKE_CMD:-make} LDFLAGS="-all-static" blogc
-
-xz -zc blogc > "blogc-static-amd64-${PV}.xz"
diff --git a/build-aux/build-windows.sh b/build-aux/build-windows.sh
deleted file mode 100755
index b00fbe6..0000000
--- a/build-aux/build-windows.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-
-set -ex
-
-DESTDIR="${PN}-${TARGET}-${PV}"
-
-${MAKE_CMD:-make} blogc.exe
-
-rm -rf "${DESTDIR}"
-mkdir -p "${DESTDIR}"
-
-cp .libs/blogc.exe "${DESTDIR}/"
-cp ../LICENSE "${DESTDIR}/"
-cp ../README.md "${DESTDIR}/"
-
-zip "${DESTDIR}.zip" "${DESTDIR}"/*
diff --git a/build-aux/check-make-embedded.sh b/build-aux/check-make-embedded.sh
deleted file mode 100755
index d2e5fe4..0000000
--- a/build-aux/check-make-embedded.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-
-set -ex
-
-${MAKE_CMD:-make} check
diff --git a/build-aux/clang-analyzer.sh b/build-aux/clang-analyzer.sh
deleted file mode 100755
index e7820c4..0000000
--- a/build-aux/clang-analyzer.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
-
-set -ex
-
-P="${PN}-clang-analyzer-${PV}"
-
-set +e
-scan-build \
- --use-cc="${CC:-clang}" \
- -o reports \
- make
-RV=$?
-set -e
-
-NUM_REPORTS=$(ls -1 reports | wc -l)
-[[ ${NUM_REPORTS} -eq 0 ]] && exit ${RV}
-[[ ${NUM_REPORTS} -eq 1 ]]
-
-REPORTS="reports/$(ls -1 reports)"
-if [[ -d "${REPORTS}" ]]; then
- mv "${REPORTS}" clang-analyzer
- tar \
- -cvJf "${P}.tar.xz" \
- clang-analyzer
- RV=1
-fi
-
-exit ${RV}
diff --git a/build-aux/travis-build.sh b/build-aux/travis-build.sh
new file mode 100755
index 0000000..53cf589
--- /dev/null
+++ b/build-aux/travis-build.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+set -ex
+
+rm -rf build
+mkdir -p build
+
+pushd build > /dev/null
+
+../configure \
+ CFLAGS="-Wall -g" \
+ --enable-ronn \
+ --disable-silent-rules \
+ --enable-tests \
+ --enable-valgrind \
+ --enable-git-receiver \
+ --enable-runserver
+
+popd > /dev/null
+
+make -C build "${TARGET}"
diff --git a/build-aux/travis-deploy.sh b/build-aux/travis-deploy.sh
new file mode 100755
index 0000000..51aac3e
--- /dev/null
+++ b/build-aux/travis-deploy.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+
+set -e
+
+if [[ "x${TRAVIS_PULL_REQUEST}" != "xfalse" ]]; then
+ echo "This is a pull request. skipping deploy ..."
+ exit 0
+fi
+
+if [[ "x${TRAVIS_BRANCH}" != "xmaster" ]] && [[ "x${TRAVIS_TAG}" != xv* ]]; then
+ echo "This isn't master branch nor a valid tag. skipping deploy ..."
+ exit 0
+fi
+
+if [[ "x${CC}" != "xgcc" ]] || [[ "x${TARGET}" = "xvalgrind" ]]; then
+ echo "Invalid target for deploy. skipping ..."
+ exit 0
+fi
+
+if [[ ! -d build ]]; then
+ echo "Build directory not found."
+ exit 1
+fi
+
+if [[ "x${TARGET}" = "xdist-srpm" ]]; then
+ FILES=( build/*.src.rpm )
+else
+ FILES=( build/*.{*.tar.{gz,bz2,xz},zip} )
+fi
+
+TARNAME="$(grep PACKAGE_TARNAME build/config.h | cut -d\" -f2)"
+VERSION="$(grep PACKAGE_VERSION build/config.h | cut -d\" -f2)"
+
+do_curl() {
+ curl \
+ --silent \
+ --ftp-create-dirs \
+ --upload-file "${1}" \
+ --user "${FTP_USER}:${FTP_PASSWORD}" \
+ "ftp://${FTP_HOST}/public_html/${TARNAME}/${TARNAME}-${VERSION}/$(basename ${1})"
+}
+
+echo " * Found files:"
+for f in "${FILES[@]}"; do
+ echo " $(basename ${f})"
+done
+echo
+
+for f in "${FILES[@]}"; do
+ echo " * Processing file: $(basename ${f}):"
+
+ echo -n " Generating SHA512 checksum ... "
+ pushd build > /dev/null
+ sha512sum "$(basename ${f})" > "$(basename ${f}).sha512"
+ popd > /dev/null
+ echo "done"
+
+ echo -n " Uploading file ... "
+ do_curl "${f}"
+ echo "done"
+
+ echo -n " Uploading SHA512 checksum ... "
+ do_curl "${f}.sha512"
+ echo "done"
+
+ echo
+done
diff --git a/build-aux/valgrind.sh b/build-aux/valgrind.sh
deleted file mode 100755
index 991b906..0000000
--- a/build-aux/valgrind.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-
-export TESTS_ENVIRONMENT="
- ${VALGRIND:-valgrind} \
- --tool=memcheck \
- --leak-check=full \
- --leak-resolution=high \
- --num-callers=20 \
- --error-exitcode=1 \
- --show-possibly-lost=no"
-
-if [[ "${1}" == *.sh ]]; then
- exec "${@}"
-else
- exec ${TESTS_ENVIRONMENT} "${@}"
-fi
diff --git a/configure.ac b/configure.ac
index 3e98afc..11d2216 100644
--- a/configure.ac
+++ b/configure.ac
@@ -42,7 +42,7 @@ AS_IF([test "x$have_rpmbuild" = "xyes"], , [
AC_MSG_ERROR([rpmbuild requested but not found])
])
])
-AM_CONDITIONAL([BUILD_SRPM], [test "x$ac_cv_path_rpmbuild" != "x"])
+AM_CONDITIONAL([USE_RPMBUILD], [test "x$ac_cv_path_rpmbuild" != "x"])
RPMBUILD="$ac_cv_path_rpmbuild"
AC_SUBST(RPMBUILD)
@@ -61,7 +61,7 @@ AS_IF([test "x$have_ronn" = "xyes"], , [
AC_MSG_ERROR([ronn requested but not found])
])
])
-AM_CONDITIONAL([BUILD_MANPAGE], [test "x$have_ronn" = "xyes"])
+AM_CONDITIONAL([USE_RONN], [test "x$have_ronn" = "xyes"])
RONN="$ac_cv_path_ronn"
AC_SUBST(RONN)
@@ -84,66 +84,11 @@ AM_CONDITIONAL([USE_VALGRIND], [test "x$have_valgrind" = "xyes"])
VALGRIND="$ac_cv_path_valgrind"
AC_SUBST(VALGRIND)
-GIT_RECEIVER="disabled"
-AC_ARG_ENABLE([git-receiver], AS_HELP_STRING([--enable-git-receiver],
- [build blogc-git-receiver tool]))
-AS_IF([test "x$enable_git_receiver" = "xyes"], [
- AC_CHECK_HEADERS([sys/types.h sys/stat.h time.h libgen.h unistd.h errno.h dirent.h], [
- GIT_RECEIVER="enabled"
- have_git_receiver=yes
- ], [
- AC_MSG_ERROR([blogc-git-receiver tool requested but required headers not found])
- ])
-])
-AM_CONDITIONAL([BUILD_GIT_RECEIVER], [test "x$have_git_receiver" = "xyes"])
-
-MAKE_="disabled"
-AC_ARG_ENABLE([make-embedded], AS_HELP_STRING([--enable-make-embedded],
- [build blogc-make tool embedded on blogc binary]))
-AC_ARG_ENABLE([make], AS_HELP_STRING([--enable-make],
- [build blogc-make tool]))
-AS_IF([test "x$enable_make" = "xyes" -o "x$enable_make_embedded" = "xyes"], [
- AC_CHECK_HEADERS([dirent.h fcntl.h libgen.h sys/stat.h sys/wait.h time.h unistd.h],, [
- AC_MSG_ERROR([blogc-make tool requested but required headers not found])
- ])
- AX_PTHREAD([], [
- AC_MSG_ERROR([blogc-make tool requested but pthread is not supported])
- ])
- have_make_lib=yes
- AS_IF([test "x$enable_make_embedded" = "xyes"], [
- MAKE_="enabled (embedded)"
- have_make_embedded=yes
- AC_DEFINE([MAKE_EMBEDDED], [], [Build blogc-make embedded to blogc binary])
- ], [
- MAKE_="enabled"
- have_make=yes
- ])
-])
-AM_CONDITIONAL([BUILD_MAKE], [test "x$have_make" = "xyes"])
-AM_CONDITIONAL([BUILD_MAKE_LIB], [test "x$have_make_lib" = "xyes"])
-AM_CONDITIONAL([BUILD_MAKE_EMBEDDED], [test "x$have_make_embedded" = "xyes"])
-
-RUNSERVER="disabled"
-AC_ARG_ENABLE([runserver], AS_HELP_STRING([--enable-runserver],
- [build blogc-runserver tool]))
-AS_IF([test "x$enable_runserver" = "xyes"], [
- AC_CHECK_HEADERS([signal.h limits.h fcntl.h unistd.h sys/stat.h sys/types.h sys/socket.h netinet/in.h arpa/inet.h],, [
- AC_MSG_ERROR([blogc-runserver tool requested but required headers not found])
- ])
- AX_PTHREAD([], [
- AC_MSG_ERROR([blogc-runserver tool requested but pthread is not supported])
- ])
- RUNSERVER="enabled"
- have_runserver=yes
-])
-AM_CONDITIONAL([BUILD_RUNSERVER], [test "x$have_runserver" = "xyes"])
-
TESTS="disabled"
AC_ARG_ENABLE([tests], AS_HELP_STRING([--disable-tests],
[disable unit tests, ignoring presence of cmocka]))
AS_IF([test "x$enable_tests" != "xno"], [
PKG_CHECK_MODULES([CMOCKA], [cmocka], [
- have_cmocka=yes
AC_MSG_CHECKING([whether the linker supports -wrap])
save_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -Wl,-wrap,exit"
@@ -154,79 +99,60 @@ AS_IF([test "x$enable_tests" != "xno"], [
[exit(1);]
])
], [
- have_ld_wrap=yes
+ TESTS="enabled"
+ have_cmocka=yes
], [
- have_ld_wrap=no
+ have_cmocka=no
], [
- have_ld_wrap=no
- ])
- AC_MSG_RESULT([$have_ld_wrap])
- AS_IF([test "x$have_ld_wrap" = "xyes"],, [
- AC_MSG_WARN([linker does not supports -wrap. tests requiring it will be disabled])
+ have_cmocka=no
])
+ AC_MSG_RESULT([$have_cmocka])
LDFLAGS="$save_LDFLAGS"
], [
have_cmocka=no
])
- AS_IF([test "x$have_cmocka" = "xyes"],, [
- have_tests=no
- TESTS="disabled"
- AS_IF([test "x$enable_tests" = "xyes"], [
- AC_MSG_ERROR([tests requested but cmocka was not found])
- ], [
- AC_MSG_WARN([cmocka was not found, disabling tests])
- ])
+])
+AS_IF([test "x$have_cmocka" = "xyes"], , [
+ AS_IF([test "x$enable_tests" = "xyes"], [
+ AC_MSG_ERROR([unit tests requested but cmocka not found])
])
+])
+AM_CONDITIONAL([USE_CMOCKA], [test "x$have_cmocka" = "xyes"])
- AC_PATH_PROG([git], [git])
- AC_PATH_PROG([make], [make])
- AC_PATH_PROG([tar], [tar])
- AS_IF([test "x$ac_cv_path_git" = "x" -o "x$ac_cv_path_make" = "x" -o "x$ac_cv_path_tar" = "x"], [
- have_bgr_deps=no
- AS_IF([test "x$have_git_receiver" = "xyes"], [
- have_tests=no
- TESTS="disabled"
- AS_IF([test "x$enable_tests" = "xyes"], [
- AC_MSG_ERROR([tests requested for blogc-git-receiver but git and/or tar not found])
- ], [
- AC_MSG_WARN([git and/or tar not found, install it to run blogc-git-receiver tests])
- ])
- ])
+GIT_RECEIVER="disabled"
+AC_ARG_ENABLE([git-receiver], AS_HELP_STRING([--enable-git-receiver],
+ [build blogc-git-receiver tool]))
+AS_IF([test "x$enable_git_receiver" = "xyes"], [
+ AC_CHECK_HEADERS([sys/types.h sys/stat.h time.h libgen.h unistd.h errno.h dirent.h], [
+ GIT_RECEIVER="enabled"
+ have_git_receiver=yes
], [
- have_bgr_deps=yes
+ AC_MSG_ERROR([blogc-git-receiver tool requested but required headers not found])
])
+])
+AM_CONDITIONAL([BUILD_GIT_RECEIVER], [test "x$have_git_receiver" = "xyes"])
- AC_PATH_PROG([bash], [bash])
- AC_PATH_PROG([diff], [diff])
- AC_PATH_PROG([tee], [tee])
- AS_IF([test "x$ac_cv_path_bash" = "x" -o "x$ac_cv_path_diff" = "x" -o "x$ac_cv_path_tee" = "x"], [
- have_tests=no
- TESTS="disabled"
- AS_IF([test "x$enable_tests" = "xyes"], [
- AC_MSG_ERROR([tests requested but bash, diff and/or tee not found])
- ], [
- AC_MSG_WARN([bash, diff and/or tee not found, install it to run tests])
- ])
- ], [
- have_tests=yes
- TESTS="enabled"
+RUNSERVER="disabled"
+AC_ARG_ENABLE([runserver], AS_HELP_STRING([--enable-runserver],
+ [build blogc-runserver tool]))
+AS_IF([test "x$enable_runserver" = "xyes"], [
+ AC_CHECK_HEADERS([signal.h stdarg.h fcntl.h unistd.h sys/stat.h sys/types.h],, [
+ AC_MSG_ERROR([blogc-runserver tool requested but required headers not found])
])
+ AC_CHECK_HEADERS([magic.h],, [
+ AC_MSG_ERROR([blogc-runserver tool requested but libmagic headers not found])
+ ])
+ AC_CHECK_LIB(magic, [magic_open], [MAGIC_LIBS="-lmagic"], [
+ AC_MSG_ERROR([blogc-runserver tool requested but libmagic library not found])
+ ])
+ AC_SUBST(MAGIC_LIBS)
+ PKG_CHECK_MODULES([LIBEVENT], [libevent >= 2.0])
+ RUNSERVER="enabled"
+ have_runserver=yes
])
-AM_CONDITIONAL([BUILD_TESTS], [test "x$have_tests" = "xyes"])
-AM_CONDITIONAL([USE_CMOCKA], [test "x$have_cmocka" = "xyes"])
-AM_CONDITIONAL([USE_LD_WRAP], [test "x$have_ld_wrap" = "xyes"])
-AM_CONDITIONAL([USE_BGR_DEPS], [test "x$have_bgr_deps" = "xyes"])
-BASH="$ac_cv_path_bash"
-AC_SUBST(BASH)
-
-AC_CHECK_HEADERS([netdb.h sys/resource.h sys/stat.h sys/time.h sys/wait.h time.h unistd.h sysexits.h])
-AC_CHECK_FUNCS([gethostname])
+AM_CONDITIONAL([BUILD_RUNSERVER], [test "x$have_runserver" = "xyes"])
-AM_CONDITIONAL([HAVE_NETDB_H], [test "x$ac_cv_header_netdb_h" = "xyes"])
-AM_CONDITIONAL([HAVE_TIME_H], [test "x$ac_cv_header_time_h" = "xyes"])
-AM_CONDITIONAL([HAVE_UNISTD_H], [test "x$ac_cv_header_unistd_h" = "xyes"])
-AM_CONDITIONAL([HAVE_SYS_RESOURCE_H], [test "x$ac_cv_header_sys_resource_h" = "xyes"])
-AM_CONDITIONAL([HAVE_SYS_TIME_H], [test "x$ac_cv_header_sys_time_h" = "xyes"])
+AC_CHECK_HEADERS([sys/stat.h time.h])
LT_LIB_M
@@ -234,16 +160,7 @@ AC_CONFIG_FILES([
Makefile
blogc.spec
])
-AC_CONFIG_FILES([tests/blogc/check_blogc.sh],
- [chmod +x tests/blogc/check_blogc.sh])
-AC_CONFIG_FILES([tests/blogc-git-receiver/check_pre_receive.sh],
- [chmod +x tests/blogc-git-receiver/check_pre_receive.sh])
-AC_CONFIG_FILES([tests/blogc-git-receiver/check_post_receive.sh],
- [chmod +x tests/blogc-git-receiver/check_post_receive.sh])
-AC_CONFIG_FILES([tests/blogc-git-receiver/check_shell.sh],
- [chmod +x tests/blogc-git-receiver/check_shell.sh])
-AC_CONFIG_FILES([tests/blogc-make/check_blogc_make.sh],
- [chmod +x tests/blogc-make/check_blogc_make.sh])
+
AC_OUTPUT
AS_ECHO("
@@ -258,7 +175,6 @@ AS_ECHO("
ldflags: ${LDFLAGS}
blogc-git-receiver: ${GIT_RECEIVER}
- blogc-make: ${MAKE_}
blogc-runserver: ${RUNSERVER}
tests: ${TESTS}
diff --git a/debian/blogc-git-receiver.install b/debian/blogc-git-receiver.install
deleted file mode 100644
index ede6da4..0000000
--- a/debian/blogc-git-receiver.install
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/bin/blogc-git-receiver
-usr/share/man/man1/blogc-git-receiver.1
diff --git a/debian/blogc-make.install b/debian/blogc-make.install
deleted file mode 100644
index 44c459a..0000000
--- a/debian/blogc-make.install
+++ /dev/null
@@ -1,3 +0,0 @@
-usr/bin/blogc-make
-usr/share/man/man1/blogc-make.1
-usr/share/man/man5/blogcfile.5
diff --git a/debian/blogc-runserver.install b/debian/blogc-runserver.install
deleted file mode 100644
index debadc7..0000000
--- a/debian/blogc-runserver.install
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/bin/blogc-runserver
-usr/share/man/man1/blogc-runserver.1
diff --git a/debian/blogc.install b/debian/blogc.install
deleted file mode 100644
index edb9ae3..0000000
--- a/debian/blogc.install
+++ /dev/null
@@ -1,6 +0,0 @@
-usr/bin/blogc
-usr/share/man/man1/blogc.1
-usr/share/man/man7/blogc-pagination.7
-usr/share/man/man7/blogc-source.7
-usr/share/man/man7/blogc-template.7
-usr/share/man/man7/blogc-toctree.7
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644
index d9ed199..0000000
--- a/debian/changelog
+++ /dev/null
@@ -1,5 +0,0 @@
-blogc (0.20.1-1~0upstream) unstable; urgency=medium
-
- * Upstream Release
-
- -- Rafael G. Martins <rafael@rafaelmartins.eng.br> Sat, 02 Jan 2021 19:38:56 +0100
diff --git a/debian/control b/debian/control
deleted file mode 100644
index 741da73..0000000
--- a/debian/control
+++ /dev/null
@@ -1,41 +0,0 @@
-Source: blogc
-Section: text
-Priority: optional
-Maintainer: Rafael G. Martins <rafael@rafaelmartins.eng.br>
-Build-Depends: debhelper-compat (= 12),
- git,
- libcmocka-dev,
- pkg-config
-Standards-Version: 4.5.1
-Homepage: https://blogc.rgm.io/
-Vcs-Browser: https://github.com/blogc/blogc
-Vcs-Git: https://github.com/blogc/blogc.git
-Rules-Requires-Root: no
-
-Package: blogc
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}
-Description: Blog compiler
- Main binary
-
-Package: blogc-git-receiver
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends},
- git,
- make
-Description: Blog compiler
- Simple login shell/git hook to deploy blogc websites
-
-Package: blogc-make
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends},
- blogc,
- blogc-runserver
-Description: Blog compiler
- Simple build tool for blogc
-
-Package: blogc-runserver
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}
-Description: Blog compiler
- Simple HTTP server to test blogc websites
diff --git a/debian/copyright b/debian/copyright
deleted file mode 100644
index 2880381..0000000
--- a/debian/copyright
+++ /dev/null
@@ -1,61 +0,0 @@
-Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
-Upstream-Name: blogc
-Upstream-Contact: Rafael G. Martins <rafael@rafaelmartins.eng.br>
-Source: https://github.com/blogc/blogc
-
-Files: *
-Copyright: 2014-2020, Rafael G. Martins <rafael@rafaelmartins.eng.br>
-License: BSD-3-Clause
-
-Files: debian/*
-Copyright: 2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
-License: BSD-3-Clause
-
-Files: src/common/utf8.c
-Copyright: 2008-2010 Bjoern Hoehrmann <bjoern@hoehrmann.de>
- 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
-License: MIT
-
-License: BSD-3-Clause
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
- .
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-License: MIT
- Permission is hereby granted, free of charge, to any person obtaining a
- copy of this software and associated documentation files (the "Software"),
- to deal in the Software without restriction, including without limitation
- the rights to use, copy, modify, merge, publish, distribute, sublicense,
- and/or sell copies of the Software, and to permit persons to whom the
- Software is furnished to do so, subject to the following conditions:
- .
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- .
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/debian/rules b/debian/rules
deleted file mode 100755
index 6a1a185..0000000
--- a/debian/rules
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/make -f
-
-#export DH_VERBOSE = 1
-export DEB_BUILD_MAINT_OPTIONS = hardening=+all optimize=-lto
-export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
-export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
-
-%:
- dh $@
-
-override_dh_auto_configure:
- dh_auto_configure -- \
- --disable-ronn \
- --enable-git-receiver \
- --enable-make \
- --enable-runserver
diff --git a/debian/source/format b/debian/source/format
deleted file mode 100644
index 163aaf8..0000000
--- a/debian/source/format
+++ /dev/null
@@ -1 +0,0 @@
-3.0 (quilt)
diff --git a/m4/ax_pthread.m4 b/m4/ax_pthread.m4
deleted file mode 100644
index 4c4051e..0000000
--- a/m4/ax_pthread.m4
+++ /dev/null
@@ -1,485 +0,0 @@
-# ===========================================================================
-# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
-# ===========================================================================
-#
-# SYNOPSIS
-#
-# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
-#
-# DESCRIPTION
-#
-# This macro figures out how to build C programs using POSIX threads. It
-# sets the PTHREAD_LIBS output variable to the threads library and linker
-# flags, and the PTHREAD_CFLAGS output variable to any special C compiler
-# flags that are needed. (The user can also force certain compiler
-# flags/libs to be tested by setting these environment variables.)
-#
-# Also sets PTHREAD_CC to any special C compiler that is needed for
-# multi-threaded programs (defaults to the value of CC otherwise). (This
-# is necessary on AIX to use the special cc_r compiler alias.)
-#
-# NOTE: You are assumed to not only compile your program with these flags,
-# but also to link with them as well. For example, you might link with
-# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
-#
-# If you are only building threaded programs, you may wish to use these
-# variables in your default LIBS, CFLAGS, and CC:
-#
-# LIBS="$PTHREAD_LIBS $LIBS"
-# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-# CC="$PTHREAD_CC"
-#
-# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
-# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to
-# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
-#
-# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
-# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
-# PTHREAD_CFLAGS.
-#
-# ACTION-IF-FOUND is a list of shell commands to run if a threads library
-# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
-# is not found. If ACTION-IF-FOUND is not specified, the default action
-# will define HAVE_PTHREAD.
-#
-# Please let the authors know if this macro fails on any platform, or if
-# you have any other suggestions or comments. This macro was based on work
-# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
-# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
-# Alejandro Forero Cuervo to the autoconf macro repository. We are also
-# grateful for the helpful feedback of numerous users.
-#
-# Updated for Autoconf 2.68 by Daniel Richard G.
-#
-# LICENSE
-#
-# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
-# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
-#
-# 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 <http://www.gnu.org/licenses/>.
-#
-# As a special exception, the respective Autoconf Macro's copyright owner
-# gives unlimited permission to copy, distribute and modify the configure
-# scripts that are the output of Autoconf when processing the Macro. You
-# need not follow the terms of the GNU General Public License when using
-# or distributing such scripts, even though portions of the text of the
-# Macro appear in them. The GNU General Public License (GPL) does govern
-# all other use of the material that constitutes the Autoconf Macro.
-#
-# This special exception to the GPL applies to versions of the Autoconf
-# Macro released by the Autoconf Archive. When you make and distribute a
-# modified version of the Autoconf Macro, you may extend this special
-# exception to the GPL to apply to your modified version as well.
-
-#serial 23
-
-AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
-AC_DEFUN([AX_PTHREAD], [
-AC_REQUIRE([AC_CANONICAL_HOST])
-AC_REQUIRE([AC_PROG_CC])
-AC_REQUIRE([AC_PROG_SED])
-AC_LANG_PUSH([C])
-ax_pthread_ok=no
-
-# We used to check for pthread.h first, but this fails if pthread.h
-# requires special compiler flags (e.g. on Tru64 or Sequent).
-# It gets checked for in the link test anyway.
-
-# First of all, check if the user has set any of the PTHREAD_LIBS,
-# etcetera environment variables, and if threads linking works using
-# them:
-if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
- ax_pthread_save_CC="$CC"
- ax_pthread_save_CFLAGS="$CFLAGS"
- ax_pthread_save_LIBS="$LIBS"
- AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"])
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
- LIBS="$PTHREAD_LIBS $LIBS"
- AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS])
- AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes])
- AC_MSG_RESULT([$ax_pthread_ok])
- if test "x$ax_pthread_ok" = "xno"; then
- PTHREAD_LIBS=""
- PTHREAD_CFLAGS=""
- fi
- CC="$ax_pthread_save_CC"
- CFLAGS="$ax_pthread_save_CFLAGS"
- LIBS="$ax_pthread_save_LIBS"
-fi
-
-# We must check for the threads library under a number of different
-# names; the ordering is very important because some systems
-# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
-# libraries is broken (non-POSIX).
-
-# Create a list of thread flags to try. Items starting with a "-" are
-# C compiler flags, and other items are library names, except for "none"
-# which indicates that we try without any flags at all, and "pthread-config"
-# which is a program returning the flags for the Pth emulation library.
-
-ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
-
-# The ordering *is* (sometimes) important. Some notes on the
-# individual items follow:
-
-# pthreads: AIX (must check this before -lpthread)
-# none: in case threads are in libc; should be tried before -Kthread and
-# other compiler flags to prevent continual compiler warnings
-# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
-# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
-# (Note: HP C rejects this with "bad form for `-t' option")
-# -pthreads: Solaris/gcc (Note: HP C also rejects)
-# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
-# doesn't hurt to check since this sometimes defines pthreads and
-# -D_REENTRANT too), HP C (must be checked before -lpthread, which
-# is present but should not be used directly; and before -mthreads,
-# because the compiler interprets this as "-mt" + "-hreads")
-# -mthreads: Mingw32/gcc, Lynx/gcc
-# pthread: Linux, etcetera
-# --thread-safe: KAI C++
-# pthread-config: use pthread-config program (for GNU Pth library)
-
-case $host_os in
-
- freebsd*)
-
- # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
- # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
-
- ax_pthread_flags="-kthread lthread $ax_pthread_flags"
- ;;
-
- hpux*)
-
- # From the cc(1) man page: "[-mt] Sets various -D flags to enable
- # multi-threading and also sets -lpthread."
-
- ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
- ;;
-
- openedition*)
-
- # IBM z/OS requires a feature-test macro to be defined in order to
- # enable POSIX threads at all, so give the user a hint if this is
- # not set. (We don't define these ourselves, as they can affect
- # other portions of the system API in unpredictable ways.)
-
- AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING],
- [
-# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
- AX_PTHREAD_ZOS_MISSING
-# endif
- ],
- [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])])
- ;;
-
- solaris*)
-
- # On Solaris (at least, for some versions), libc contains stubbed
- # (non-functional) versions of the pthreads routines, so link-based
- # tests will erroneously succeed. (N.B.: The stubs are missing
- # pthread_cleanup_push, or rather a function called by this macro,
- # so we could check for that, but who knows whether they'll stub
- # that too in a future libc.) So we'll check first for the
- # standard Solaris way of linking pthreads (-mt -lpthread).
-
- ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags"
- ;;
-esac
-
-# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
-
-AS_IF([test "x$GCC" = "xyes"],
- [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"])
-
-# The presence of a feature test macro requesting re-entrant function
-# definitions is, on some systems, a strong hint that pthreads support is
-# correctly enabled
-
-case $host_os in
- darwin* | hpux* | linux* | osf* | solaris*)
- ax_pthread_check_macro="_REENTRANT"
- ;;
-
- aix*)
- ax_pthread_check_macro="_THREAD_SAFE"
- ;;
-
- *)
- ax_pthread_check_macro="--"
- ;;
-esac
-AS_IF([test "x$ax_pthread_check_macro" = "x--"],
- [ax_pthread_check_cond=0],
- [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"])
-
-# Are we compiling with Clang?
-
-AC_CACHE_CHECK([whether $CC is Clang],
- [ax_cv_PTHREAD_CLANG],
- [ax_cv_PTHREAD_CLANG=no
- # Note that Autoconf sets GCC=yes for Clang as well as GCC
- if test "x$GCC" = "xyes"; then
- AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
- [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
-# if defined(__clang__) && defined(__llvm__)
- AX_PTHREAD_CC_IS_CLANG
-# endif
- ],
- [ax_cv_PTHREAD_CLANG=yes])
- fi
- ])
-ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
-
-ax_pthread_clang_warning=no
-
-# Clang needs special handling, because older versions handle the -pthread
-# option in a rather... idiosyncratic way
-
-if test "x$ax_pthread_clang" = "xyes"; then
-
- # Clang takes -pthread; it has never supported any other flag
-
- # (Note 1: This will need to be revisited if a system that Clang
- # supports has POSIX threads in a separate library. This tends not
- # to be the way of modern systems, but it's conceivable.)
-
- # (Note 2: On some systems, notably Darwin, -pthread is not needed
- # to get POSIX threads support; the API is always present and
- # active. We could reasonably leave PTHREAD_CFLAGS empty. But
- # -pthread does define _REENTRANT, and while the Darwin headers
- # ignore this macro, third-party headers might not.)
-
- PTHREAD_CFLAGS="-pthread"
- PTHREAD_LIBS=
-
- ax_pthread_ok=yes
-
- # However, older versions of Clang make a point of warning the user
- # that, in an invocation where only linking and no compilation is
- # taking place, the -pthread option has no effect ("argument unused
- # during compilation"). They expect -pthread to be passed in only
- # when source code is being compiled.
- #
- # Problem is, this is at odds with the way Automake and most other
- # C build frameworks function, which is that the same flags used in
- # compilation (CFLAGS) are also used in linking. Many systems
- # supported by AX_PTHREAD require exactly this for POSIX threads
- # support, and in fact it is often not straightforward to specify a
- # flag that is used only in the compilation phase and not in
- # linking. Such a scenario is extremely rare in practice.
- #
- # Even though use of the -pthread flag in linking would only print
- # a warning, this can be a nuisance for well-run software projects
- # that build with -Werror. So if the active version of Clang has
- # this misfeature, we search for an option to squash it.
-
- AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread],
- [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG],
- [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
- # Create an alternate version of $ac_link that compiles and
- # links in two steps (.c -> .o, .o -> exe) instead of one
- # (.c -> exe), because the warning occurs only in the second
- # step
- ax_pthread_save_ac_link="$ac_link"
- ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
- ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"`
- ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
- ax_pthread_save_CFLAGS="$CFLAGS"
- for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
- AS_IF([test "x$ax_pthread_try" = "xunknown"], [break])
- CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
- ac_link="$ax_pthread_save_ac_link"
- AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
- [ac_link="$ax_pthread_2step_ac_link"
- AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
- [break])
- ])
- done
- ac_link="$ax_pthread_save_ac_link"
- CFLAGS="$ax_pthread_save_CFLAGS"
- AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no])
- ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
- ])
-
- case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
- no | unknown) ;;
- *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
- esac
-
-fi # $ax_pthread_clang = yes
-
-if test "x$ax_pthread_ok" = "xno"; then
-for ax_pthread_try_flag in $ax_pthread_flags; do
-
- case $ax_pthread_try_flag in
- none)
- AC_MSG_CHECKING([whether pthreads work without any flags])
- ;;
-
- -mt,pthread)
- AC_MSG_CHECKING([whether pthreads work with -mt -lpthread])
- PTHREAD_CFLAGS="-mt"
- PTHREAD_LIBS="-lpthread"
- ;;
-
- -*)
- AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
- PTHREAD_CFLAGS="$ax_pthread_try_flag"
- ;;
-
- pthread-config)
- AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
- AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
- PTHREAD_CFLAGS="`pthread-config --cflags`"
- PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
- ;;
-
- *)
- AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
- PTHREAD_LIBS="-l$ax_pthread_try_flag"
- ;;
- esac
-
- ax_pthread_save_CFLAGS="$CFLAGS"
- ax_pthread_save_LIBS="$LIBS"
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
- LIBS="$PTHREAD_LIBS $LIBS"
-
- # Check for various functions. We must include pthread.h,
- # since some functions may be macros. (On the Sequent, we
- # need a special flag -Kthread to make this header compile.)
- # We check for pthread_join because it is in -lpthread on IRIX
- # while pthread_create is in libc. We check for pthread_attr_init
- # due to DEC craziness with -lpthreads. We check for
- # pthread_cleanup_push because it is one of the few pthread
- # functions on Solaris that doesn't have a non-functional libc stub.
- # We try pthread_create on general principles.
-
- AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
-# if $ax_pthread_check_cond
-# error "$ax_pthread_check_macro must be defined"
-# endif
- static void routine(void *a) { a = 0; }
- static void *start_routine(void *a) { return a; }],
- [pthread_t th; pthread_attr_t attr;
- pthread_create(&th, 0, start_routine, 0);
- pthread_join(th, 0);
- pthread_attr_init(&attr);
- pthread_cleanup_push(routine, 0);
- pthread_cleanup_pop(0) /* ; */])],
- [ax_pthread_ok=yes],
- [])
-
- CFLAGS="$ax_pthread_save_CFLAGS"
- LIBS="$ax_pthread_save_LIBS"
-
- AC_MSG_RESULT([$ax_pthread_ok])
- AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
-
- PTHREAD_LIBS=""
- PTHREAD_CFLAGS=""
-done
-fi
-
-# Various other checks:
-if test "x$ax_pthread_ok" = "xyes"; then
- ax_pthread_save_CFLAGS="$CFLAGS"
- ax_pthread_save_LIBS="$LIBS"
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
- LIBS="$PTHREAD_LIBS $LIBS"
-
- # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
- AC_CACHE_CHECK([for joinable pthread attribute],
- [ax_cv_PTHREAD_JOINABLE_ATTR],
- [ax_cv_PTHREAD_JOINABLE_ATTR=unknown
- for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
- AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
- [int attr = $ax_pthread_attr; return attr /* ; */])],
- [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break],
- [])
- done
- ])
- AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
- test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
- test "x$ax_pthread_joinable_attr_defined" != "xyes"],
- [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE],
- [$ax_cv_PTHREAD_JOINABLE_ATTR],
- [Define to necessary symbol if this constant
- uses a non-standard name on your system.])
- ax_pthread_joinable_attr_defined=yes
- ])
-
- AC_CACHE_CHECK([whether more special flags are required for pthreads],
- [ax_cv_PTHREAD_SPECIAL_FLAGS],
- [ax_cv_PTHREAD_SPECIAL_FLAGS=no
- case $host_os in
- solaris*)
- ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
- ;;
- esac
- ])
- AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
- test "x$ax_pthread_special_flags_added" != "xyes"],
- [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
- ax_pthread_special_flags_added=yes])
-
- AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
- [ax_cv_PTHREAD_PRIO_INHERIT],
- [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
- [[int i = PTHREAD_PRIO_INHERIT;]])],
- [ax_cv_PTHREAD_PRIO_INHERIT=yes],
- [ax_cv_PTHREAD_PRIO_INHERIT=no])
- ])
- AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
- test "x$ax_pthread_prio_inherit_defined" != "xyes"],
- [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])
- ax_pthread_prio_inherit_defined=yes
- ])
-
- CFLAGS="$ax_pthread_save_CFLAGS"
- LIBS="$ax_pthread_save_LIBS"
-
- # More AIX lossage: compile with *_r variant
- if test "x$GCC" != "xyes"; then
- case $host_os in
- aix*)
- AS_CASE(["x/$CC"],
- [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
- [#handle absolute path differently from PATH based program lookup
- AS_CASE(["x$CC"],
- [x/*],
- [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
- [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
- ;;
- esac
- fi
-fi
-
-test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
-
-AC_SUBST([PTHREAD_LIBS])
-AC_SUBST([PTHREAD_CFLAGS])
-AC_SUBST([PTHREAD_CC])
-
-# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
-if test "x$ax_pthread_ok" = "xyes"; then
- ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
- :
-else
- ax_pthread_ok=no
- $2
-fi
-AC_LANG_POP
-])dnl AX_PTHREAD
diff --git a/maint/README.md b/maint/README.md
deleted file mode 100644
index 27ff7d8..0000000
--- a/maint/README.md
+++ /dev/null
@@ -1,93 +0,0 @@
-# How to release a new blogc version
-
-These are some rough steps required to produce a blogc release.
-
-
-## Define version number
-
-- Read repository logs:
- ```
- $ git log v0.18.0..HEAD # replace with whatever latest release
- ```
-- Follow this criteria:
- - Only bug fixes: Bump micro version.
- - Something new: Bump minor version, set micro to `0`.
- - We have no plans to change major version so far. Keep it `0`.
-
-
-## Prepare release
-
-- Write blog post (repository is https://github.com/blogc/blogc.rgm.io/)
- ```
- $ cp content/news/blogc-0.18.0.txt content/news/blogc-0.19.0.txt # replace versions
- $ vim blogcfile # change LATEST_RELEASE, add new post file to the end of [posts]
- $ vim content/news/blogc-0.19.0.txt # write the content, based on what changed. put some placeholder DATE
- $ blogc-make runserver
- ```
-- Copy manpage sources from main repository (https://github.com/blogc/blogc):
- ```
- $ cp -r ../blogc/man/* man/
- $ make -C man
- ```
- ronn output is not idempotent. It may rewrite HTML for manpages that are unchanged. Make sure to discard these changes somehow with git.
-- Write GitHub release draft. Content is similar to blog post. No need to include lots of links. Always append this to the end of text:
- ```
- Please download the custom tarballs, not the files generated automatically by GitHub, they are garbage.
- ```
-
-
-## Bump version
-
-- Make sure that all the code is in place.
-- Edit `blogc.spec.in`. Check if dependencies and packaging are still correct.
- - If something needs update, do it. Then commit, push and wait for [CI](https://github.com/blogc/blogc/actions). After successful build, grab a `.src.rpm` from https://distfiles.rgm.io/blogc/LATEST/, upload to a test [Copr](https://copr.fedorainfracloud.org/), wait until it builds and follow also next step.
- - If everything is ok, add a changelog line to the top of the `%changelog` section.
-- Update debian version:
- - If something needs update, do it. Then commit, push and wait for [CI](https://github.com/blogc/blogc/actions).
- - Run `dch`:
- ```
- $ dch --distribution unstable --newversion 0.19.0-1~0upstream "Upstream Release"
- ```
-- Commit, push and wait for [CI](https://github.com/blogc/blogc/actions).
-- Create signed tag:
- ```
- $ git tag -s -m 'blogc-0.19.0' v0.19.0 # replace with whatever version you defined before
- ```
- This requires my (rafaelmartins) personal GPG key. If someone else needs to publish a release, please announce the new key in the blog post and GitHub release.
-- Push signed tag:
- ```
- $ git push origin v0.19.0 # replace with whatever version you defined before
- ```
-- Wait for [CI](https://github.com/blogc/blogc/actions) to build the release files and push them to https://distfiles.rgm.io/blogc/.
-
-
-## Releasing new version
-
-- Download new release files and sign them:
- ```
- $ ./download_release.py
- ```
- This requires my (rafaelmartins) personal GPG key to sign files. If someone else needs to publish a release, please edit the script to add new GPG key and announce it in the blog post and GitHub release.
-- Grab files from `releases/0.19.0` (replace version) and upload to GitHub release draft, including `.asc` files. The `.src.rpm` and tarballs with debs can be omited.
-- Publish release on GitHub.
-- Fix blog post DATE, commit and push.
-
-
-## Maintain downstream packages
-- Upload `.src.rpm` file to the [official Copr](https://copr.fedorainfracloud.org/coprs/rafaelmartins/blogc/). The Copr is owned by rafaelmartins, there's no concept of organizations. I believe that an user could request publish access here: https://copr.fedorainfracloud.org/coprs/rafaelmartins/blogc/permissions/
-- Prepare and submit [termux-packages](https://github.com/termux/termux-packages) pull request.
- - Edit `packages/blogc/build.sh`. Update version.
- - Try to build package (it will fail):
- ```
- $ ./scripts/run-docker.sh ./build-package.sh blogc
- ```
- - Get new SHA256 hash from last command and update `packages/blogc/build.sh`.
- - Build package:
- ```
- $ ./scripts/run-docker.sh ./build-package.sh blogc
- ```
- - If everything builds fine, commit and create pull request.
-
-## Celebrate
-
- \o/
diff --git a/maint/download_release.py b/maint/download_release.py
deleted file mode 100755
index 6618972..0000000
--- a/maint/download_release.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python3
-# coding: utf-8
-
-import os
-import re
-import requests
-import shutil
-import subprocess
-import sys
-
-re_version = re.compile(r'blogc-([^\'"]+)\.tar\.gz')
-re_distfile = re.compile(r'(blogc[^\'"]+)\.sha512')
-base_url = 'https://distfiles.rgm.io/blogc'
-cwd = os.path.dirname(os.path.abspath(__file__))
-gpg_key = '0x47B8CCD75DBE6358'
-
-
-def download_release(version):
- if version is None:
- release_url = '%s/LATEST' % (base_url,)
- r = requests.get(release_url)
- r.raise_for_status()
- match = re_version.search(r.text)
- if match is None:
- raise RuntimeError('Could not guess version')
- version = match.group(1)
- else:
- release_url = '%s/blogc-%s' % (base_url, version)
- r = requests.get(release_url)
- r.raise_for_status()
-
- dest_path = os.path.join(cwd, 'releases', version)
- if os.path.exists(dest_path):
- shutil.rmtree(dest_path)
- os.makedirs(dest_path)
-
- for distfile in set(re_distfile.findall(r.text)):
- file_url = '%s/%s' % (release_url, distfile)
- subprocess.check_call(['wget', '-P', dest_path, file_url,
- '%s.sha512' % file_url])
- subprocess.check_call(['sha512sum', '-c', '%s.sha512' % distfile],
- cwd=dest_path)
- subprocess.check_call(['gpg', '--local-user', gpg_key, '--detach-sign',
- '--armor', distfile],
- cwd=dest_path)
-
-
-if __name__ == '__main__':
- download_release(sys.argv[1] if len(sys.argv) > 1 else None)
diff --git a/man/blogc-git-receiver.1.ronn b/man/blogc-git-receiver.1.ronn
index 3aac9f2..dc35621 100644
--- a/man/blogc-git-receiver.1.ronn
+++ b/man/blogc-git-receiver.1.ronn
@@ -12,13 +12,13 @@ When used as a login shell, it will accept git payloads, creating bare repositor
as needed, and installing a hook, that will take care of rebuilding the website each
time someone push something to the `master` branch.
-The git repository must provide a blogcfile(5) (if blogc-make(1) is installed), or
-a `Makefile` (or a `GNUMakefile`) that should accept the `OUTPUT_DIR` variable, and
-install built files into the directory pointed out by this variable.
+The git repository must provide a `Makefile` (or a `GNUMakefile`), that should
+accept the `OUTPUT_DIR` variable, and install built files in the directory pointed
+by this variable.
-`blogc-git-receiver` is part of `blogc` project, but isn't tied to blogc(1) or
-blogc-make(1). Any repository with `Makefile` that builds content and install it to
-`OUTPUT_DIR` should work with `blogc-git-receiver`.
+`blogc-git-receiver` is part of `blogc` project, but isn't tied to blogc(1). Any
+repository with `Makefile` that builds content and install it to `OUTPUT_DIR`
+should works with `blogc-git-receiver`.
## SETUP
@@ -29,12 +29,7 @@ blogc-git-receiver(1):
Now add ssh keys to `/home/blogc/.ssh/authorized_keys`. Every key in
`authorized_keys` will be allowed to push to the git repositories, and even
-create new ones. It is also possible to add `blogc-git-receiver` as a command in
-the `authorized_keys` file for each key, but this setup is slightly more tricky,
-as you may leak shell access to an user by mystake, if you forget to add the command
-to a key that should not have shell access. Only use this method if you don't have
-another option (e.g. in shared hosting environments that only provide one shell
-account), or if you know exactly what you are doing.
+create new ones.
Also, make sure to install all the dependencies required by the websites,
including a web server. `blogc-git-receiver` can't handle web server virtual hosts.
@@ -48,27 +43,7 @@ To deploy a website (e.g. blogc example repository):
This will deploy the example to the server, creating a symlink to the built content
in `/home/blogc/repos/blogs/blogc-example.git/htdocs`. This symlink should be used
-as the document root for the web server virtual host. If this symlink can't be
-readed by your webserver for some reason, you can create it in some other directory
-by adding the full symlink path to the ~/blogc-git-receiver.ini configuration file:
-
- $ $EDITOR ~/blogc-git-receiver.ini
- [repo:blogs/blogc-example.git]
- symlink=/path/to/my/symlink
-
-Do not duplicate the section if it already exists, just append the symlink path to
-it.
-
-### Rebuild last successful build
-
-If for some reason you want to rebuild the last successful build of a given website,
-you can run its `pre-receive` hook manually in the server:
-
- # su -s /bin/sh - blogc
- $ cd ~/repos/blogs/blogc-example.git
- $ ./hooks/pre-receive
-
-This should re-run the last build as if it was pushed to git.
+as the document root for the web server virtual host.
### Setup with SELinux enabled (Fedora)
@@ -88,7 +63,9 @@ After running these commands, the machine is ready to be used.
## REPOSITORY MIRRORING
Users can rely on `blogc-git-receiver` to mirror repositories to a remote Git
-repository (e.g. a free Bitbucket private repository).
+repository (e.g. a free Bitbucket private repository). This feature just requires
+adding a remote called `mirror` to the bare repository in the server. If such remote
+exists, `blogc-git-receiver` will `git push --mirror` to it.
Please note that the `blogc` user must be able to push to the remote repository, and
that any content manually pushed to the remote repository is overwritten by
@@ -106,29 +83,14 @@ means that if an error happens when mirroring the repository, the deploy will st
succeed. Users should pay attention to the git hook logs, to avoid losing data
due to repositories not being mirrored.
-This feature just requires adding a remote called `mirror` to the bare repository
-in the server, or creating a configuration file (~/blogc-git-receiver.ini), that is
-a simple INI-style file where each repository is represented by a section and the
-value of the `mirror` variable is the URL that should be used to push.
-
-Edit configuration file (recommended, do not duplicate the section if it already
-exists, just append the mirror to it):
-
- # su -s /bin/sh - blogc
- $ $EDITOR ~/blogc-git-receiver.ini
- [repo:myblog.git]
- mirror=$YOUR_GIT_MIRROR_URL
-
-Or to add the `mirror` remote:
+To add the `mirror` remote:
- # su -s /bin/sh - blogc
+ # su -s /bin/bash - blogc
$ cd repos
$ git init --bare myblog.git # if not created yet
$ cd myblog.git
$ git remote add --mirror=push mirror $YOUR_GIT_MIRROR_URL
-Both examples assume that your repository is named `myblog.git`.
-
### Caveats of repository mirroring with SSH
The authentication must be done with a password-less SSH key created by the `blogc`
@@ -142,49 +104,17 @@ checking in SSH's `~/.ssh/config` file:
The example uses `bitbucket.org` as remote host, that should be changed if needed.
-To change this file, users must login with `/bin/sh` or any other "real" shell,
+To change this file, users must login with `/bin/bash` or any other "real" shell,
as `root`:
- # su -s /bin/sh - blogc
-
-### Push to mirror manually
-
-If for some reason you want to push the repository of a given website to remote
-mirror, you can run its `post-receive` hook manually in the server:
-
- # su -s /bin/sh - blogc
- $ cd ~/repos/blogs/blogc-example.git
- $ ./hooks/post-receive
-
-WARNING: If you push manually and your server's repository is empty, you'll clean
-your mirror repository.
-
-## ENVIRONMENT
-
-The following variables can be set in the SSH Server (usually in `~/.ssh/environment`)
-to change `blogc-git-receiver` behaviour:
-
- * `BLOGC_GIT_RECEIVER_BASE_DIR`:
- Path to the base directory that should be used by `blogc-git-receiver`. Defaults
- to user's home directory. Useful for shared hosting environments that only provide
- one shell user.
- * `BLOGC_GIT_RECEIVER_BUILDS_DIR`:
- Path to the directory that should be used to store the blogc builds. Defaults
- to `$BLOGC_GIT_RECEIVER_BASE_DIR/builds`. This directory must be readable by
- your webserver. This variable is useful to keep your git repositories unreadable,
- while letting your webserver access the built files. In this case, users need to
- also define custom symlinks for every repository in
- `$BLOGC_GIT_RECEIVER_BASE_DIR/blogc-git-receiver.ini`, because the default
- `htdocs` symlink inside the git repositories won't be acessible by the webserver.
+ # su -s /bin/bash - blogc
-The following variable is exported by `blogc-git-receiver` when building websites
-with make(1):
+## ENVIRONMENT VARIABLES
- * `BLOGC_GIT_RECEIVER=1`:
- This variable can be used to enable building of content that should only be
- built when running in production environment, for example. This variable will
- not be exported when using blogc-make(1), whose builds are always considered to
- be "production" (blogc-make(1) is never called with `-D`).
+`blogc-git-receiver` will export an environment variable called `BLOGC_GIT_RECEIVER`
+when calling `gmake` to build websites. This variable can be used to enable building
+of content that should only be built when running in production environment, for
+example.
## BUGS
@@ -196,4 +126,4 @@ Rafael G. Martins &lt;<rafael@rafaelmartins.eng.br>&gt;
## SEE ALSO
-blogc(1), git(1), git-shell(1), chsh(1), su(1), make(1)
+blogc(1), git(7), chsh(1), su(1), make(1)
diff --git a/man/blogc-make.1.ronn b/man/blogc-make.1.ronn
deleted file mode 100644
index d44b685..0000000
--- a/man/blogc-make.1.ronn
+++ /dev/null
@@ -1,219 +0,0 @@
-blogc-make(1) -- a simple build tool for blogc
-==============================================
-
-## SYNOPSIS
-
-`blogc-make` [`-V`] [`-f` <FILE>] [<RULE> ...]<br>
-`blogc-make` [`-h`|`-v`]
-
-## DESCRIPTION
-
-**blogc-make** is a simple build tool for blogc websites. It reads a blogcfile(5)
-and generates the output files using blogc(1) and some predefined rules, that are
-useful enough for most common use cases.
-
-See blogcfile(5) for details on the file format.
-
-## OPTIONS
-
- * `-D`:
- Builds for development environment. This option is useful to load local,
- non-optimized assets for development purposes. It adds two global
- variables to all blogc(1) calls: `MAKE_ENV_DEV=1` and `MAKE_ENV=dev`.
-
- * `-V`:
- Activates verbose mode, that will give more details of commands runs.
-
- * `-f` <FILE>:
- Reads <FILE> as `blogcfile`.
-
- * `-v`:
- Show program name, version and exit.
-
- * `-h`:
- Show help message and exit.
-
-## HELPER RULES
-
-### all
-
-Run all build rules. This is the default rule.
-
-### clean
-
-Clean built files and empty directories in output directory.
-
-### runserver
-
-Run `blogc-runserver(1)` (if available) pointing to output directory, watching
-for changes in the source files and rebuilding as needed. This rule accepts
-some arguments, in the following format:
-
- runserver:host=127.0.0.1,port=8080,threads=20
-
-The values in the example are the default values. Rebuilds are done by running
-`blogc-make all` internally.
-
-### watch
-
-Watch for changes in the source files, rebuilding as needed.
-
-Rebuilds are done by running `blogc-make all` internally.
-
-### atom_dump
-
-Dump default Atom feed template based on current blogcfile(5) settings.
-
-The template is dumped to the standard output, and can be used as base
-for customized Atom feed templates.
-
-## BUILD RULES
-
-### index
-
-Build website index from posts.
-
-The rule passes the following helper variables to blogc(1):
-
- * `MAKE_RULE`:
- `index`
- * `MAKE_TYPE`:
- `post`
-
-### atom
-
-Build main atom feed from posts.
-
-The rule passes the following helper variables to blogc(1):
-
- * `MAKE_RULE`:
- `atom`
- * `MAKE_TYPE`:
- `atom`
-
-### atom_tags
-
-Build atom feeds for each tag from posts.
-
-The rule passes the following helper variables to blogc(1):
-
- * `MAKE_RULE`:
- `atom_tags`
- * `MAKE_TYPE`:
- `atom`
-
-### pagination
-
-Build pagination pages from posts. This rule is disabled if `posts_per_page`
-value in blogcfile(5) is negative or `0`.
-
-The rule passes the following helper variables to blogc(1):
-
- * `MAKE_RULE`:
- `pagination`
- * `MAKE_TYPE`:
- `post`
-
-### pagination_tags
-
-Build pagination pages for each tag from posts. This rule is disabled if
-`posts_per_page` value in blogcfile(5) is negative or `0`.
-
-The rule passes the following helper variables to blogc(1):
-
- * `MAKE_RULE`:
- `pagination_tags`
- * `MAKE_TYPE`:
- `post`
-
-### posts
-
-Build individual pages for each post.
-
-The rule passes the following helper variables to blogc(1):
-
- * `MAKE_RULE`:
- `posts`
- * `MAKE_TYPE`:
- `post`
- * `MAKE_SLUG`:
- The slug of the post being built, as provided in blogcfile
-
-### tags
-
-Build post listings for each tag from posts.
-
-The rule passes the following helper variables to blogc(1):
-
- * `MAKE_RULE`:
- `tags`
- * `MAKE_TYPE`:
- `post`
-
-### pages
-
-Build individual pages for each page.
-
-The rule passes the following helper variables to blogc(1):
-
- * `MAKE_RULE`:
- `pages`
- * `MAKE_TYPE`:
- `page`
- * `MAKE_SLUG`:
- The slug of the page being built, as provided in blogcfile
-
-### copy
-
-Copy static files from source directory to output directory.
-
-## FILES
-
-The `blogc-make` command expects a settings file, called `blogcfile` by default,
-or any other file passed to `-f` option. `blogcfile` must have valid UTF-8 content.
-
-The `blogc-make` command will read any files listed on `blogcfile`, and may write
-files to the configured output directory.
-
-## ENVIRONMENT
-
- * `BLOGC`:
- Path to `blogc(1)` binary. If not provided, the `blogc` binary in `$PATH` will
- be used.
-
- * `BLOGC_RUNSERVER`:
- Path to `blogc-runserver(1)` binary. If not provided, the `blogc-runserver`
- binary in `$PATH` will be used, if available.
-
- * `OUTPUT_DIR`:
- Path to the directory where `blogc-make` should write (or instruct blogc(1) to
- write) output files.
-
-Any other environment variables are inherited by blogc(1) and blogc-runserver(1),
-when called by `blogc-make`.
-
-## EXAMPLES
-
-Build all files:
-
- $ blogc-make
-
-or
-
- $ blogc-make all
-
-Clean built files:
-
- $ blogc-make clean
-
-## BUGS
-
-Please report any issues to: <https://github.com/blogc/blogc>
-
-## AUTHOR
-
-Rafael G. Martins &lt;<rafael@rafaelmartins.eng.br>&gt;
-
-## SEE ALSO
-
-blogc(1), blogc-runserver(1), blogcfile(5)
diff --git a/man/blogc-pagination.7.ronn b/man/blogc-pagination.7.ronn
index ceb41d6..db40334 100644
--- a/man/blogc-pagination.7.ronn
+++ b/man/blogc-pagination.7.ronn
@@ -12,16 +12,14 @@ blogc(1) in the command line, no sorting is done.
blogc(1) accepts some variables as `-D` options, that are used to filter the
files passed as arguments to it:
+ * `FILTER_PER_PAGE`:
+ Integer, limits the maximum number of files to be listed.
+
* `FILTER_PAGE`:
Integer, current page. If calling blogc(1) with 10 files,
- `FILTER_PER_PAGE=4` and `FILTER_PAGE=3`, it will return just the 2 last
+ `FILTER_PER_PAGE`=4 and `FILTER_PAGE`=3, it will return just the 2 last
files, skipping the first 2 pages with 4 files each one.
- * `FILTER_PER_PAGE`:
- Integer, limits the maximum number of files to be listed. If negative or
- `0`, no posts are included. Have no effect if `FILTER_PAGE` is not
- defined.
-
* `FILTER_TAG`:
String, if defined, blogc(1) will only list files that declare a `TAGS`
variable, as a space-separated list of tags (tags can't have spaces,
@@ -29,18 +27,6 @@ files passed as arguments to it:
variables. The pagination filters will only act on the files with the
provided tag, instead of filtering the whole file set.
- * `FILTER_REVERSE`:
- Boolean (1/y/yes/true/on), if set, blogc(1) will list files in reverse order.
- This filter is combined with `FILTER_SORT`, and all the other filters will
- get the files already in the reverse order.
-
- * `FILTER_SORT`:
- Boolean (1/y/yes/true/on), if set, blogc(1) will sort files using the `DATE`
- variable provided in the files, instead of respecting the order of the
- source files provided to blogc(1). The files are sorted in descending order
- and combined with `FILTER_REVERSE`, that will result in the files sorted in
- ascending order. All the other filters will get the files already sorted.
-
## TEMPLATE VARIABLES
blogc(1) will export some global blogc-template(7) variables, that can be used
diff --git a/man/blogc-runserver.1.ronn b/man/blogc-runserver.1.ronn
index a8534f8..a306fbe 100644
--- a/man/blogc-runserver.1.ronn
+++ b/man/blogc-runserver.1.ronn
@@ -35,14 +35,6 @@ able to serve any website built by static site generators.
* <DOCROOT>:
HTTP server document root.
-## ENVIRONMENT
-
- * `BLOGC_RUNSERVER_DEFAULT_HOST`:
- Changes the default HTTP server listen address, if defined.
-
- * `BLOGC_RUNSERVER_DEFAULT_PORT`:
- Changes the default HTTP server listen port, if defined.
-
## BUGS
Please report any issues to: <https://github.com/blogc/blogc>
diff --git a/man/blogc-source.7.ronn b/man/blogc-source.7.ronn
index 56fa552..0273194 100644
--- a/man/blogc-source.7.ronn
+++ b/man/blogc-source.7.ronn
@@ -45,19 +45,13 @@ You can omit seconds, minutes and hours if you want, they will be filled with
``yyyy-mm-dd hh`` and ``yyyy-mm-dd``
The ``DATE_FORMAT`` variable should be passed to blogc(1) as a global
-variable. Its value must be a valid strftime(3) format.
+variable. Its value must be a valid strptime(3) format.
The source parser will also automatically generate a variable called `FILENAME`,
that stores the name of the source file, without its extension. This is useful
for building permalinks in templates. This variable can't be overriden by an
explicit definition in source file.
-The variable `FIRST_HEADER` is created by the source parser by default,
-containing the unparsed value of the first header found in the source file.
-The content is not parsed but HTML entities are encoded. Headers inside
-blockquotes are ignored. This variable can be overriden by an explicit
-definition in source file, that must have the HTML entities escaped manually.
-
Another variable, `DESCRIPTION`, will be automatically created by the source
parser. It contains the unparsed content of the first paragraph found in the
source file. The content is not parsed but HTML entities are encoded. Paragraphs
@@ -219,9 +213,6 @@ Code is defined with 1 or 2 '`' before and after the text.
This is inline code: `code`
This is inline code: ``code``
-The later form is particularly useful when a '`' is part of the code, because
-escaping delimiters with '\' is not possible.
-
### Images
Images are defined using the following syntax:
@@ -286,4 +277,4 @@ Rafael G. Martins &lt;<rafael@rafaelmartins.eng.br>&gt;
## SEE ALSO
-blogc(1), blogc-template(7), strftime(3)
+blogc(1), blogc-template(7), strptime(3)
diff --git a/man/blogc-template.7.ronn b/man/blogc-template.7.ronn
index 1530fb3..d010a1c 100644
--- a/man/blogc-template.7.ronn
+++ b/man/blogc-template.7.ronn
@@ -22,8 +22,7 @@ matches the requirements of the given block.
Blocks can be defined more than once, but can't be nested.
-The available blocks are: `entry`, `listing`, `listing_empty`, `listing_entry`
-and `listing_once`.
+The available blocks are: `entry`, `listing` and `listing_once`.
### entry block
@@ -57,42 +56,6 @@ This is how a `listing` block is defined:
will be included once for each entry.
{% endblock %}
-### listing_empty block
-
-This block is similar to the `listing` block, but its content is included
-only when there are no entries to be listed, either because no source files
-were provided or because there are no entries remaining after filtering (see
-blogc-pagination(7)).
-
-This is how a `listing_empty` block is defined:
-
- {% block listing_empty %}
- No entries available.
- {% endblock %}
-
-### listing_entry block
-
-This block is identical to the `entry` block, but its content is included in
-the output file only when blogc(1) is called with `-l` and `-e` <SOURCE>
-options. The variables available in the block are provided by the source
-file provided using `-e` <SOURCE> option.
-
-This is how a `listing_entry` block is defined:
-
- {% block listing_entry %}
- This content will only be included when rendering a listing, but with
- content provided by a single entry.
- {% endblock %}
-
-When multiple `listing_entry` blocks are defined, blogc(1) should be called
-with multiple `-e` <SOURCE> options. If a `listing_entry` block does not have
-a corresponding `-e` <SOURCE> option, or if its value is an empty string,
-the content of the `listing_entry` block is not included.
-
-`listing_entry` blocks inside iterator are evaluated as multiple blocks and
-also require multiple `-e` <SOURCE> options. blogc(1) won't use the same
-source for every iteration.
-
### listing_once block
The content of a `listing_once` block is included in the output file when
@@ -111,8 +74,8 @@ This is how a `listing_once` block is defined:
will be included only once.
{% endblock %}
-This is a 'real world' usage example of a `listing_once` block, supposing
-that the `TITLE` variable is defined:
+This is a 'real life' usage example of a `listing_once` block, supposing
+that each source file defines a `TITLE` variable:
{% block listing_once %}
<ul>
@@ -151,7 +114,7 @@ in the template. If user append `_FORMATTED` to the end of the variable name,
a formatter will be applied, if available for the variable name:
- Date formatter: if variable name starts with `DATE_`, it is formatted with
- a strftime(3) format, provided by `DATE_FORMAT` variable. The `DATE_FORMATTED`
+ a strptime(3) format, provided by `DATE_FORMAT` variable. The `DATE_FORMATTED`
"meta-variable" will return the formatted version of the `DATE` variable.
If `DATE_FORMAT` is not provided, the original value will be returned.
@@ -174,53 +137,6 @@ An existing variable is not overrided by the truncate syntax. That means
that if `FOO_5` variable exists, it won't be handled as a truncate
"meta-variable", and `FOO_5` variable value will be returned normally.
-## PREDEFINED TEMPLATE VARIABLES
-
-blogc(1) provides some template variables, that can be used to display some build
-metadata in your website.
-
-If some of the variables are not available in the system running the build, they
-won't be defined. It is recommended to rely on template conditionals, mainly
-`ifdef` and `ifndef` when using these variables.
-
-### Static variables
-
-These variables are always available, and are set during the blogc(1) binary
-compilation.
-
- * `BLOGC_VERSION`:
- The version of blogc(1) used to build. e.g.: `blogc 0.14.1`.
-
-### Resource usage variables
-
-It is not possible to measure the resource usage of blogc(1) until the end of
-the execution, because the rendering of these variables itself is using resources,
-and the evaluation of the used resources was already done. To get better values,
-it is recommended to use these variables only in the website footer.
-
- * `BLOGC_RUSAGE_CPU_TIME`:
- The CPU time used to build, up to the point where this variable was used for
- the first time in the template (value is cached). e.g.: `12.345ms`.
-
- * `BLOGC_RUSAGE_MEMORY`:
- The memory used to build, up to the point where this variable was used for the
- first time in the template (value is cached). e.g.: `1.234MB`.
-
-### System information variables
-
- * `BLOGC_SYSINFO_HOSTNAME`:
- The hostname of the machine where the build happened (short hostname only, not
- FQDN).
-
- * `BLOGC_SYSINFO_USERNAME`:
- The username of the user that executed the build.
-
- * `BLOGC_SYSINFO_DATETIME`:
- The GMT datetime of the build. e.g. `2019-02-10 22:00:00`.
-
- * `BLOGC_SYSINFO_INSIDE_DOCKER`:
- If built inside a docker container, this variable will be defined, with value `1`.
-
## TEMPLATE CONDITIONALS
Template conditionals are used to include content to the output, or not,
@@ -317,40 +233,16 @@ This is how a `foreach` iterator is defined in a template:
{% endforeach %}
Where `TAGS` is the variable with space-separated list of items, and `FOREACH_ITEM`
-is the variable defined by blogc(1), that will store the item for a given iteration.
+is the variable defined by blogc(1), that will store the item value for a given
+iteration.
If the value of the `TAGS` variable is "item1 item2 item3", this template is
-rendered 3 times, one for each item.
-
-It is possible to map the items to arbitrary strings by defining other variables
-following a predefined for naming schema, like:
-
- TAGS__ITEM1
-
-Where `TAGS` is the variable defined in the foreach iterator, and `ITEM1` is the
-current iteration item (the value of `FOREACH_ITEM` for the current iteration,
-converted to upper case and with special characters converted to `_`).
-
-This is how a `foreach` iterator using arbitrary string mapping is defined in a template:
-
- {% foreach TAGS %}
- <a href="/tag/{{ FOREACH_ITEM }}/">{{ FOREACH_VALUE }}</a>
- {% endforeach %}
-
-`FOREACH_VALUE` is the variable defined by blogc(1), that will store the arbitrary string
-mapped to current iteration item. This variable can be checked using `ifdef` conditionals
-(and similar) as usual:
-
- {% foreach TAGS %}
- {% ifdef FOREACH_VALUE %}
- <a href="/tag/{{ FOREACH_ITEM }}/">{{ FOREACH_VALUE }}</a>
- {% endif %}
- {% endforeach %}
+rendered 3 times, one for each item value.
-The `FOREACH_ITEM` and `FOREACH_VALUE` variables can be truncated, like:
+The `FOREACH_ITEM` variable can be truncated, like:
{% foreach TAGS %}
- <a href="/tag/{{ FOREACH_ITEM_5 }}/">{{ FOREACH_VALUE_5 }}</a>
+ <a href="/tag/{{ FOREACH_ITEM }}/">{{ FOREACH_ITEM_5 }}</a>
{% endforeach %}
## WHITESPACE CONTROL
@@ -378,4 +270,4 @@ Rafael G. Martins &lt;<rafael@rafaelmartins.eng.br>&gt;
## SEE ALSO
-blogc(1), blogc-source(7), strcmp(3), strftime(3)
+blogc(1), blogc-source(7), strcmp(3)
diff --git a/man/blogc-toctree.7.ronn b/man/blogc-toctree.7.ronn
deleted file mode 100644
index 720a4ee..0000000
--- a/man/blogc-toctree.7.ronn
+++ /dev/null
@@ -1,87 +0,0 @@
-blogc-toctree(7) -- blogc's "table of contents" tree support
-============================================================
-
-## DESCRIPTION
-
-blogc(1) generates a "table of contents" tree for every source file, out of
-its content headers, that is available for usage as a `{{ TOCTREE }}`
-template variable. The tree is composed by lists of links for the headers,
-and is usually placed right before the content, as an index.
-
-## USAGE
-
-For a source file with the following content:
-
- TITLE: Some Title
- -----------------
- # Header 1
-
- Some content.
-
- ## Header 2
-
- More content.
-
- ### Header 3
-
- Content.
-
-A template block with the following content:
-
- {% block entry %}
- {{ TOCTREE }}
- {% endblock %}
-
-Would generate output similar to this:
-
- <ul>
- <li><a href="#header-1">Header 1</a></li>
- <ul>
- <li><a href="#header-2">Header 2</a></li>
- <ul>
- <li><a href="#header-3">Header 3</a></li>
- </ul>
- </ul>
- </ul>
-
-The depth of the tree can be controlled using the `TOCTREE_MAXDEPTH` variable,
-that may be defined globally (see blogc(1)) or for each source file (see
-blogc-source(7)). Setting this variable to `0` disables the generator.
-Setting this variable to a positive number will limit the number of tree
-levels to such value. The default value is `-1`, which means no maximum depth.
-
-Please note that the depth is evaluated from the lower header level available
-in the content. This means that if a source file only have level 2 and level 3
-headers, and `TOCTREE_MAXDEPTH=1`, only headers with level 2 are included in the
-"table of contents" tree.
-
-For a source file with the following content:
-
- TITLE: Some Title
- TOCTREE_MAXDEPTH: 1
- -----------------
- ## Header 2
-
- Some content
-
- ### Header 3
-
- More content
-
-With the same template presented before, would generate output similar to this:
-
- <ul>
- <li><a href="#header-2">Header 2</a></li>
- </ul>
-
-## BUGS
-
-Please report any issues to: <https://github.com/blogc/blogc>
-
-## AUTHOR
-
-Rafael G. Martins &lt;<rafael@rafaelmartins.eng.br>&gt;
-
-## SEE ALSO
-
-blogc(1), blogc-source(7), blogc-template(7)
diff --git a/man/blogc.1.ronn b/man/blogc.1.ronn
index 11f7808..a97122b 100644
--- a/man/blogc.1.ronn
+++ b/man/blogc.1.ronn
@@ -3,21 +3,14 @@ blogc(1) -- a blog compiler
## SYNOPSIS
-`blogc` [`-d`] [`-D` <KEY>=<VALUE> ...] `-t` <TEMPLATE> [`-o` <OUTPUT>] <SOURCE><br>
-`blogc` `-l` [`-e` <SOURCE>] [`-d`] [`-D` <KEY>=<VALUE> ...] `-t` <TEMPLATE> [`-o` <OUTPUT>] [<SOURCE> ...]<br>
-`blogc` `-l` [`-e` <SOURCE>] [`-d`] [`-D` <KEY>=<VALUE> ...] `-t` <TEMPLATE> [`-o` <OUTPUT>] [<SOURCE> ...]<br>
-`blogc` `-l` [`-e` <SOURCE>] `-p` <KEY> [`-d`] [`-D` <KEY>=<VALUE> ...] [<SOURCE> ...]<br>
-`blogc` `-i` [`-d`] [`-D` <KEY>=<VALUE> ...] `-t` <TEMPLATE> [`-o` <OUTPUT>] &lt; <FILE_LIST><br>
-`blogc` `-i` `-l` [`-e` <SOURCE>] [`-d`] [`-D` <KEY>=<VALUE> ...] `-t` <TEMPLATE> [`-o` <OUTPUT>] &lt; <FILE_LIST><br>
-`blogc` `-i` `-l` [`-e` <SOURCE>] `-p` <KEY> [`-d`] [`-D` <KEY>=<VALUE> ...] &lt; <FILE_LIST><br>
-`echo` `-e` "<SOURCE>\n..." | `blogc` `-i` [`-d`] [`-D` <KEY>=<VALUE> ...] `-t` <TEMPLATE> [`-o` <OUTPUT>]<br>
-`echo` `-e` "<SOURCE>\n..." | `blogc` `-i` `-l` [`-e` <SOURCE>] [`-d`] [`-D` <KEY>=<VALUE> ...] `-t` <TEMPLATE> [`-o` <OUTPUT>]<br>
-`echo` `-e` "<SOURCE>\n..." | `blogc` `-i` `-l` [`-e` <SOURCE>] `-p` <KEY> [`-d`] [`-D` <KEY>=<VALUE> ...]<br>
+`blogc` `-d` [`-D` <KEY>=<VALUE> ...] `-t` <TEMPLATE> [`-o` <OUTPUT>] <SOURCE><br>
+`blogc` `-d` `-l` [`-D` <KEY>=<VALUE> ...] `-t` <TEMPLATE> [`-o` <OUTPUT>] [<SOURCE> ...]<br>
+`blogc` `-d` `-l` `-p` <KEY> [`-D` <KEY>=<VALUE> ...] [<SOURCE> ...]<br>
`blogc` [`-h`|`-v`]
## DESCRIPTION
-**blogc** compiles source files and templates into blog/website resources. It
+**blogc** converts source files and templates into blog/website resources. It
gets one (or more) source files and a template, and generates an output file,
based on the template and the content read from the source file(s). It was
designed to be used with make(1).
@@ -30,39 +23,20 @@ designed to be used with make(1).
page or a post.
* `listing`:
- Listing mode, second example in [SYNOPSIS][], activated when calling `blogc`
- with `-l` option. Accepts multiple source files, and allow users to iterate
- over the content of all the source files to produce listing pages, like
- indexes and feeds. By providing another source file to `blogc` with `-e`
- option, third example in [SYNOPSIS][], its content will be available for usage
- during listing, similar to the default entry mode. This is useful for users
- that want to have an index page with content and posts listing together.
- See blogc-template(7) for details.
+ Listing mode, second example in [SYNOPSIS][], activated when
+ calling `blogc` with `-l` option. Accepts multiple source files, and allow
+ users to iterate over the content of all the source files to produce listing
+ pages, like indexes and feeds.
## OPTIONS
* `-d`:
Activates debug.
- * `-i`:
- Reads list of source files from standard input. Content of standard input is
- parsed as a file where each line is a file path. Empty lines and lines
- starting with `#` are ignored. If some source files are provided to command
- line while using this option, they will be parsed **before** the files read
- from standard input.
-
* `-l`:
Activates listing mode, allowing user to provide multiple source files. See
blogc-source(7) for details.
- * `-e` <SOURCE>:
- When used together with `-l` the source file will be parsed and its content
- will be made available for usage in the templates in listing mode via
- `listing_entry` blocks. This option can be used more than once, so users can
- have more than one `listing_entry` block in the same template. Passing an
- empty string will skip the `listing_entry` block. See blogc-template(7) for
- details.
-
* `-D` <KEY>=<VALUE>:
Set global configuration parameter. <KEY> must be an ascii uppercase string,
with only letters, numbers (after the first letter) and underscores (after
@@ -71,10 +45,9 @@ designed to be used with make(1).
See blogc-template(7) for details.
* `-p` <KEY>:
- Show the value of a variable right after the source parsing and exits. This
- is useful to get parameters for your `Makefile`, like the last page when
- implementing pagination, see blogc-pagination(7) for details. This option can
- also dump variables defined in a source file, if called without `-l`.
+ Show the value of a global configuration parameter right after the source
+ parsing and exits. This is useful to get parameters for your `Makefile`,
+ like the last page when using pagination, see blogc-pagination(7) for details.
* `-t` <TEMPLATE>:
Template file. It is a required option, if `blogc` needs to render something.
@@ -100,7 +73,7 @@ files must have valid UTF-8 content.
No environment variables are required by `blogc`, but global timezone will
be used by locale-dependant datetime input field descriptors (like `%c`), and
-can be overridden using environment variables. See strftime(3).
+can be overridden using environment variables. See strptime(3).
## EXAMPLES
@@ -108,10 +81,6 @@ Build index from source files:
$ blogc -l -t template.tmpl -o index.html source1.txt source2.txt source3.txt
-Build index from source files, with additional content from `index.txt`:
-
- $ blogc -l -e index.txt -t template.tmpl -o index.html source1.txt source2.txt source3.txt
-
Build entry page from source file:
$ blogc -t template.tmpl -o entry.html entry.txt
@@ -128,4 +97,4 @@ Rafael G. Martins &lt;<rafael@rafaelmartins.eng.br>&gt;
## SEE ALSO
-blogc-source(7), blogc-template(7), blogc-pagination(7) make(1), strftime(3)
+blogc-source(7), blogc-template(7), blogc-pagination(7) make(1), strptime(3)
diff --git a/man/blogcfile.5.ronn b/man/blogcfile.5.ronn
deleted file mode 100644
index 3d4f482..0000000
--- a/man/blogcfile.5.ronn
+++ /dev/null
@@ -1,207 +0,0 @@
-blogcfile(5) -- blogc-make's configuration file
-===============================================
-
-## DESCRIPTION
-
-**blogcfile** is the configuration file for blogc-make(1), that is a simple
-build tool for blogc(1). It is an INI-style file, with some predefined
-sections, that will provide the data required by blogc-make(1) rules to
-build websites.
-
-**blogcfile** must be valid UTF-8.
-
-## OPTIONS
-
-### Global variables
-
-The `[global]` section contains all the blogc(1) variables that should be
-passed to all blogc(1) calls.
-
-The following variables are required and should be always provided:
-
- * `AUTHOR_NAME`:
- The name of the website main author.
-
- * `AUTHOR_EMAIL`:
- The email of the website main author.
-
- * `BASE_DOMAIN`:
- The base domain of the website.
-
- * `SITE_TITLE`:
- The website title.
-
- * `SITE_TAGLINE`:
- The website tagline.
-
-### Settings
-
-blogc-make(1) relies on a predefined set of rules to build the websites,
-however these rules can be customized with the following settings, from the
-`[settings]` section:
-
- * `atom_ext` (default: `.xml`):
- The extension of the generated Atom feeds.
-
- * `atom_order` (default: `DESC`):
- The ordering (`ASC` or `DESC`) of the Atom feeds. Please note that the files
- are not sorted by date, they are sorted by their order in the `[posts]`
- section.
-
- * `atom_posts_per_page` (default: `10`):
- Number of posts per page in the Atom feeds. If negative, all the posts are
- included. If `0`, no Atom feeds are generated.
-
- * `atom_prefix` (default: `atom`):
- The prefix of the generated Atom feeds. It is relative to the output
- directory. With the default values of the settings, the main Atom feed will
- be `atom.xml`, the Atom feed for the `foo` tag will be `atom/foo.xml` and so
- on.
-
- * `atom_template` (default: internal template)
- The template file that should be used when building Atom feeds. This file
- is relative to `template_dir`. If not provided, an internal default template
- will be used instead. The internal template can be dumped using the `atom_dump`
- blogc-make(1) rule.
-
- * `content_dir` (default: `content`):
- The directory that stores the source files. This directory is relative
- to `blogcfile`.
-
- * `date_format` (default: `%b %d, %Y, %I:%M %p GMT`):
- The strftime(3) format that should be used when formating dates. Please note
- that the times are always handled as UTC/GMT.
-
- * `html_ext` (default: `/index.html`):
- The extension of the generated HTML files. The default value will result on
- friendly URL, by creating directories with `index.html` files inside, instead
- of creating the HTML file directly. The `index` page is a special case:
- instead of generating something like `/index/index.html`, it will generate
- `/index.html`, because this is behavior that most users would expect.
-
- * `html_order` (default: `DESC`):
- The ordering (`ASC` or `DESC`) of the posts in the listing indexes.
- Please note that the files are not sorted by date, they are sorted by
- their order in the `[posts]` section.
-
- * `index_prefix` (default: unset):
- The prefix of the index HTML page, that is the listing of blog posts. This
- option is useful if the user wants to host a page in the root of the website,
- and move the posts listing index to a subdirectory.
-
- * `listing_entry` (default: unset):
- The page that will be included in the listing pages of the website, without
- the page prefix and without the extension, only the "slug" should be used.
- See blogc(1) and the description of `listing_entry` block in blogc-template(7)
- for details.
-
- * `locale` (default: unset):
- The locale to be used when calling blogc(1). E.g. `en_US.UTF-8`.
-
- * `main_template` (default: `main.tmpl`):
- The template file that should be used when building HTML files. This file
- is relative to `template_dir`.
-
- * `pagination_prefix` (default: `page`):
- The prefix of the generated pagination pages. It is relative to the
- output directory.
-
- * `post_prefix` (default: `post`):
- The prefix of the posts file names. It is used for both content and output
- directories, and is relative to `content_dir` and the output directory.
-
- * `posts_per_page` (default: `10`):
- Number of posts per page in the pagination pages. If negative, all the posts
- are included. If `0`, no post listing pages are generated. Also, if negative or
- `0`, the `pagination` build rule is disabled.
-
- * `posts_sort` (default: `false`):
- If true, blogc(1) will sort the posts by date, despite the order of the posts
- in the `[posts]` section, in descending order. This setting is compatible with
- `html_order` and `atom_order` settings, to control the order of the posts.
-
- * `source_ext` (default: `.txt`):
- The extension of the source files.
-
- * `tag_prefix` (default: `tag`):
- The prefix of the generated tag listing index pages. It is relative to the
- output directory.
-
- * `template_dir` (default: `templates`):
- The directory that stores the template files. This directory is relative
- to `blogcfile`.
-
-### Posts listing
-
-The `[posts]` section is a listing of the posts that will be included in the
-website. They should be listed without the post prefix and without the extension,
-only the "slugs" should be used. For example, with default settings, if the source
-of the post is `content/post/foo.txt`, the line added to the `[posts]` section
-is `foo`.
-
-All the posts are relative to the `post_prefix` in the root of the website.
-
-### Pages listing
-
-The `[pages]` section is a listing of the pages that will be included in the
-website. They should be listed without the page prefix and without the extension,
-only the "slugs" should be used. For example, with default settings, if the source
-of the page is `content/foo.txt`, the line added to the `[pages]` section is `foo`.
-
-All the pages are relative to the root of the website.
-
-### Tags listing
-
-The `[tags]` section is a listing of the tags that should be listed in the
-website. blogc-make(1) will generate post listing indexes and Atom feeds for
-each tag listed in the section.
-
-The tags will be also provided to blogc as a `MAKE_TAGS` variable, that is a
-space-separated list of the tags, useful to generate tag clouds using the
-`foreach` template iterator. See blogc-template(7).
-
-### Copy listing
-
-The `[copy]` section is a listing of the files that should be copied to the
-output directory.
-
-All the files are relative to the `blogcfile`, and their directory structure
-will be built inside the output directory.
-
-## EXAMPLE
-
- [global]
- AUTHOR_NAME = Author
- AUTHOR_EMAIL = author@example.org
- SITE_TITLE = Site Title
- SITE_TAGLINE = Site Tagline
- BASE_DOMAIN = http://example.org
-
- [settings]
- locale = en_US.utf8
-
- [posts]
- post1
- post2
-
- [pages]
- about
-
- [tags]
- tag1
- tag2
-
- [copy]
- assets/custom.css
-
-## BUGS
-
-Please report any issues to: <https://github.com/blogc/blogc>
-
-## AUTHOR
-
-Rafael G. Martins &lt;<rafael@rafaelmartins.eng.br>&gt;
-
-## SEE ALSO
-
-blogc(1), blogc-make(1), blogc-template(7) strftime(3)
diff --git a/man/index.txt b/man/index.txt
index d11e1c9..4ca6e67 100644
--- a/man/index.txt
+++ b/man/index.txt
@@ -1,19 +1,15 @@
# manuals
blogc(1) blogc.1.ronn
blogc-git-receiver(1) blogc-git-receiver.1.ronn
-blogc-make(1) blogc-make.1.ronn
blogc-runserver(1) blogc-runserver.1.ronn
-blogcfile(5) blogcfile.5.ronn
blogc-source(7) blogc-source.7.ronn
blogc-template(7) blogc-template.7.ronn
-blogc-toctree(7) blogc-toctree.7.ronn
blogc-pagination(7) blogc-pagination.7.ronn
# external manuals
-make(1) https://man.cx/make(1)
-chsh(1) https://man.cx/chsh(1)
-su(1) https://man.cx/su(1)
-strcmp(3) https://man.cx/strcmp(3)
-strftime(3) https://man.cx/strftime(3)
-git(1) https://man.cx/git(1)
-git-shell(1) https://man.cx/git-shell(1)
+make(1) http://man.cx/make(1)
+chsh(1) http://man.cx/chsh(1)
+su(1) http://man.cx/su(1)
+strcmp(3) http://man.cx/strcmp(3)
+strptime(3) http://man.cx/strptime(3)
+git(7) http://man.cx/git(7)
diff --git a/src/blogc-git-receiver.c b/src/blogc-git-receiver.c
new file mode 100644
index 0000000..820fce5
--- /dev/null
+++ b/src/blogc-git-receiver.c
@@ -0,0 +1,501 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libgen.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <time.h>
+
+#include "utils.h"
+
+#ifndef BUFFER_SIZE
+#define BUFFER_SIZE 4096
+#endif
+
+
+static unsigned int
+cpu_count(void)
+{
+#ifdef _SC_NPROCESSORS_ONLN
+ long num = sysconf(_SC_NPROCESSORS_ONLN);
+ if (num >= 1)
+ return (unsigned int) num;
+#endif
+ return 1;
+}
+
+
+static void
+rmdir_recursive(const char *dir)
+{
+ struct stat buf;
+ if (0 != stat(dir, &buf)) {
+ fprintf(stderr, "warning: failed to remove directory (%s): %s\n", dir,
+ strerror(errno));
+ return;
+ }
+ if (!S_ISDIR(buf.st_mode)) {
+ fprintf(stderr, "error: trying to remove invalid directory: %s\n", dir);
+ exit(2);
+ }
+ DIR *d = opendir(dir);
+ if (d == NULL) {
+ fprintf(stderr, "error: failed to open directory: %s\n",
+ strerror(errno));
+ exit(2);
+ }
+ struct dirent *e;
+ while (NULL != (e = readdir(d))) {
+ if ((0 == strcmp(e->d_name, ".")) || (0 == strcmp(e->d_name, "..")))
+ continue;
+ char *f = sb_strdup_printf("%s/%s", dir, e->d_name);
+ if (0 != stat(f, &buf)) {
+ fprintf(stderr, "error: failed to stat directory entry (%s): %s\n",
+ e->d_name, strerror(errno));
+ free(f);
+ exit(2);
+ }
+ if (S_ISDIR(buf.st_mode)) {
+ rmdir_recursive(f);
+ }
+ else if (0 != unlink(f)) {
+ fprintf(stderr, "error: failed to remove file (%s): %s\n", f,
+ strerror(errno));
+ free(f);
+ exit(2);
+ }
+ free(f);
+ }
+ if (0 != closedir(d)) {
+ fprintf(stderr, "error: failed to close directory: %s\n",
+ strerror(errno));
+ exit(2);
+ }
+ if (0 != rmdir(dir)) {
+ fprintf(stderr, "error: failed to remove directory: %s\n",
+ strerror(errno));
+ exit(2);
+ }
+}
+
+
+static int
+git_shell(int argc, char *argv[])
+{
+ int rv = 0;
+
+ char *repo = NULL;
+ char *command_orig = NULL;
+ char *command_name = NULL;
+ char command_new[BUFFER_SIZE];
+
+ bool exec_git = false;
+
+ // validate git command
+ size_t len = strlen(argv[2]);
+ if (!((len > 17 && (0 == strncmp(argv[2], "git-receive-pack ", 17))) ||
+ (len > 16 && (0 == strncmp(argv[2], "git-upload-pack ", 16))) ||
+ (len > 19 && (0 == strncmp(argv[2], "git-upload-archive ", 19)))))
+ {
+ fprintf(stderr, "error: unsupported git command: %s\n", argv[2]);
+ rv = 1;
+ goto cleanup;
+ }
+
+ // get shell path
+ char *self = getenv("SHELL");
+ if (self == NULL) {
+ fprintf(stderr, "error: failed to find blogc-git-receiver path\n");
+ rv = 1;
+ goto cleanup;
+ }
+
+ // get home path
+ char *home = getenv("HOME");
+ if (home == NULL) {
+ fprintf(stderr, "error: failed to find user home path\n");
+ rv = 1;
+ goto cleanup;
+ }
+
+ // get git repository
+ command_orig = sb_strdup(argv[2]);
+ char *p, *r;
+ for (p = command_orig; *p != ' ' && *p != '\0'; p++);
+ if (*p == ' ')
+ p++;
+ if (*p == '\'' || *p == '"')
+ p++;
+ if (*p == '/')
+ p++;
+ for (r = p; *p != '\'' && *p != '"' && *p != '\0'; p++);
+ if (*p == '\'' || *p == '"')
+ *p = '\0';
+ if (*--p == '/')
+ *p = '\0';
+
+ repo = sb_strdup_printf("repos/%s", r);
+
+ // check if repository is sane
+ if (0 == strlen(repo)) {
+ fprintf(stderr, "error: invalid repository\n");
+ rv = 1;
+ goto cleanup;
+ }
+
+ if (0 == strncmp(argv[2], "git-upload-", 11)) // no need to check len here
+ goto git_exec;
+
+ if (0 != chdir(home)) {
+ fprintf(stderr, "error: failed to chdir (%s): %s\n", home,
+ strerror(errno));
+ rv = 1;
+ goto cleanup;
+ }
+
+ if (0 != access(repo, F_OK)) {
+ char *git_init_cmd = sb_strdup_printf(
+ "git init --bare \"%s\" > /dev/null", repo);
+ if (0 != system(git_init_cmd)) {
+ fprintf(stderr, "error: failed to create git repository: %s\n",
+ repo);
+ rv = 1;
+ free(git_init_cmd);
+ goto cleanup;
+ }
+ free(git_init_cmd);
+ }
+
+ if (0 != chdir(repo)) {
+ fprintf(stderr, "error: failed to chdir (%s/%s): %s\n", home, repo,
+ strerror(errno));
+ rv = 1;
+ goto cleanup;
+ }
+
+ if (0 != access("hooks", F_OK)) {
+ // openwrt git package won't install git templates, then the git
+ // repositories created with it won't have the hooks/ directory.
+ if (0 != mkdir("hooks", 0777)) { // mkdir honors umask for us.
+ fprintf(stderr, "error: failed to create directory (%s/%s/hooks): "
+ "%s\n", home, repo, strerror(errno));
+ rv = 1;
+ goto cleanup;
+ }
+ }
+
+ if (0 != chdir("hooks")) {
+ fprintf(stderr, "error: failed to chdir (%s/%s/hooks): %s\n", home,
+ repo, strerror(errno));
+ rv = 1;
+ goto cleanup;
+ }
+
+ if (0 == access("pre-receive", F_OK)) {
+ if (0 != unlink("pre-receive")) {
+ fprintf(stderr, "error: failed to remove old symlink "
+ "(%s/%s/hooks/pre-receive): %s\n", home, repo, strerror(errno));
+ rv = 1;
+ goto cleanup;
+ }
+ }
+
+ if (0 != symlink(self, "pre-receive")) {
+ fprintf(stderr, "error: failed to create symlink "
+ "(%s/%s/hooks/pre-receive): %s\n", home, repo, strerror(errno));
+ rv = 1;
+ goto cleanup;
+ }
+
+ if (0 == access("post-receive", F_OK)) {
+ if (0 != unlink("post-receive")) {
+ fprintf(stderr, "error: failed to remove old symlink "
+ "(%s/%s/hooks/post-receive): %s\n", home, repo, strerror(errno));
+ rv = 1;
+ goto cleanup;
+ }
+ }
+
+ if (0 != symlink(self, "post-receive")) {
+ fprintf(stderr, "error: failed to create symlink "
+ "(%s/%s/hooks/post-receive): %s\n", home, repo, strerror(errno));
+ rv = 1;
+ goto cleanup;
+ }
+
+ if (0 != chdir(home)) {
+ fprintf(stderr, "error: failed to chdir (%s): %s\n", home,
+ strerror(errno));
+ rv = 1;
+ goto cleanup;
+ }
+
+git_exec:
+ command_name = sb_strdup(argv[2]);
+ for (p = command_name; *p != ' ' && *p != '\0'; p++);
+ if (*p == ' ')
+ *p = '\0';
+
+ if (BUFFER_SIZE < (strlen(command_name) + strlen(repo) + 4)) {
+ fprintf(stderr, "error: git-shell command is too big\n");
+ rv = 1;
+ goto cleanup;
+ }
+
+ if (snprintf(command_new, BUFFER_SIZE, "%s '%s'", command_name, repo))
+ exec_git = true;
+
+cleanup:
+ free(repo);
+ free(command_orig);
+ free(command_name);
+
+ if (exec_git) {
+ execlp("git-shell", "git-shell", "-c", command_new, NULL);
+
+ // execlp only returns on error, then something bad happened
+ fprintf(stderr, "error: failed to execute git-shell\n");
+ rv = 1;
+ }
+
+ return rv;
+}
+
+
+static int
+git_post_receive_hook(int argc, char *argv[])
+{
+ if (0 != system("git config --local remote.mirror.pushurl &> /dev/null")) {
+ if (0 != system("git config --local remote.mirror.url &> /dev/null")) {
+ fprintf(stderr, "warning: repository mirroring disabled\n");
+ return 0;
+ }
+ }
+
+ // at this point we know that we have a remote called mirror, we can just
+ // push to it.
+ if (0 != system("git push --mirror mirror"))
+ fprintf(stderr, "warning: failed push to git mirror\n");
+
+ return 0;
+}
+
+
+typedef enum {
+ START_OLD = 1,
+ OLD,
+ START_NEW,
+ NEW,
+ START_REF,
+ REF
+} input_state_t;
+
+
+static int
+git_pre_receive_hook(int argc, char *argv[])
+{
+ int c;
+ char buffer[BUFFER_SIZE];
+
+ input_state_t state = START_OLD;
+ size_t i = 0;
+ size_t start = 0;
+
+ int rv = 0;
+ char *new = NULL;
+ char *master = NULL;
+
+ while (EOF != (c = getc(stdin))) {
+
+ buffer[i] = (char) c;
+
+ switch (state) {
+ case START_OLD:
+ start = i;
+ state = OLD;
+ break;
+ case OLD:
+ if (c != ' ')
+ break;
+ // no need to store old
+ state = START_NEW;
+ break;
+ case START_NEW:
+ start = i;
+ state = NEW;
+ break;
+ case NEW:
+ if (c != ' ')
+ break;
+ state = START_REF;
+ new = strndup(buffer + start, i - start);
+ break;
+ case START_REF:
+ start = i;
+ state = REF;
+ break;
+ case REF:
+ if (c != '\n')
+ break;
+ state = START_OLD;
+ // we just care about a ref (refs/heads/master), everything
+ // else is disposable :)
+ if (!((i - start == 17) &&
+ (0 == strncmp("refs/heads/master", buffer + start, 17))))
+ {
+ free(new);
+ new = NULL;
+ break;
+ }
+ master = new;
+ break;
+ }
+
+ if (++i >= BUFFER_SIZE) {
+ fprintf(stderr, "error: pre-receive hook payload is too big.\n");
+ rv = 1;
+ goto cleanup2;
+ }
+ }
+
+ if (master == NULL) {
+ fprintf(stderr, "warning: no reference to master branch found. "
+ "nothing to deploy.\n");
+ goto cleanup2;
+ }
+
+ char *repo_dir = NULL;
+ char *output_dir = NULL;
+
+ if (NULL == getcwd(buffer, BUFFER_SIZE)) {
+ fprintf(stderr, "error: failed to get repository remote path: %s\n",
+ strerror(errno));
+ rv = 1;
+ goto cleanup;
+ }
+
+ repo_dir = sb_strdup(buffer);
+
+ char dir[] = "/tmp/blogc_XXXXXX";
+ if (NULL == mkdtemp(dir)) {
+ rv = 1;
+ goto cleanup;
+ }
+
+ char *git_archive_cmd = sb_strdup_printf(
+ "git archive \"%s\" | tar -x -C \"%s\" -f -", master, dir);
+ if (0 != system(git_archive_cmd)) {
+ fprintf(stderr, "error: failed to extract git content to temporary "
+ "directory: %s\n", dir);
+ rv = 1;
+ free(git_archive_cmd);
+ goto cleanup;
+ }
+ free(git_archive_cmd);
+
+ if (0 != chdir(dir)) {
+ fprintf(stderr, "error: failed to chdir (%s): %s\n", dir,
+ strerror(errno));
+ rv = 1;
+ goto cleanup;
+ }
+
+ if ((0 != access("Makefile", F_OK)) && (0 != access("GNUMakefile", F_OK))) {
+ fprintf(stderr, "warning: no makefile found. skipping ...\n");
+ goto cleanup;
+ }
+
+ char *home = getenv("HOME");
+ if (home == NULL) {
+ fprintf(stderr, "error: failed to find user home path\n");
+ rv = 1;
+ goto cleanup;
+ }
+
+ unsigned long epoch = time(NULL);
+ output_dir = sb_strdup_printf("%s/builds/%s-%lu", home, master, epoch);
+ char *gmake_cmd = sb_strdup_printf(
+ "gmake -j%d OUTPUT_DIR=\"%s\" BLOGC_GIT_RECEIVER=1",
+ cpu_count(), output_dir);
+ fprintf(stdout, "running command: %s\n\n", gmake_cmd);
+ fflush(stdout);
+ if (0 != system(gmake_cmd)) {
+ fprintf(stderr, "error: failed to build website ...\n");
+ rmdir_recursive(output_dir);
+ free(gmake_cmd);
+ rv = 1;
+ goto cleanup;
+ }
+ free(gmake_cmd);
+
+ if (0 != chdir(repo_dir)) {
+ fprintf(stderr, "error: failed to chdir (%s): %s\n", repo_dir,
+ strerror(errno));
+ rmdir_recursive(output_dir);
+ rv = 1;
+ goto cleanup;
+ }
+
+ char *htdocs_sym = NULL;
+ ssize_t htdocs_sym_len = readlink("htdocs", buffer, BUFFER_SIZE);
+ if (0 < htdocs_sym_len) {
+ if (0 != unlink("htdocs")) {
+ fprintf(stderr, "error: failed to remove symlink (%s/htdocs): %s\n",
+ repo_dir, strerror(errno));
+ rmdir_recursive(output_dir);
+ rv = 1;
+ goto cleanup;
+ }
+ buffer[htdocs_sym_len] = '\0';
+ htdocs_sym = buffer;
+ }
+
+ if (0 != symlink(output_dir, "htdocs")) {
+ fprintf(stderr, "error: failed to create symlink (%s/htdocs): %s\n",
+ repo_dir, strerror(errno));
+ rmdir_recursive(output_dir);
+ rv = 1;
+ goto cleanup;
+ }
+
+ if (htdocs_sym != NULL)
+ rmdir_recursive(htdocs_sym);
+
+cleanup:
+ free(output_dir);
+ rmdir_recursive(dir);
+ free(repo_dir);
+cleanup2:
+ free(new);
+ return rv;
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ if (argc > 0) {
+ if (0 == strcmp(basename(argv[0]), "pre-receive"))
+ return git_pre_receive_hook(argc, argv);
+ if (0 == strcmp(basename(argv[0]), "post-receive"))
+ return git_post_receive_hook(argc, argv);
+ }
+
+ if (argc == 3 && (0 == strcmp(argv[1], "-c")))
+ return git_shell(argc, argv);
+
+ fprintf(stderr, "error: this is a special shell, go away!\n");
+ return 1;
+}
diff --git a/src/blogc-git-receiver/main.c b/src/blogc-git-receiver/main.c
deleted file mode 100644
index 13218dd..0000000
--- a/src/blogc-git-receiver/main.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <libgen.h>
-#include "shell.h"
-#include "pre-receive.h"
-#include "post-receive.h"
-
-
-int
-main(int argc, char *argv[])
-{
- if (argc > 0) {
- if (0 == strcmp(basename(argv[0]), "pre-receive"))
- return bgr_pre_receive_hook(argc, argv);
- if (0 == strcmp(basename(argv[0]), "post-receive"))
- return bgr_post_receive_hook(argc, argv);
- }
-
- if (argc == 3 && (0 == strcmp(argv[1], "-c"))) {
- return bgr_shell(argc, argv);
- }
-
- // this is a hack to make blogc-git-receiver work out-of-the-box as a
- // `command=` in authorized_keys file. it will only work if the command
- // path is absolute.
- char *ssh_orig = getenv("SSH_ORIGINAL_COMMAND");
- if (argc == 1 && ssh_orig != NULL && argv[0][0] == '/') {
- setenv("SHELL", argv[0], 1);
- char* _argv[] = {argv[0], "-c", ssh_orig};
- return bgr_shell(3, _argv);
- }
-
- fprintf(stderr, "error: this is a special shell, go away!\n");
- return 1;
-}
diff --git a/src/blogc-git-receiver/post-receive.c b/src/blogc-git-receiver/post-receive.c
deleted file mode 100644
index 17a8aa7..0000000
--- a/src/blogc-git-receiver/post-receive.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <libgen.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include "../common/utils.h"
-#include "../common/config-parser.h"
-#include "settings.h"
-#include "post-receive.h"
-
-
-int
-bgr_post_receive_hook(int argc, char *argv[])
-{
- int rv = 0;
- char *mirror = NULL;
-
- char *hooks_dir = dirname(argv[0]); // this was validated by main()
- char *real_hooks_dir = realpath(hooks_dir, NULL);
- if (real_hooks_dir == NULL) {
- fprintf(stderr, "error: failed to guess repository root: %s\n",
- strerror(errno));
- return 1;
- }
-
- char *repo_path = bc_strdup(dirname(real_hooks_dir));
- free(real_hooks_dir);
- if (0 != chdir(repo_path)) {
- fprintf(stderr, "error: failed to change to repository root\n");
- rv = 1;
- goto cleanup;
- }
-
- // local repository settings should take precedence, so if the repo have
- // the 'mirror' remote, just push to it.
- // this will be removed at some point, but will be kept for compatibility
- // with old setups.
- if ((0 == system("git config --local remote.mirror.pushurl > /dev/null")) ||
- (0 == system("git config --local remote.mirror.url > /dev/null")))
- {
- mirror = bc_strdup("mirror");
- goto push;
- }
-
- bc_config_t *config = bgr_settings_parse();
- if (config == NULL) {
- fprintf(stderr, "warning: repository mirroring disabled\n");
- goto cleanup;
- }
-
- char *section = bgr_settings_get_section(config, repo_path);
- if (section == NULL) {
- fprintf(stderr, "warning: repository mirroring disabled\n");
- bc_config_free(config);
- goto cleanup;
- }
-
- mirror = bc_strdup(bc_config_get(config, section, "mirror"));
- free(section);
- bc_config_free(config);
-
- if (mirror == NULL) {
- fprintf(stderr, "warning: repository mirroring disabled\n");
- goto cleanup;
- }
-
-push:
-
- {
- char *git_cmd = bc_strdup_printf("git push --mirror %s", mirror);
- if (0 != system(git_cmd))
- fprintf(stderr, "warning: failed push to git mirror\n");
- free(git_cmd);
- }
-
- free(mirror);
-
-cleanup:
- free(repo_path);
-
- return rv;
-}
diff --git a/src/blogc-git-receiver/post-receive.h b/src/blogc-git-receiver/post-receive.h
deleted file mode 100644
index fc56dc3..0000000
--- a/src/blogc-git-receiver/post-receive.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _POST_RECEIVE_H
-#define _POST_RECEIVE_H
-
-int bgr_post_receive_hook(int argc, char *argv[]);
-
-#endif /* _POST_RECEIVE_H */
diff --git a/src/blogc-git-receiver/pre-receive-parser.c b/src/blogc-git-receiver/pre-receive-parser.c
deleted file mode 100644
index 61a533c..0000000
--- a/src/blogc-git-receiver/pre-receive-parser.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include "../common/utils.h"
-#include "pre-receive-parser.h"
-
-typedef enum {
- START_OLD = 1,
- OLD,
- START_NEW,
- NEW,
- START_REF,
- REF
-} input_state_t;
-
-
-bc_trie_t*
-bgr_pre_receive_parse(const char *input, size_t input_len)
-{
- input_state_t state = START_OLD;
- size_t start = 0;
- size_t start_new = 0;
-
- bc_trie_t* rv = bc_trie_new(free);
-
- for (size_t current = 0; current < input_len; current++) {
-
- char c = input[current];
-
- switch (state) {
- case START_OLD:
- start = current;
- state = OLD;
- break;
- case OLD:
- if (c != ' ')
- break;
- // no need to store old
- state = START_NEW;
- break;
- case START_NEW:
- start = current;
- state = NEW;
- break;
- case NEW:
- if (c != ' ')
- break;
- state = START_REF;
- start_new = start;
- break;
- case START_REF:
- start = current;
- state = REF;
- break;
- case REF:
- if (c != '\n')
- break;
- state = START_OLD;
- if ((current - start > 11) &&
- (0 == strncmp("refs/heads/", input + start, 11)))
- {
- char *key = bc_strndup(input + start + 11, current - start - 11);
- bc_trie_insert(rv, key, bc_strndup(input + start_new, start - 1 - start_new));
- free(key);
- }
- break;
- }
- }
-
- if (bc_trie_size(rv) == 0) {
- bc_trie_free(rv);
- return NULL;
- }
-
- return rv;
-}
diff --git a/src/blogc-git-receiver/pre-receive-parser.h b/src/blogc-git-receiver/pre-receive-parser.h
deleted file mode 100644
index 45a9da8..0000000
--- a/src/blogc-git-receiver/pre-receive-parser.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _PRE_RECEIVE_PARSER_H
-#define _PRE_RECEIVE_PARSER_H
-
-#include <stddef.h>
-#include "../common/utils.h"
-
-bc_trie_t* bgr_pre_receive_parse(const char *input, size_t input_len);
-
-#endif /* _PRE_RECEIVE_PARSER_H */
diff --git a/src/blogc-git-receiver/pre-receive.c b/src/blogc-git-receiver/pre-receive.c
deleted file mode 100644
index 12d29cf..0000000
--- a/src/blogc-git-receiver/pre-receive.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-#include <dirent.h>
-#include <time.h>
-#include <libgen.h>
-#include "../common/compat.h"
-#include "../common/utils.h"
-#include "../common/stdin.h"
-#include "settings.h"
-#include "pre-receive-parser.h"
-#include "pre-receive.h"
-
-
-static size_t
-cpu_count(void)
-{
-#ifdef _SC_NPROCESSORS_ONLN
- long num = sysconf(_SC_NPROCESSORS_ONLN);
- if (num >= 1)
- return (size_t) num;
-#endif
- return 1;
-}
-
-
-static void
-rmdir_recursive(const char *dir)
-{
- if (dir == NULL)
- return;
- struct stat buf;
- if (0 != stat(dir, &buf)) {
- return;
- }
- if (!S_ISDIR(buf.st_mode)) {
- fprintf(stderr, "error: trying to remove invalid directory: %s\n", dir);
- exit(2);
- }
- DIR *d = opendir(dir);
- if (d == NULL) {
- fprintf(stderr, "error: failed to open directory: %s\n",
- strerror(errno));
- exit(2);
- }
- struct dirent *e;
- while (NULL != (e = readdir(d))) {
- if ((0 == strcmp(e->d_name, ".")) || (0 == strcmp(e->d_name, "..")))
- continue;
- char *f = bc_strdup_printf("%s/%s", dir, e->d_name);
- if (0 != stat(f, &buf)) {
- fprintf(stderr, "error: failed to stat directory entry (%s): %s\n",
- e->d_name, strerror(errno));
- free(f);
- exit(2);
- }
- if (S_ISDIR(buf.st_mode)) {
- rmdir_recursive(f);
- }
- else if (0 != unlink(f)) {
- fprintf(stderr, "error: failed to remove file (%s): %s\n", f,
- strerror(errno));
- free(f);
- exit(2);
- }
- free(f);
- }
- if (0 != closedir(d)) {
- fprintf(stderr, "error: failed to close directory: %s\n",
- strerror(errno));
- exit(2);
- }
- if (0 != rmdir(dir)) {
- fprintf(stderr, "error: failed to remove directory: %s\n",
- strerror(errno));
- exit(2);
- }
-}
-
-
-int
-bgr_pre_receive_hook(int argc, char *argv[])
-{
- int rv = 0;
- char *ref = NULL;
- char *output_dir = NULL;
- char *tmpdir = NULL;
- char *sym = NULL;
-
- char *hooks_dir = dirname(argv[0]); // this was validated by main()
- char *real_hooks_dir = realpath(hooks_dir, NULL);
- if (real_hooks_dir == NULL) {
- fprintf(stderr, "error: failed to guess repository root: %s\n",
- strerror(errno));
- return 1;
- }
-
- char *repo_dir = bc_strdup(dirname(real_hooks_dir));
- free(real_hooks_dir);
- if (0 != chdir(repo_dir)) {
- fprintf(stderr, "error: failed to change to repository root\n");
- rv = 1;
- goto cleanup;
- }
-
- bc_config_t *config = bgr_settings_parse();
- if (config == NULL) {
- goto default_sym;
- }
-
- char *section = bgr_settings_get_section(config, repo_dir);
- if (section == NULL) {
- bc_config_free(config);
- goto default_sym;
- }
-
- const char *sym_tmp = bc_config_get(config, section, "symlink");
- if (sym_tmp == NULL) {
- free(section);
- bc_config_free(config);
- goto default_sym;
- }
-
- sym = bc_str_starts_with(sym_tmp, "/") ? bc_strdup(sym_tmp) :
- bc_strdup_printf("%s/%s", repo_dir, sym_tmp);
- free(section);
- bc_config_free(config);
-
-default_sym:
-
- if (sym == NULL) {
- sym = bc_strdup_printf("%s/htdocs", repo_dir);
- }
-
- if (NULL == getenv("GIT_DIR")) {
- if (0 != access(sym, R_OK)) {
- fprintf(stderr, "error: no previous build found. nothing to "
- "rebuild.\n");
- rv = 1;
- goto cleanup;
- }
- char *build_dir = realpath(sym, NULL);
- if (build_dir == NULL) {
- fprintf(stderr, "error: failed to get the hash of last built "
- "commit: %s\n", strerror(errno));
- rv = 1;
- goto cleanup;
- }
- char **pieces = bc_str_split(basename(build_dir), '-', 2);
- free(build_dir);
- if (bc_strv_length(pieces) != 2) {
- fprintf(stderr, "error: failed to parse the hash of last built "
- "commit.\n");
- bc_strv_free(pieces);
- rv = 1;
- goto cleanup;
- }
- ref = bc_strdup(pieces[0]);
- bc_strv_free(pieces);
- }
- else {
- size_t input_len;
- char *input = bc_stdin_read(&input_len);
- bc_trie_t *branches = bgr_pre_receive_parse(input, input_len);
-
- // try 'master' by default to avoid breaking existing setups
- ref = bc_strdup(bc_trie_lookup(branches, "master"));
- if (ref == NULL) {
- // try 'main'
- ref = bc_strdup(bc_trie_lookup(branches, "main"));
- }
-
- bc_trie_free(branches);
- free(input);
- }
-
- if (ref == NULL) {
- fprintf(stderr, "warning: no suitable branch found. "
- "nothing to deploy.\n");
- goto cleanup;
- }
-
- char dir[] = "/tmp/blogc_XXXXXX";
- if (NULL == mkdtemp(dir)) {
- rv = 1;
- goto cleanup;
- }
- tmpdir = dir;
-
- char *git_archive_cmd = bc_strdup_printf(
- "git archive \"%s\" | tar -x -C \"%s\" -f -", ref, tmpdir);
- if (0 != system(git_archive_cmd)) {
- fprintf(stderr, "error: failed to extract git content to temporary "
- "directory: %s\n", tmpdir);
- rv = 1;
- free(git_archive_cmd);
- goto cleanup;
- }
- free(git_archive_cmd);
-
- if (0 != chdir(tmpdir)) {
- fprintf(stderr, "error: failed to chdir (%s): %s\n", tmpdir,
- strerror(errno));
- rv = 1;
- goto cleanup;
- }
-
- char *buildsd = bgr_settings_get_builds_dir();
- if (buildsd == NULL) {
- fprintf(stderr, "error: failed to find builds directory path\n");
- rv = 1;
- goto cleanup;
- }
-
- unsigned long epoch = time(NULL);
- output_dir = bc_strdup_printf("%s/%s-%lu", buildsd, ref, epoch);
- free(buildsd);
-
- if (0 == access(output_dir, F_OK)) {
- char *tmp = output_dir;
- output_dir = bc_strdup_printf("%s-", tmp);
- free(tmp);
- }
-
- // detect if we will run blogc-make, make or nothing, and generate the
- // command.
- char *build_cmd = NULL;
- if (0 == access("blogcfile", F_OK)) {
- int status_bmake = system("blogc-make -v 2> /dev/null > /dev/null");
- if (127 == bc_compat_status_code(status_bmake)) {
- fprintf(stderr, "error: failed to find blogc-make binary\n");
- rv = 1;
- goto cleanup;
- }
- build_cmd = bc_strdup_printf("OUTPUT_DIR=\"%s\" blogc-make -V all",
- output_dir);
- }
- else if ((0 == access("Makefile", F_OK)) || (0 == access("GNUMakefile", F_OK))) {
- const char *make_impl = NULL;
-
- int status_gmake = system("gmake -f /dev/null 2> /dev/null > /dev/null");
- if (127 != bc_compat_status_code(status_gmake)) {
- make_impl = "gmake";
- }
- else {
- int status_make = system("make -f /dev/null 2> /dev/null > /dev/null");
- if (127 != bc_compat_status_code(status_make)) {
- make_impl = "make";
- }
- }
-
- if (make_impl == NULL) {
- fprintf(stderr, "error: no 'make' implementation found\n");
- rv = 1;
- goto cleanup;
- }
- build_cmd = bc_strdup_printf(
- "%s -j%d OUTPUT_DIR=\"%s\" BLOGC_GIT_RECEIVER=1", make_impl,
- cpu_count(), output_dir);
- }
- else {
- fprintf(stderr, "warning: no blogcfile or Makefile found. skipping ...\n");
- goto cleanup;
- }
-
- fprintf(stdout, "running command: %s\n\n", build_cmd);
- fflush(stdout);
- if (0 != system(build_cmd)) {
- fprintf(stderr, "error: failed to build website ...\n");
- rmdir_recursive(output_dir);
- free(build_cmd);
- rv = 1;
- goto cleanup;
- }
- free(build_cmd);
-
- char *htdocs_sym = realpath(sym, NULL);
- if ((htdocs_sym != NULL) && (0 != unlink(sym))) {
- fprintf(stderr, "error: failed to remove symlink (%s): %s\n", sym,
- strerror(errno));
- rmdir_recursive(output_dir);
- rv = 1;
- goto cleanup2;
- }
-
- if (0 != symlink(output_dir, sym)) {
- fprintf(stderr, "error: failed to create symlink (%s): %s\n", sym,
- strerror(errno));
- rmdir_recursive(output_dir);
- rv = 1;
- goto cleanup2;
- }
-
- if (htdocs_sym != NULL)
- rmdir_recursive(htdocs_sym);
-
-cleanup2:
- free(htdocs_sym);
-
-cleanup:
- free(sym);
- free(ref);
- free(output_dir);
- rmdir_recursive(tmpdir);
- free(repo_dir);
- return rv;
-}
diff --git a/src/blogc-git-receiver/pre-receive.h b/src/blogc-git-receiver/pre-receive.h
deleted file mode 100644
index ab19c47..0000000
--- a/src/blogc-git-receiver/pre-receive.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _PRE_RECEIVE_H
-#define _PRE_RECEIVE_H
-
-int bgr_pre_receive_hook(int argc, char *argv[]);
-
-#endif /* _PRE_RECEIVE_H */
diff --git a/src/blogc-git-receiver/settings.c b/src/blogc-git-receiver/settings.c
deleted file mode 100644
index db29b18..0000000
--- a/src/blogc-git-receiver/settings.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdio.h>
-#include <libgen.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include "../common/utils.h"
-#include "../common/config-parser.h"
-#include "../common/error.h"
-#include "../common/file.h"
-#include "settings.h"
-
-
-const char*
-bgr_settings_get_base_dir(void)
-{
- char *rv = getenv("BLOGC_GIT_RECEIVER_BASE_DIR");
- if (rv != NULL) {
- return rv;
- }
- return getenv("HOME");
-}
-
-
-char*
-bgr_settings_get_builds_dir(void)
-{
- char *rv = getenv("BLOGC_GIT_RECEIVER_BUILDS_DIR");
- if (rv != NULL) {
- return bc_strdup(rv);
- }
- return bc_strdup_printf("%s/builds", bgr_settings_get_base_dir());
-}
-
-
-char*
-bgr_settings_get_section(bc_config_t *config, const char *repo_path)
-{
- const char *bd = bgr_settings_get_base_dir();
- if (bd == NULL) {
- return NULL;
- }
- char *rv = NULL;
- char** sections = bc_config_list_sections(config);
- for (size_t i = 0; sections[i] != NULL; i++) {
- if (bc_str_starts_with(sections[i], "repo:")) {
- char *tmp_repo = bc_strdup_printf("%s/repos/%s", bd, sections[i] + 5);
- char *real_tmp_repo = realpath(tmp_repo, NULL); // maybe not needed
- free(tmp_repo);
- if (real_tmp_repo == NULL)
- continue;
- if (0 == strcmp(real_tmp_repo, repo_path)) {
- rv = bc_strdup(sections[i]);
- free(real_tmp_repo);
- break;
- }
- free(real_tmp_repo);
- }
- }
- bc_strv_free(sections);
- return rv;
-}
-
-
-bc_config_t*
-bgr_settings_parse(void)
-{
- const char *bd = bgr_settings_get_base_dir();
- if (bd == NULL) {
- return NULL;
- }
- char *config_file = bc_strdup_printf("%s/blogc-git-receiver.ini", bd);
- if ((0 != access(config_file, F_OK))) {
- free(config_file);
- return NULL;
- }
-
- size_t len;
- bc_error_t *err = NULL;
- char* config_content = bc_file_get_contents(config_file, true, &len, &err);
- if (err != NULL) {
- fprintf(stderr, "warning: failed to read configuration file (%s): %s\n",
- config_file, err->msg);
- bc_error_free(err);
- free(config_file);
- free(config_content);
- return NULL;
- }
-
- bc_config_t *config = bc_config_parse(config_content, len, NULL, &err);
- free(config_content);
- if (err != NULL) {
- fprintf(stderr, "warning: failed to parse configuration file (%s): %s\n",
- config_file, err->msg);
- bc_error_free(err);
- free(config_file);
- return NULL;
- }
- free(config_file);
-
- return config;
-}
diff --git a/src/blogc-git-receiver/settings.h b/src/blogc-git-receiver/settings.h
deleted file mode 100644
index 04c1a2b..0000000
--- a/src/blogc-git-receiver/settings.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _SETTINGS_H
-#define _SETTINGS_H
-
-#include "../common/config-parser.h"
-
-const char* bgr_settings_get_base_dir(void);
-char* bgr_settings_get_builds_dir(void);
-char* bgr_settings_get_section(bc_config_t *config, const char *repo_path);
-bc_config_t* bgr_settings_parse(void);
-
-#endif /* _SETTINGS_H */
diff --git a/src/blogc-git-receiver/shell-command-parser.c b/src/blogc-git-receiver/shell-command-parser.c
deleted file mode 100644
index 0091e0b..0000000
--- a/src/blogc-git-receiver/shell-command-parser.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include "../common/utils.h"
-#include "shell-command-parser.h"
-
-typedef enum {
- START_COMMAND = 1,
- START_REPO,
- START_REPO2,
- REPO,
- START_ESCAPED,
-} command_state_t;
-
-
-char*
-bgr_shell_command_parse(const char *command)
-{
- command_state_t state = START_COMMAND;
- size_t start = 0;
- size_t command_len = strlen(command);
-
- bc_string_t *rv = bc_string_new();
-
- for (size_t current = 0; current < command_len; current++) {
-
- char c = command[current];
-
- switch (state) {
- case START_COMMAND:
- if (c == ' ') {
- if (((current == 16) &&
- (0 == strncmp("git-receive-pack", command, 16))) ||
- ((current == 15) &&
- (0 == strncmp("git-upload-pack", command, 15))) ||
- ((current == 18) &&
- (0 == strncmp("git-upload-archive", command, 18))))
- {
- state = START_REPO;
- break;
- }
- goto error;
- }
- break;
-
- case START_REPO:
- if (c == '\'') { // never saw git using double-quotes
- state = START_REPO2;
- break;
- }
- if (c == '\\') { // escaped ! or '
- state = START_ESCAPED;
- break;
- }
- goto error;
-
- case START_REPO2:
- if (c == '\'') {
- state = START_REPO;
- break;
- }
- start = current;
- if (rv->len == 0 && c == '/') { // no absolute urls
- start = current + 1;
- }
- state = REPO;
- break;
-
- case START_ESCAPED:
- if (c == '!' || c == '\'') {
- bc_string_append_c(rv, c);
- state = START_REPO;
- break;
- }
- goto error;
-
- case REPO:
- if (c == '\'') {
- bc_string_append_len(rv, command + start, current - start);
- state = START_REPO;
- break;
- }
- break;
- }
- }
-
- if (rv->len > 0)
- return bc_string_free(rv, false);
-
-error:
- bc_string_free(rv, true);
- return NULL;
-}
diff --git a/src/blogc-git-receiver/shell-command-parser.h b/src/blogc-git-receiver/shell-command-parser.h
deleted file mode 100644
index 818d098..0000000
--- a/src/blogc-git-receiver/shell-command-parser.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _SHELL_COMMAND_PARSER_H
-#define _SHELL_COMMAND_PARSER_H
-
-char* bgr_shell_command_parse(const char *command);
-
-#endif /* _SHELL_COMMAND_PARSER_H */
diff --git a/src/blogc-git-receiver/shell.c b/src/blogc-git-receiver/shell.c
deleted file mode 100644
index a4c8a2d..0000000
--- a/src/blogc-git-receiver/shell.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-#include "../common/utils.h"
-#include "settings.h"
-#include "shell-command-parser.h"
-#include "shell.h"
-
-
-static bool
-lexists(const char *pathname)
-{
- struct stat b;
- int tmp_errno = errno;
- bool rv = lstat(pathname, &b) == 0;
- errno = tmp_errno;
- return rv;
-}
-
-
-int
-bgr_shell(int argc, char *argv[])
-{
- int rv = 0;
-
- char *repo = NULL;
- char *quoted_repo = NULL;
-
- // get shell path
- char *self = getenv("SHELL");
- if (self == NULL) {
- fprintf(stderr, "error: failed to find blogc-git-receiver path\n");
- rv = 1;
- goto cleanup;
- }
-
- // get base dir path
- const char *bd = bgr_settings_get_base_dir();
- if (bd == NULL) {
- fprintf(stderr, "error: failed to find base directory path\n");
- rv = 1;
- goto cleanup;
- }
-
- // validate command and extract git repository
- char *tmp_repo = bgr_shell_command_parse(argv[2]);
- if (tmp_repo == NULL) {
- fprintf(stderr, "error: invalid git-shell command: %s\n", argv[2]);
- rv = 1;
- goto cleanup;
- }
-
- repo = bc_strdup_printf("%s/repos/%s", bd, tmp_repo);
- quoted_repo = bc_shell_quote(repo);
- free(tmp_repo);
-
- if (0 == strncmp(argv[2], "git-upload-", 11)) // no need to check len here
- goto git_exec;
-
- if (0 != access(repo, F_OK)) {
- char *git_init_cmd = bc_strdup_printf(
- "git init --bare %s > /dev/null", quoted_repo);
- if (0 != system(git_init_cmd)) {
- fprintf(stderr, "error: failed to create git repository: %s\n",
- repo);
- rv = 1;
- free(git_init_cmd);
- goto cleanup;
- }
- free(git_init_cmd);
- }
-
- if (0 != chdir(repo)) {
- fprintf(stderr, "error: failed to chdir (%s): %s\n", repo,
- strerror(errno));
- rv = 1;
- goto cleanup;
- }
-
- if (0 != access("hooks", F_OK)) {
- // openwrt git package won't install git templates, then the git
- // repositories created with it won't have the hooks/ directory.
- if (0 != mkdir("hooks", 0777)) { // mkdir honors umask for us.
- fprintf(stderr, "error: failed to create directory (%s/hooks): "
- "%s\n", repo, strerror(errno));
- rv = 1;
- goto cleanup;
- }
- }
-
- if (0 != chdir("hooks")) {
- fprintf(stderr, "error: failed to chdir (%s/hooks): %s\n", repo,
- strerror(errno));
- rv = 1;
- goto cleanup;
- }
-
- if (lexists("pre-receive")) {
- if (0 != unlink("pre-receive")) {
- fprintf(stderr, "error: failed to remove old symlink "
- "(%s/hooks/pre-receive): %s\n", repo, strerror(errno));
- rv = 1;
- goto cleanup;
- }
- }
-
- if (0 != symlink(self, "pre-receive")) {
- fprintf(stderr, "error: failed to create symlink "
- "(%s/hooks/pre-receive): %s\n", repo, strerror(errno));
- rv = 1;
- goto cleanup;
- }
-
- if (lexists("post-receive")) {
- if (0 != unlink("post-receive")) {
- fprintf(stderr, "error: failed to remove old symlink "
- "(%s/hooks/post-receive): %s\n", repo, strerror(errno));
- rv = 1;
- goto cleanup;
- }
- }
-
- if (0 != symlink(self, "post-receive")) {
- fprintf(stderr, "error: failed to create symlink "
- "(%s/hooks/post-receive): %s\n", repo, strerror(errno));
- rv = 1;
- goto cleanup;
- }
-
-git_exec:
-
- if (0 != chdir(bd)) {
- fprintf(stderr, "error: failed to chdir (%s): %s\n", bd, strerror(errno));
- rv = 1;
- goto cleanup;
- }
-
- // static allocation instead of bc_strdup_printf to avoid leaks
- char buffer[4096];
- char *command = bc_strdup(argv[2]);
- char *p;
- for (p = command; *p != ' ' && *p != '\0'; p++);
- if (*p == ' ')
- *p = '\0';
-
- if (sizeof(buffer) < (strlen(command) + strlen(quoted_repo) + 2)) {
- fprintf(stderr, "error: git-shell command is too big\n");
- rv = 1;
- goto cleanup;
- }
-
- if (0 > snprintf(buffer, sizeof(buffer), "%s %s", command, quoted_repo)) {
- fprintf(stderr, "error: failed to generate git-shell command\n");
- rv = 1;
- goto cleanup;
- }
-
- free(command);
- free(repo);
- free(quoted_repo);
-
- // this is a hack. no memory handling should be done inside this block
- if (NULL == getenv("__VALGRIND_ENABLED")) {
- execlp("git-shell", "git-shell", "-c", buffer, NULL);
-
- // execlp only returns on error, then something bad happened
- fprintf(stderr, "error: failed to execute git-shell\n");
- return 1;
- }
-
- printf("git-shell -c \"%s\"\n", buffer); // used by tests, ignore
- return 0;
-
-cleanup:
- free(repo);
- free(quoted_repo);
- return rv;
-}
diff --git a/src/blogc-git-receiver/shell.h b/src/blogc-git-receiver/shell.h
deleted file mode 100644
index b59ff40..0000000
--- a/src/blogc-git-receiver/shell.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _SHELL_H
-#define _SHELL_H
-
-char* bgr_shell_get_repo(const char *command);
-int bgr_shell(int argc, char *argv[]);
-
-#endif /* _SHELL_H */
diff --git a/src/blogc-make/atom.c b/src/blogc-make/atom.c
deleted file mode 100644
index 0b8cfd1..0000000
--- a/src/blogc-make/atom.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include "../common/error.h"
-#include "../common/utils.h"
-#include "settings.h"
-#include "utils.h"
-#include "atom.h"
-
-static const char atom_template[] =
- "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
- "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n"
- " <title type=\"text\">{{ SITE_TITLE }}{%% ifdef FILTER_TAG %%} - "
- "{{ FILTER_TAG }}{%% endif %%}</title>\n"
- " <id>{{ BASE_DOMAIN }}{{ BASE_URL }}%s</id>\n"
- " <updated>{{ DATE_FIRST_FORMATTED }}</updated>\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/\" />\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}%s\" rel=\"self\" />\n"
- " <author>\n"
- " <name>{{ AUTHOR_NAME }}</name>\n"
- " <email>{{ AUTHOR_EMAIL }}</email>\n"
- " </author>\n"
- " <subtitle type=\"text\">{{ SITE_TAGLINE }}</subtitle>\n"
- " {%%- block listing %%}\n"
- " <entry>\n"
- " <title type=\"text\">{{ TITLE }}</title>\n"
- " <id>{{ BASE_DOMAIN }}{{ BASE_URL }}%s</id>\n"
- " <updated>{{ DATE_FORMATTED }}</updated>\n"
- " <published>{{ DATE_FORMATTED }}</published>\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}%s\" />\n"
- " <author>\n"
- " <name>{{ AUTHOR_NAME }}</name>\n"
- " <email>{{ AUTHOR_EMAIL }}</email>\n"
- " </author>\n"
- " <content type=\"html\"><![CDATA[{{ CONTENT }}]]></content>\n"
- " </entry>\n"
- " {%%- endblock %%}\n"
- "</feed>\n";
-
-
-char*
-bm_atom_generate(bm_settings_t *settings)
-{
- if (settings == NULL)
- return NULL;
-
- const char *atom_prefix = bc_trie_lookup(settings->settings, "atom_prefix");
- const char *atom_ext = bc_trie_lookup(settings->settings, "atom_ext");
- const char *post_prefix = bc_trie_lookup(settings->settings, "post_prefix");
- const char *post_ext = bc_trie_lookup(settings->settings, "html_ext");
-
- bc_string_t *atom_url = bc_string_new();
-
- if (atom_prefix[0] != '\0')
- bc_string_append_c(atom_url, '/');
-
- bc_string_append(atom_url, atom_prefix);
- bc_string_append(atom_url, "{% ifdef FILTER_TAG %}/{{ FILTER_TAG }}");
-
- if (atom_prefix[0] == '\0' && atom_ext[0] != '/')
- bc_string_append(atom_url, "{% else %}/index");
-
- bc_string_append(atom_url, "{% endif %}");
- bc_string_append(atom_url, atom_ext);
-
- char *post_url = bm_generate_filename(NULL, post_prefix, "{{ FILENAME }}",
- post_ext);
-
- char *rv = bc_strdup_printf(atom_template, atom_url->str, atom_url->str,
- post_url, post_url);
-
- bc_string_free(atom_url, true);
- free(post_url);
-
- return rv;
-}
-
-
-char*
-bm_atom_deploy(bm_settings_t *settings, bc_error_t **err)
-{
- if (settings == NULL || err == NULL || *err != NULL)
- return NULL;
-
- if (NULL != bc_trie_lookup(settings->settings, "atom_legacy_entry_id")) {
- *err = bc_error_new_printf(BLOGC_MAKE_ERROR_ATOM,
- "'atom_legacy_entry_id' setting is not supported anymore. see "
- "https://blogc.rgm.io/news/blogc-0.16.1/ for details");
- return NULL;
- }
-
- // this is not really portable
- char fname[] = "/tmp/blogc-make_XXXXXX";
- int fd;
- if (-1 == (fd = mkstemp(fname))) {
- *err = bc_error_new_printf(BLOGC_MAKE_ERROR_ATOM,
- "Failed to create temporary atom template: %s", strerror(errno));
- return NULL;
- }
-
- char *content = bm_atom_generate(settings);
- if (content == NULL) {
- close(fd);
- unlink(fname);
- return NULL;
- }
-
- if (-1 == write(fd, content, strlen(content))) {
- *err = bc_error_new_printf(BLOGC_MAKE_ERROR_ATOM,
- "Failed to write to temporary atom template: %s", strerror(errno));
- free(content);
- close(fd);
- unlink(fname);
- return NULL;
- }
-
- free(content);
- close(fd);
-
- return bc_strdup(fname);
-}
-
-
-void
-bm_atom_destroy(const char *fname)
-{
- unlink(fname);
-}
diff --git a/src/blogc-make/atom.h b/src/blogc-make/atom.h
deleted file mode 100644
index 29a6dcb..0000000
--- a/src/blogc-make/atom.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _MAKE_ATOM_H
-#define _MAKE_ATOM_H
-
-#include "../common/error.h"
-#include "settings.h"
-
-char* bm_atom_generate(bm_settings_t *settings);
-char* bm_atom_deploy(bm_settings_t *settings, bc_error_t **err);
-void bm_atom_destroy(const char *fname);
-
-#endif /* _MAKE_ATOM_H */
diff --git a/src/blogc-make/ctx.c b/src/blogc-make/ctx.c
deleted file mode 100644
index b8d23dd..0000000
--- a/src/blogc-make/ctx.c
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <errno.h>
-#include <libgen.h>
-#include <limits.h>
-#include <time.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <string.h>
-#include <unistd.h>
-#include "../common/error.h"
-#include "../common/file.h"
-#include "../common/utils.h"
-#include "atom.h"
-#include "settings.h"
-#include "exec.h"
-#include "utils.h"
-#include "ctx.h"
-
-
-bm_filectx_t*
-bm_filectx_new(bm_ctx_t *ctx, const char *filename, const char *slug,
- struct stat *st)
-{
- if (ctx == NULL || filename == NULL)
- return NULL;
-
- char *f = filename[0] == '/' ? bc_strdup(filename) :
- bc_strdup_printf("%s/%s", ctx->root_dir, filename);
-
- bm_filectx_t *rv = bc_malloc(sizeof(bm_filectx_t));
- rv->path = f;
- rv->short_path = bc_strdup(filename);
- rv->slug = bc_strdup(slug);
-
- if (st == NULL) {
- struct stat buf;
-
- if (0 != stat(f, &buf)) {
- rv->tv_sec = 0;
- rv->tv_nsec = 0;
- rv->readable = false;
- return rv;
- }
-
- st = &buf;
- }
-
- // if it isn't NULL the file exists for sure
- rv->tv_sec = st->st_mtim_tv_sec;
- rv->tv_nsec = st->st_mtim_tv_nsec;
- rv->readable = true;
- return rv;
-}
-
-
-bc_slist_t*
-bm_filectx_new_r(bc_slist_t *l, bm_ctx_t *ctx, const char *filename)
-{
- if (ctx == NULL || filename == NULL)
- return NULL;
-
- char *f = filename[0] == '/' ? bc_strdup(filename) :
- bc_strdup_printf("%s/%s", ctx->root_dir, filename);
-
- struct stat buf;
- if (0 != stat(f, &buf)) {
- free(f);
- return l;
- }
-
- if (S_ISDIR(buf.st_mode)) {
- DIR *dir = opendir(f);
- if (dir == NULL) {
- free(f);
- return l;
- }
-
- struct dirent *e;
- while (NULL != (e = readdir(dir))) {
- if ((0 == strcmp(e->d_name, ".")) || (0 == strcmp(e->d_name, "..")))
- continue;
- char *tmp = bc_strdup_printf("%s/%s", filename, e->d_name);
- l = bm_filectx_new_r(l, ctx, tmp);
- free(tmp);
- }
-
- closedir(dir);
- free(f);
- return l;
- }
-
- l = bc_slist_append(l, bm_filectx_new(ctx, filename, NULL, &buf));
- free(f);
- return l;
-}
-
-
-bool
-bm_filectx_changed(bm_filectx_t *ctx, time_t *tv_sec, long *tv_nsec)
-{
- if (ctx == NULL)
- return false;
-
- struct stat buf;
-
- if (0 == stat(ctx->path, &buf)) {
- if (buf.st_mtim_tv_sec == ctx->tv_sec) {
- if (buf.st_mtim_tv_nsec > ctx->tv_nsec) {
- if (tv_sec != NULL)
- *tv_sec = buf.st_mtim_tv_sec;
- if (tv_nsec != NULL)
- *tv_nsec = buf.st_mtim_tv_nsec;
- return true;
- }
- }
- else if (buf.st_mtim_tv_sec > ctx->tv_sec) {
- if (tv_sec != NULL)
- *tv_sec = buf.st_mtim_tv_sec;
- if (tv_nsec != NULL)
- *tv_nsec = buf.st_mtim_tv_nsec;
- return true;
- }
- }
-
- return false;
-}
-
-
-void
-bm_filectx_reload(bm_filectx_t *ctx)
-{
- if (ctx == NULL)
- return;
-
- time_t tv_sec;
- long tv_nsec;
-
- if (!bm_filectx_changed(ctx, &tv_sec, &tv_nsec))
- return;
-
- ctx->tv_sec = tv_sec;
- ctx->tv_nsec = tv_nsec;
- ctx->readable = true;
-}
-
-
-void
-bm_filectx_free(bm_filectx_t *fctx)
-{
- if (fctx == NULL)
- return;
- free(fctx->path);
- free(fctx->short_path);
- free(fctx->slug);
- free(fctx);
-}
-
-
-bm_ctx_t*
-bm_ctx_new(bm_ctx_t *base, const char *settings_file, const char *argv0,
- bc_error_t **err)
-{
- if (settings_file == NULL || err == NULL || *err != NULL)
- return NULL;
-
- char *abs_filename = bm_abspath(settings_file, err);
- if (*err != NULL)
- return NULL;
-
- size_t content_len;
- char *content = bc_file_get_contents(abs_filename, true, &content_len,
- err);
- if (*err != NULL) {
- free(abs_filename);
- return NULL;
- }
-
- bm_settings_t *settings = bm_settings_parse(content, content_len, err);
- if (settings == NULL || *err != NULL) {
- free(abs_filename);
- free(content);
- return NULL;
- }
- free(content);
-
- const char *template_dir = bc_trie_lookup(settings->settings, "template_dir");
- if (template_dir == NULL)
- template_dir = "";
-
- char *atom_template = NULL;
- bool atom_template_tmp = false;
- const char *atom_template_conf = bc_trie_lookup(settings->settings,
- "atom_template");
- if (atom_template_conf != NULL) {
- atom_template = bc_strdup_printf("%s/%s", template_dir, atom_template_conf);
- }
- else {
- atom_template = bm_atom_deploy(settings, err);
- atom_template_tmp = true;
- if (*err != NULL) {
- free(abs_filename);
- bm_settings_free(settings);
- return NULL;
- }
- }
-
- bm_ctx_t *rv = NULL;
- if (base == NULL) {
- rv = bc_malloc(sizeof(bm_ctx_t));
- rv->blogc = bm_exec_find_binary(argv0, "blogc", "BLOGC");
- rv->blogc_runserver = bm_exec_find_binary(argv0, "blogc-runserver",
- "BLOGC_RUNSERVER");
- rv->dev = false;
- rv->verbose = false;
- }
- else {
- bm_ctx_free_internal(base);
- rv = base;
- }
- rv->settings = settings;
-
- rv->settings_fctx = bm_filectx_new(rv, abs_filename, NULL, NULL);
- rv->root_dir = bc_strdup(dirname(abs_filename));
- free(abs_filename);
-
- const char *output_dir = getenv("OUTPUT_DIR");
- rv->short_output_dir = bc_strdup(output_dir != NULL ? output_dir : "_build");
-
- if (rv->short_output_dir[0] == '/') {
- rv->output_dir = bc_strdup(rv->short_output_dir);
- }
- else {
- rv->output_dir = bc_strdup_printf("%s/%s", rv->root_dir,
- rv->short_output_dir);
- }
-
- // can't return null and set error after this!
-
- char *main_template = bc_strdup_printf("%s/%s", template_dir,
- bm_ctx_settings_lookup(rv, "main_template"));
- rv->main_template_fctx = bm_filectx_new(rv, main_template, NULL, NULL);
- free(main_template);
-
- rv->atom_template_tmp = atom_template_tmp;
- rv->atom_template_fctx = bm_filectx_new(rv, atom_template, NULL, NULL);
- free(atom_template);
-
- const char *content_dir = bm_ctx_settings_lookup(rv, "content_dir");
- const char *post_prefix = bm_ctx_settings_lookup(rv, "post_prefix");
- const char *source_ext = bm_ctx_settings_lookup(rv, "source_ext");
- const char *listing_entry = bm_ctx_settings_lookup(rv, "listing_entry");
-
- rv->listing_entry_fctx = NULL;
- if (listing_entry != NULL) {
- char *f = bm_generate_filename(content_dir, NULL, listing_entry, source_ext);
- rv->listing_entry_fctx = bm_filectx_new(rv, f, listing_entry, NULL);
- free(f);
- }
-
- rv->posts_fctx = NULL;
- if (settings->posts != NULL) {
- for (size_t i = 0; settings->posts[i] != NULL; i++) {
- char *f = bm_generate_filename(content_dir, post_prefix,
- settings->posts[i], source_ext);
- rv->posts_fctx = bc_slist_append(rv->posts_fctx,
- bm_filectx_new(rv, f, settings->posts[i], NULL));
- free(f);
- }
- }
-
- rv->pages_fctx = NULL;
- if (settings->pages != NULL) {
- for (size_t i = 0; settings->pages[i] != NULL; i++) {
- char *f = bm_generate_filename(content_dir, NULL, settings->pages[i],
- source_ext);
- rv->pages_fctx = bc_slist_append(rv->pages_fctx,
- bm_filectx_new(rv, f, settings->pages[i], NULL));
- free(f);
- }
- }
-
- rv->copy_fctx = NULL;
- if (settings->copy != NULL) {
- for (size_t i = 0; settings->copy[i] != NULL; i++) {
- rv->copy_fctx = bm_filectx_new_r(rv->copy_fctx, rv,
- settings->copy[i]);
- }
- }
-
- return rv;
-}
-
-
-bool
-bm_ctx_reload(bm_ctx_t **ctx)
-{
- if (*ctx == NULL || (*ctx)->settings_fctx == NULL)
- return false;
-
- if (bm_filectx_changed((*ctx)->settings_fctx, NULL, NULL)) {
- // reload everything! we could just reload settings_fctx, as this
- // would force rebuilding everything, but we need to know new/deleted
- // files
-
- // needs to dup path, because it may be freed when reloading.
- char *tmp = bc_strdup((*ctx)->settings_fctx->path);
- bc_error_t *err = NULL;
- *ctx = bm_ctx_new(*ctx, tmp, NULL, &err);
- free(tmp);
- if (err != NULL) {
- bc_error_print(err, "blogc-make");
- bc_error_free(err);
- return false;
- }
- return true;
- }
-
- bm_filectx_reload((*ctx)->main_template_fctx);
- bm_filectx_reload((*ctx)->atom_template_fctx);
- bm_filectx_reload((*ctx)->listing_entry_fctx);
-
- for (bc_slist_t *tmp = (*ctx)->posts_fctx; tmp != NULL; tmp = tmp->next)
- bm_filectx_reload((bm_filectx_t*) tmp->data);
-
- for (bc_slist_t *tmp = (*ctx)->pages_fctx; tmp != NULL; tmp = tmp->next)
- bm_filectx_reload((bm_filectx_t*) tmp->data);
-
- for (bc_slist_t *tmp = (*ctx)->copy_fctx; tmp != NULL; tmp = tmp->next)
- bm_filectx_reload((bm_filectx_t*) tmp->data);
-
- return true;
-}
-
-
-void
-bm_ctx_free_internal(bm_ctx_t *ctx)
-{
- if (ctx == NULL)
- return;
-
- bm_settings_free(ctx->settings);
- ctx->settings = NULL;
-
- free(ctx->root_dir);
- ctx->root_dir = NULL;
- free(ctx->short_output_dir);
- ctx->short_output_dir = NULL;
- free(ctx->output_dir);
- ctx->output_dir = NULL;
-
- if (ctx->atom_template_tmp)
- bm_atom_destroy(ctx->atom_template_fctx->path);
- ctx->atom_template_tmp = false;
-
- bm_filectx_free(ctx->main_template_fctx);
- ctx->main_template_fctx = NULL;
- bm_filectx_free(ctx->atom_template_fctx);
- ctx->atom_template_fctx = NULL;
- bm_filectx_free(ctx->settings_fctx);
- ctx->settings_fctx = NULL;
- bm_filectx_free(ctx->listing_entry_fctx);
- ctx->listing_entry_fctx = NULL;
-
- bc_slist_free_full(ctx->posts_fctx, (bc_free_func_t) bm_filectx_free);
- ctx->posts_fctx = NULL;
- bc_slist_free_full(ctx->pages_fctx, (bc_free_func_t) bm_filectx_free);
- ctx->pages_fctx = NULL;
- bc_slist_free_full(ctx->copy_fctx, (bc_free_func_t) bm_filectx_free);
- ctx->copy_fctx = NULL;
-}
-
-
-void
-bm_ctx_free(bm_ctx_t *ctx)
-{
- if (ctx == NULL)
- return;
- bm_ctx_free_internal(ctx);
- free(ctx->blogc);
- free(ctx->blogc_runserver);
- free(ctx);
-}
-
-
-const char*
-bm_ctx_settings_lookup(bm_ctx_t *ctx, const char *key)
-{
- if (ctx == NULL || ctx->settings == NULL || ctx->settings->settings == NULL)
- return NULL;
- return bc_trie_lookup(ctx->settings->settings, key);
-}
-
-
-const char*
-bm_ctx_settings_lookup_str(bm_ctx_t *ctx, const char *key)
-{
- const char *rv = bm_ctx_settings_lookup(ctx, key);
- return rv == NULL ? "" : rv;
-}
diff --git a/src/blogc-make/ctx.h b/src/blogc-make/ctx.h
deleted file mode 100644
index a66d51c..0000000
--- a/src/blogc-make/ctx.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _MAKE_CTX_H
-#define _MAKE_CTX_H
-
-#include <sys/stat.h>
-#include <stdbool.h>
-#include <time.h>
-#include "settings.h"
-#include "../common/error.h"
-#include "../common/utils.h"
-
-#ifdef __APPLE__
-#define st_mtim_tv_sec st_mtimespec.tv_sec
-#define st_mtim_tv_nsec st_mtimespec.tv_nsec
-#endif
-
-#ifdef __ANDROID__
-#define st_mtim_tv_sec st_mtime
-#define st_mtim_tv_nsec st_mtime_nsec
-#endif
-
-#ifndef st_mtim_tv_sec
-#define st_mtim_tv_sec st_mtim.tv_sec
-#endif
-#ifndef st_mtim_tv_nsec
-#define st_mtim_tv_nsec st_mtim.tv_nsec
-#endif
-
-
-typedef struct {
- char *path;
- char *short_path;
- char *slug;
- time_t tv_sec;
- long tv_nsec;
- bool readable;
-} bm_filectx_t;
-
-typedef struct {
- char *blogc;
- char *blogc_runserver;
-
- bool dev;
- bool verbose;
- bool atom_template_tmp;
-
- bm_settings_t *settings;
-
- char *root_dir;
- char *output_dir;
- char *short_output_dir;
-
- bm_filectx_t *main_template_fctx;
- bm_filectx_t *atom_template_fctx;
- bm_filectx_t *settings_fctx;
- bm_filectx_t *listing_entry_fctx;
-
- bc_slist_t *posts_fctx;
- bc_slist_t *pages_fctx;
- bc_slist_t *copy_fctx;
-} bm_ctx_t;
-
-bm_filectx_t* bm_filectx_new(bm_ctx_t *ctx, const char *filename, const char *slug,
- struct stat *st);
-bc_slist_t* bm_filectx_new_r(bc_slist_t *l, bm_ctx_t *ctx, const char *filename);
-bool bm_filectx_changed(bm_filectx_t *ctx, time_t *tv_sec, long *tv_nsec);
-void bm_filectx_reload(bm_filectx_t *ctx);
-void bm_filectx_free(bm_filectx_t *fctx);
-bm_ctx_t* bm_ctx_new(bm_ctx_t *base, const char *settings_file,
- const char *argv0, bc_error_t **err);
-bool bm_ctx_reload(bm_ctx_t **ctx);
-void bm_ctx_free_internal(bm_ctx_t *ctx);
-void bm_ctx_free(bm_ctx_t *ctx);
-const char* bm_ctx_settings_lookup(bm_ctx_t *ctx, const char *key);
-const char* bm_ctx_settings_lookup_str(bm_ctx_t *ctx, const char *key);
-
-#endif /* _MAKE_CTX_H */
diff --git a/src/blogc-make/exec-native.c b/src/blogc-make/exec-native.c
deleted file mode 100644
index 6d7f58f..0000000
--- a/src/blogc-make/exec-native.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <libgen.h>
-#include <errno.h>
-#include "../common/error.h"
-#include "../common/file.h"
-#include "../common/utils.h"
-#include "exec-native.h"
-#include "ctx.h"
-
-
-int
-bm_exec_native_cp(bm_filectx_t *source, bm_filectx_t *dest, bool verbose)
-{
- if (verbose)
- printf("Copying '%s' to '%s'\n", source->path, dest->path);
- else
- printf(" COPY %s\n", dest->short_path);
- fflush(stdout);
-
- char *fname = bc_strdup(dest->path);
- for (char *tmp = fname; *tmp != '\0'; tmp++) {
- if (*tmp != '/' && *tmp != '\\')
- continue;
- char bkp = *tmp;
- *tmp = '\0';
- if ((strlen(fname) > 0) &&
- (-1 == mkdir(fname, 0777)) &&
- (errno != EEXIST))
- {
- fprintf(stderr, "blogc-make: error: failed to create output "
- "directory (%s): %s\n", fname, strerror(errno));
- free(fname);
- return 1;
- }
- *tmp = bkp;
- }
- free(fname);
-
- int fd_from = open(source->path, O_RDONLY);
- if (fd_from < 0) {
- fprintf(stderr, "blogc-make: error: failed to open source file to copy "
- " (%s): %s\n", source->path, strerror(errno));
- return 1;
- }
-
- int fd_to = open(dest->path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
- if (fd_to < 0) {
- fprintf(stderr, "blogc-make: error: failed to open destination file to "
- "copy (%s): %s\n", dest->path, strerror(errno));
- close(fd_from);
- return 1;
- }
-
- ssize_t nread;
- char buffer[BC_FILE_CHUNK_SIZE];
- while (0 < (nread = read(fd_from, buffer, BC_FILE_CHUNK_SIZE))) {
- char *out_ptr = buffer;
- do {
- ssize_t nwritten = write(fd_to, out_ptr, nread);
- if (nwritten == -1) {
- fprintf(stderr, "blogc-make: error: failed to write to "
- "destination file (%s): %s\n", dest->path, strerror(errno));
- close(fd_from);
- close(fd_to);
- return 1;
- }
- nread -= nwritten;
- out_ptr += nwritten;
- } while (nread > 0);
- }
-
- close(fd_from);
- close(fd_to);
-
- return 0;
-}
-
-
-bool
-bm_exec_native_is_empty_dir(const char *dir, bc_error_t **err)
-{
- DIR *d = opendir(dir);
- if (d == NULL) {
- if (errno == ENOENT) {
- return true;
- }
- if (err != NULL) {
- *err = bc_error_new_printf(0, "failed to open directory (%s): %s\n",
- dir, strerror(errno));
- }
- return true;
- }
-
- struct dirent *e;
- size_t count = 0;
- while (NULL != (e = readdir(d))) {
- if ((0 == strcmp(e->d_name, ".")) || (0 == strcmp(e->d_name, "..")))
- continue;
- count++;
- break;
- }
-
- if (0 != closedir(d)) {
- if (err != NULL) {
- *err = bc_error_new_printf(0, "failed to close directory (%s): %s\n",
- dir, strerror(errno));
- }
- return true;
- }
-
- return count == 0;
-}
-
-
-int
-bm_exec_native_rm(const char *output_dir, bm_filectx_t *dest, bool verbose)
-{
- if (verbose)
- printf("Removing file '%s'\n", dest->path);
- else
- printf(" CLEAN %s\n", dest->short_path);
- fflush(stdout);
-
- if (0 != unlink(dest->path)) {
- fprintf(stderr, "blogc-make: error: failed to remove file (%s): %s\n",
- dest->path, strerror(errno));
- return 1;
- }
-
- int rv = 0;
-
- // blame freebsd's libc for all of those memory allocations around dirname
- // calls!
- char *short_dir = bc_strdup(dirname(dest->short_path));
- char *dir = bc_strdup(dirname(dest->path));
-
- bc_error_t *err = NULL;
-
- while ((0 != strcmp(short_dir, ".")) && (0 != strcmp(short_dir, "/"))) {
- bool empty = bm_exec_native_is_empty_dir(dir, &err);
- if (err != NULL) {
- fprintf(stderr, "blogc-make: error: %s\n", err->msg);
- bc_error_free(err);
- rv = 1;
- break;
- }
- if (!empty) {
- break;
- }
- if (verbose) {
- printf("Removing directory '%s'\n", dir);
- fflush(stdout);
- }
- if (0 != rmdir(dir)) {
- fprintf(stderr,
- "blogc-make: error: failed to remove directory(%s): %s\n",
- dir, strerror(errno));
- rv = 1;
- break;
- }
- if (0 == strcmp(dir, output_dir)) {
- break;
- }
-
- char *tmp = short_dir;
- short_dir = bc_strdup(dirname(short_dir));
- free(tmp);
- tmp = dir;
- dir = bc_strdup(dirname(dir));
- free(tmp);
- }
-
- free(short_dir);
- free(dir);
-
- return rv;
-}
diff --git a/src/blogc-make/exec-native.h b/src/blogc-make/exec-native.h
deleted file mode 100644
index 56a1da1..0000000
--- a/src/blogc-make/exec-native.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _MAKE_EXEC_NATIVE_H
-#define _MAKE_EXEC_NATIVE_H
-
-#include <stdbool.h>
-#include "../common/error.h"
-#include "ctx.h"
-
-int bm_exec_native_cp(bm_filectx_t *source, bm_filectx_t *dest, bool verbose);
-bool bm_exec_native_is_empty_dir(const char *dir, bc_error_t **err);
-int bm_exec_native_rm(const char *output_dir, bm_filectx_t *dest, bool verbose);
-
-#endif /* _MAKE_EXEC_NATIVE_H */
diff --git a/src/blogc-make/exec.c b/src/blogc-make/exec.c
deleted file mode 100644
index 4b1f6df..0000000
--- a/src/blogc-make/exec.c
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif /* HAVE_CONFIG_H */
-
-#ifdef HAVE_SYSEXITS_H
-#include <sysexits.h>
-#else
-#define EX_CONFIG 78
-#endif /* HAVE_SYSEXITS_H */
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <libgen.h>
-#include "../common/compat.h"
-#include "../common/error.h"
-#include "../common/file.h"
-#include "../common/utils.h"
-#include "ctx.h"
-#include "exec.h"
-#include "settings.h"
-
-
-char*
-bm_exec_find_binary(const char *argv0, const char *bin, const char *env)
-{
-#ifdef MAKE_EMBEDDED
- // for embedded blogc-make, if we are looking for blogc, we just return
- // argv0, because the static binary may not be named `blogc`, and we
- // prefer to use our own `blogc` instead of some other version around.
- if (argv0 != NULL && bin != NULL && (0 == strcmp(bin, "blogc"))) {
- return bc_shell_quote(argv0);
- }
-#endif
-
- // first try: env var
- const char *env_bin = getenv(env);
- if (env_bin != NULL) {
- return bc_shell_quote(env_bin);
- }
-
- // second try: same dir as current exec
- // we rely on some assumptions here:
- //
- // - if binary is called without a directory, that means location will
- // be resolved from $PATH, we don't care about doing a dir lookup.
- // - we *never* call chdir anywhere in the code, so we can assume
- // that relative paths will work as expected.
- // - windows path sep is not supported
- if (argv0 != NULL && (NULL != strchr(argv0, '/'))) {
- char *path = bc_strdup(argv0);
- char *dir = bc_strdup(dirname(path));
- free(path);
- char *tmp = bc_strdup_printf("%s/%s", dir, bin);
- free(dir);
- if (0 == access(tmp, X_OK)) {
- char *rv = bc_shell_quote(tmp);
- free(tmp);
- return rv;
- }
- free(tmp);
- }
-
- // last try: $PATH
- return bc_strdup(bin);
-}
-
-
-int
-bm_exec_command(const char *cmd, const char *input, char **output,
- char **error, bc_error_t **err)
-{
- if (err == NULL || *err != NULL)
- return 1;
-
- int fd_in[2];
- if (-1 == pipe(fd_in)) {
- *err = bc_error_new_printf(BLOGC_MAKE_ERROR_EXEC,
- "Failed to create stdin pipe: %s", strerror(errno));
- return 1;
- }
-
- int fd_out[2];
- if (-1 == pipe(fd_out)) {
- *err = bc_error_new_printf(BLOGC_MAKE_ERROR_EXEC,
- "Failed to create stdout pipe: %s", strerror(errno));
- close(fd_in[0]);
- close(fd_in[1]);
- return 1;
- }
-
- int fd_err[2];
- if (-1 == pipe(fd_err)) {
- *err = bc_error_new_printf(BLOGC_MAKE_ERROR_EXEC,
- "Failed to create stderr pipe: %s", strerror(errno));
- close(fd_in[0]);
- close(fd_in[1]);
- close(fd_out[0]);
- close(fd_out[1]);
- return 1;
- }
-
- pid_t pid = fork();
- if (pid == -1) {
- *err = bc_error_new_printf(BLOGC_MAKE_ERROR_EXEC,
- "Failed to fork: %s", strerror(errno));
- close(fd_in[0]);
- close(fd_in[1]);
- close(fd_out[0]);
- close(fd_out[1]);
- close(fd_err[0]);
- close(fd_err[1]);
- return 1;
- }
-
- // child
- if (pid == 0) {
- close(fd_in[1]);
- close(fd_out[0]);
- close(fd_err[0]);
-
- dup2(fd_in[0], STDIN_FILENO);
- dup2(fd_out[1], STDOUT_FILENO);
- dup2(fd_err[1], STDERR_FILENO);
-
- char *const argv[] = {
- "/bin/sh",
- "-c",
- (char*) cmd,
- NULL,
- };
-
- execv(argv[0], argv);
-
- exit(1);
- }
-
- // parent
- close(fd_in[0]);
- close(fd_out[1]);
- close(fd_err[1]);
-
- if (input != NULL) {
- if (-1 == write(fd_in[1], input, strlen(input))) {
- *err = bc_error_new_printf(BLOGC_MAKE_ERROR_EXEC,
- "Failed to write to stdin pipe: %s", strerror(errno));
- close(fd_in[1]);
- close(fd_out[0]);
- close(fd_err[0]);
- return 1;
- }
- }
-
- close(fd_in[1]);
-
- char buffer[BC_FILE_CHUNK_SIZE];
- ssize_t s;
-
- bc_string_t *out = NULL;
- while(0 != (s = read(fd_out[0], buffer, BC_FILE_CHUNK_SIZE))) {
- if (s == -1) {
- *err = bc_error_new_printf(BLOGC_MAKE_ERROR_EXEC,
- "Failed to read from stdout pipe: %s", strerror(errno));
- close(fd_out[0]);
- close(fd_err[0]);
- bc_string_free(out, true);
- return 1;
- }
- if (out == NULL) {
- out = bc_string_new();
- }
- bc_string_append_len(out, buffer, s);
- }
- if (out != NULL) {
- *output = bc_string_free(out, false);
- }
- close(fd_out[0]);
-
- out = NULL;
- while(0 != (s = read(fd_err[0], buffer, BC_FILE_CHUNK_SIZE))) {
- if (s == -1) {
- *err = bc_error_new_printf(BLOGC_MAKE_ERROR_EXEC,
- "Failed to read from stderr pipe: %s", strerror(errno));
- close(fd_err[0]);
- bc_string_free(out, true);
- return 1;
- }
- if (out == NULL)
- out = bc_string_new();
- bc_string_append_len(out, buffer, s);
- }
- if (out != NULL) {
- *error = bc_string_free(out, false);
- }
- close(fd_err[0]);
-
- int status;
- waitpid(pid, &status, 0);
-
- return bc_compat_status_code(status);
-}
-
-
-static void
-list_variables(const char *key, const char *value, bc_string_t *str)
-{
- char *tmp = bc_shell_quote(value);
- bc_string_append_printf(str, " -D %s=%s", key, tmp);
- free(tmp);
-}
-
-
-char*
-bm_exec_build_blogc_cmd(const char *blogc_bin, bm_settings_t *settings,
- bc_trie_t *global_variables, bc_trie_t *local_variables, const char *print,
- bool listing, const char *listing_entry, const char *template,
- const char *output, bool dev, bool sources_stdin)
-{
- bc_string_t *rv = bc_string_new();
-
- const char *locale = NULL;
- if (settings != NULL) {
- locale = bc_trie_lookup(settings->settings, "locale");
- }
- if (locale != NULL) {
- char *tmp = bc_shell_quote(locale);
- bc_string_append_printf(rv, "LC_ALL=%s ", tmp);
- free(tmp);
- }
-
- bc_string_append(rv, blogc_bin);
-
- if (settings != NULL) {
- if (settings->tags != NULL) {
- char *tags = bc_strv_join(settings->tags, " ");
- bc_string_append_printf(rv, " -D MAKE_TAGS='%s'", tags);
- free(tags);
- }
-
- bc_trie_foreach(settings->global,
- (bc_trie_foreach_func_t) list_variables, rv);
- }
-
- bc_trie_foreach(global_variables, (bc_trie_foreach_func_t) list_variables, rv);
- bc_trie_foreach(local_variables, (bc_trie_foreach_func_t) list_variables, rv);
-
- if (dev) {
- bc_string_append(rv, " -D MAKE_ENV_DEV=1 -D MAKE_ENV='dev'");
- }
-
- if (print != NULL) {
- bc_string_append_printf(rv, " -p %s", print);
- }
-
- if (listing) {
- bc_string_append(rv, " -l");
- if (listing_entry != NULL) {
- char *tmp = bc_shell_quote(listing_entry);
- bc_string_append_printf(rv, " -e %s", tmp);
- free(tmp);
- }
- }
-
- if (template != NULL) {
- char *tmp = bc_shell_quote(template);
- bc_string_append_printf(rv, " -t %s", tmp);
- free(tmp);
- }
-
- if (output != NULL) {
- char *tmp = bc_shell_quote(output);
- bc_string_append_printf(rv, " -o %s", tmp);
- free(tmp);
- }
-
- if (sources_stdin) {
- bc_string_append(rv, " -i");
- }
-
- return bc_string_free(rv, false);
-}
-
-
-int
-bm_exec_blogc(bm_ctx_t *ctx, bc_trie_t *global_variables, bc_trie_t *local_variables,
- bool listing, bm_filectx_t *listing_entry, bm_filectx_t *template,
- bm_filectx_t *output, bc_slist_t *sources, bool only_first_source)
-{
- if (ctx == NULL)
- return 1;
-
- bc_string_t *input = bc_string_new();
- for (bc_slist_t *l = sources; l != NULL; l = l->next) {
- bc_string_append_printf(input, "%s\n", ((bm_filectx_t*) l->data)->path);
- if (only_first_source)
- break;
- }
-
- char *cmd = bm_exec_build_blogc_cmd(ctx->blogc, ctx->settings, global_variables,
- local_variables, NULL, listing, listing_entry == NULL ? NULL : listing_entry->path,
- template->path, output->path, ctx->dev, input->len > 0);
-
- if (ctx->verbose)
- printf("%s\n", cmd);
- else
- printf(" BLOGC %s\n", output->short_path);
- fflush(stdout);
-
- char *out = NULL;
- char *err = NULL;
- bc_error_t *error = NULL;
-
- int rv = bm_exec_command(cmd, input->str, &out, &err, &error);
-
- if (error != NULL) {
- bc_error_print(error, "blogc-make");
- free(cmd);
- free(out);
- free(err);
- bc_string_free(input, true);
- bc_error_free(error);
- return 1;
- }
-
- if (rv != 0 && ctx->verbose) {
- fprintf(stderr,
- "blogc-make: error: Failed to execute command.\n"
- "\n"
- "STATUS CODE: %d\n", rv);
- if (input->len > 0) {
- fprintf(stderr, "\nSTDIN:\n"
- "----------------------------->8-----------------------------\n"
- "%s\n"
- "----------------------------->8-----------------------------\n",
- bc_str_strip(input->str));
- }
- if (out != NULL) {
- fprintf(stderr, "\nSTDOUT:\n"
- "----------------------------->8-----------------------------\n"
- "%s\n"
- "----------------------------->8-----------------------------\n",
- bc_str_strip(out));
- }
- if (err != NULL) {
- fprintf(stderr, "\nSTDERR:\n"
- "----------------------------->8-----------------------------\n"
- "%s\n"
- "----------------------------->8-----------------------------\n",
- bc_str_strip(err));
- }
- fprintf(stderr, "\n");
- }
- else if (err != NULL) {
- fprintf(stderr, "%s\n", err);
- }
-
- bc_string_free(input, true);
- free(cmd);
- free(out);
- free(err);
-
- return rv == 127 ? 1 : rv;
-}
-
-
-char*
-bm_exec_blogc_get_variable(bm_ctx_t *ctx, bc_trie_t *global_variables,
- bc_trie_t *local_variables, const char *variable, bool listing,
- bc_slist_t *sources, bool only_first_source)
-{
- if (ctx == NULL)
- return NULL;
-
- bc_string_t *input = bc_string_new();
- for (bc_slist_t *l = sources; l != NULL; l = l->next) {
- bc_string_append_printf(input, "%s\n", ((bm_filectx_t*) l->data)->path);
- if (only_first_source)
- break;
- }
-
- char *cmd = bm_exec_build_blogc_cmd(ctx->blogc, ctx->settings, global_variables,
- local_variables, variable, listing, NULL, NULL, NULL, ctx->dev, input->len > 0);
-
- if (ctx->verbose)
- printf("%s\n", cmd);
- fflush(stdout);
-
- char *out = NULL;
- char *err = NULL;
- bc_error_t *error = NULL;
-
- int rv = bm_exec_command(cmd, input->str, &out, &err, &error);
-
- if (error != NULL) {
- bc_error_print(error, "blogc-make");
- bc_error_free(error);
- bc_string_free(input, true);
- free(cmd);
- free(out);
- free(err);
- return NULL;
- }
-
- if (rv != 0) {
- if (rv != EX_CONFIG)
- fprintf(stderr, "blogc-make: error: %s\n", bc_str_strip(err));
- bc_string_free(input, true);
- free(cmd);
- free(out);
- free(err);
- return NULL;
- }
-
- char *val = NULL;
- if (out != NULL)
- val = bc_strndup(out, strlen(out) - 1);
-
- bc_string_free(input, true);
- free(cmd);
- free(out);
- free(err);
-
- return val;
-}
-
-
-int
-bm_exec_blogc_runserver(bm_ctx_t *ctx, const char *host, const char *port,
- const char *threads)
-{
- if (ctx == NULL)
- return 1;
-
- bc_string_t *cmd = bc_string_new();
-
- bc_string_append(cmd, ctx->blogc_runserver);
-
- if (host != NULL) {
- char *tmp = bc_shell_quote(host);
- bc_string_append_printf(cmd, " -t %s", tmp);
- free(tmp);
- }
-
- if (port != NULL) {
- char *tmp = bc_shell_quote(port);
- bc_string_append_printf(cmd, " -p %s", tmp);
- free(tmp);
- }
-
- if (threads != NULL) {
- char *tmp = bc_shell_quote(threads);
- bc_string_append_printf(cmd, " -m %s", tmp);
- free(tmp);
- }
-
- char *tmp = bc_shell_quote(ctx->output_dir);
- bc_string_append_printf(cmd, " %s", tmp);
- free(tmp);
-
- if (ctx->verbose)
- printf("%s\n\n", cmd->str);
- else
- printf("\n");
- fflush(stdout);
-
- // we don't need pipes to run blogc-runserver, because it is "interactive"
- int status = system(cmd->str);
- int rv = bc_compat_status_code(status);
- bc_string_free(cmd, true);
-
- if (rv != 0 && rv != 130) {
- if (rv == 127) {
- fprintf(stderr,
- "blogc-make: error: blogc-runserver command not found. Maybe "
- "it is not installed?\n");
- rv = 1; // blogc-make exists, so we should not return 127
- }
- else {
- fprintf(stderr,
- "blogc-make: error: Failed to execute command, returned "
- "status code: %d\n", rv);
- }
- }
-
- return rv;
-}
diff --git a/src/blogc-make/exec.h b/src/blogc-make/exec.h
deleted file mode 100644
index 6bc206f..0000000
--- a/src/blogc-make/exec.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _MAKE_EXEC_H
-#define _MAKE_EXEC_H
-
-#include <stdbool.h>
-#include "../common/error.h"
-#include "../common/utils.h"
-#include "ctx.h"
-#include "settings.h"
-
-char* bm_exec_find_binary(const char *argv0, const char *bin, const char *env);
-int bm_exec_command(const char *cmd, const char *input, char **output,
- char **error, bc_error_t **err);
-char* bm_exec_build_blogc_cmd(const char *blogc_bin, bm_settings_t *settings,
- bc_trie_t *global_variables, bc_trie_t *local_variables, const char *print,
- bool listing, const char *listing_entry, const char *template,
- const char *output, bool dev, bool sources_stdin);
-int bm_exec_blogc(bm_ctx_t *ctx, bc_trie_t *global_variables,
- bc_trie_t *local_variables, bool listing, bm_filectx_t *listing_entry,
- bm_filectx_t *template, bm_filectx_t *output, bc_slist_t *sources,
- bool only_first_source);
-char* bm_exec_blogc_get_variable(bm_ctx_t *ctx, bc_trie_t *global_variables,
- bc_trie_t *local_variables, const char *variable, bool listing,
- bc_slist_t *sources, bool only_first_source);
-int bm_exec_blogc_runserver(bm_ctx_t *ctx, const char *host, const char *port,
- const char *threads);
-
-#endif /* _MAKE_EXEC_H */
diff --git a/src/blogc-make/httpd.c b/src/blogc-make/httpd.c
deleted file mode 100644
index c352da0..0000000
--- a/src/blogc-make/httpd.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <pthread.h>
-#include <unistd.h>
-#include "../common/utils.h"
-#include "ctx.h"
-#include "exec.h"
-#include "reloader.h"
-#include "httpd.h"
-
-// we are not going to unit-test these functions, then printing errors
-// directly is not a big issue
-
-
-typedef struct {
- bm_ctx_t *ctx;
- bc_trie_t *args;
-} bm_httpd_t;
-
-static pthread_mutex_t mutex_httpd_starting = PTHREAD_MUTEX_INITIALIZER;
-static bool httpd_starting = false;
-
-
-static void*
-httpd_thread(void *arg)
-{
- bm_httpd_t *httpd = arg;
-
- pthread_mutex_lock(&mutex_httpd_starting);
- httpd_starting = true;
- pthread_mutex_unlock(&mutex_httpd_starting);
-
- int rv = bm_exec_blogc_runserver(httpd->ctx, bc_trie_lookup(httpd->args, "host"),
- bc_trie_lookup(httpd->args, "port"), bc_trie_lookup(httpd->args, "threads"));
-
- pthread_mutex_lock(&mutex_httpd_starting);
- httpd_starting = false;
- pthread_mutex_unlock(&mutex_httpd_starting);
-
- free(httpd);
-
- // stop the reloader
- bm_reloader_stop(rv);
-
- return NULL;
-}
-
-
-int
-bm_httpd_run(bm_ctx_t **ctx, bm_rule_exec_func_t rule_exec, bc_slist_t *outputs,
- bc_trie_t *args)
-{
- pthread_mutex_lock(&mutex_httpd_starting);
- bool starting = httpd_starting;
- pthread_mutex_unlock(&mutex_httpd_starting);
-
- if (starting) {
- fprintf(stderr, "blogc-make: error: httpd already running\n");
- return 1;
- }
-
- int err;
-
- pthread_attr_t attr;
- if (0 != (err = pthread_attr_init(&attr))) {
- fprintf(stderr, "blogc-make: error: failed to initialize httpd "
- "thread attributes: %s\n", strerror(err));
- return 1;
- }
-
- // we run the thread detached, because we don't want to wait it to join
- // before exiting. the OS can clean it properly
- if (0 != (err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED))) {
- fprintf(stderr, "blogc-make: error: failed to mark httpd thread as "
- "detached: %s\n", strerror(err));
- return 1;
- }
-
- bm_httpd_t *rv = bc_malloc(sizeof(bm_httpd_t));
- rv->ctx = *ctx;
- rv->args = args;
-
- pthread_t thread;
- if (0 != (err = pthread_create(&thread, &attr, httpd_thread, rv))) {
- fprintf(stderr, "blogc-make: error: failed to create httpd "
- "thread: %s\n", strerror(err));
- free(rv);
- return 1;
- }
-
- // we could use some pthread_*_timedwait() apis here, but I decided to
- // just use simple mutexes for the sake of portability.
- size_t count = 0;
- while (true) {
- pthread_mutex_lock(&mutex_httpd_starting);
- starting = httpd_starting;
- pthread_mutex_unlock(&mutex_httpd_starting);
-
- if (starting)
- break;
-
- if (++count > 100) {
- fprintf(stderr, "blogc-make: error: failed to start httpd thread: "
- "too many retries\n");
- // rv will leak, but it is not safe to free here
- return 1;
- }
- usleep(100000);
- }
-
- return bm_reloader_run(ctx, rule_exec, outputs, args);
-}
diff --git a/src/blogc-make/httpd.h b/src/blogc-make/httpd.h
deleted file mode 100644
index b0fa87d..0000000
--- a/src/blogc-make/httpd.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _MAKE_HTTPD_H
-#define _MAKE_HTTPD_H
-
-#include "../common/utils.h"
-#include "ctx.h"
-#include "rules.h"
-
-int bm_httpd_run(bm_ctx_t **ctx, bm_rule_exec_func_t rule_exec, bc_slist_t *outputs,
- bc_trie_t *args);
-
-#endif /* _MAKE_HTTPD_H */
diff --git a/src/blogc-make/main.c b/src/blogc-make/main.c
deleted file mode 100644
index 5b4a030..0000000
--- a/src/blogc-make/main.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif /* HAVE_CONFIG_H */
-
-#include <locale.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "../common/error.h"
-#include "../common/utils.h"
-#include "ctx.h"
-#include "rules.h"
-
-
-static void
-print_help(void)
-{
- printf(
- "usage:\n"
- " blogc-make [-h] [-v] [-D] [-V] [-f FILE] [RULE ...]\n"
- " - A simple build tool for blogc.\n"
- "\n"
- "positional arguments:\n"
- " RULE build rule(s) to run. can include comma-separated\n"
- " key-value pairs of rule arguments in the format\n"
- " RULE:arg1=value1,arg2=value2,... (default: all)\n"
- "\n"
- "optional arguments:\n"
- " -h show this help message and exit\n"
- " -v show version and exit\n"
- " -D build for development environment\n"
- " -V be verbose when executing commands\n"
- " -f FILE read FILE as blogcfile\n");
- bm_rule_print_help();
-}
-
-
-static void
-print_usage(void)
-{
- printf("usage: blogc-make [-h] [-v] [-D] [-V] [-f FILE] [RULE ...]\n");
-}
-
-
-int
-#ifdef MAKE_EMBEDDED
-bm_main(int argc, char **argv)
-#else
-main(int argc, char **argv)
-#endif
-{
- setlocale(LC_ALL, "");
-
- int rv = 0;
- bc_error_t *err = NULL;
-
- bc_slist_t *rules = NULL;
- bool verbose = false;
- bool dev = false;
- char *blogcfile = NULL;
- bm_ctx_t *ctx = NULL;
-
- for (size_t i = 1; i < argc; i++) {
- if (argv[i][0] == '-') {
- switch (argv[i][1]) {
- case 'h':
- print_help();
- goto cleanup;
- case 'v':
- printf("%s\n", PACKAGE_STRING);
- goto cleanup;
- case 'D':
- dev = true;
- break;
- case 'V':
- verbose = true;
- break;
- case 'f':
- if (argv[i][2] != '\0')
- blogcfile = bc_strdup(argv[i] + 2);
- else if (i + 1 < argc)
- blogcfile = bc_strdup(argv[++i]);
- break;
-#ifdef MAKE_EMBEDDED
- case 'm':
- // no-op, for embedding into blogc binary.
- break;
-#endif
- default:
- print_usage();
- fprintf(stderr, "blogc-make: error: invalid argument: "
- "-%c\n", argv[i][1]);
- rv = 1;
- goto cleanup;
- }
- }
- else {
- rules = bc_slist_append(rules, bc_strdup(argv[i]));
- }
- }
-
- if (rules == NULL) {
- rules = bc_slist_append(rules, bc_strdup("all"));
- }
-
- ctx = bm_ctx_new(NULL, blogcfile ? blogcfile : "blogcfile",
- argc > 0 ? argv[0] : NULL, &err);
- if (err != NULL) {
- bc_error_print(err, "blogc-make");
- rv = 1;
- goto cleanup;
- }
- ctx->dev = dev;
- ctx->verbose = verbose;
-
- rv = bm_rule_executor(ctx, rules);
-
-cleanup:
-
- bc_slist_free_full(rules, free);
- free(blogcfile);
- bm_ctx_free(ctx);
- bc_error_free(err);
-
- return rv;
-}
diff --git a/src/blogc-make/reloader.c b/src/blogc-make/reloader.c
deleted file mode 100644
index fea8bd4..0000000
--- a/src/blogc-make/reloader.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <string.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <errno.h>
-#include "../common/utils.h"
-#include "ctx.h"
-#include "rules.h"
-#include "reloader.h"
-
-// we are not going to unit-test these functions, then printing errors
-// directly is not a big issue
-
-static pthread_mutex_t mutex_running = PTHREAD_MUTEX_INITIALIZER;
-static bool running = false;
-static int reloader_status_code = 0;
-static void (*handler_func)(int) = NULL;
-
-static void
-sig_handler(int signum)
-{
- bm_reloader_stop(signum + 128);
-}
-
-
-int
-bm_reloader_run(bm_ctx_t **ctx, bm_rule_exec_func_t rule_exec,
- bc_slist_t *outputs, bc_trie_t *args)
-{
- // install ^C handler
- struct sigaction current_action;
- if (sigaction(SIGINT, NULL, &current_action) < 0) {
- fprintf(stderr, "blogc-make: failed to run reloader: %s\n", strerror(errno));
- return 1;
- }
- if (current_action.sa_handler != sig_handler) { // not installed yet
- // backup current handler
- pthread_mutex_lock(&mutex_running);
- handler_func = current_action.sa_handler;
- pthread_mutex_unlock(&mutex_running);
-
- // set new handler
- struct sigaction new_action;
- new_action.sa_handler = sig_handler;
- sigemptyset(&new_action.sa_mask);
- new_action.sa_flags = 0;
- if (sigaction(SIGINT, &new_action, NULL) < 0) {
- fprintf(stderr, "blogc-make: failed to run reloader: %s\n",
- strerror(errno));
- return 1;
- }
- }
-
- pthread_mutex_lock(&mutex_running);
- running = true;
- pthread_mutex_unlock(&mutex_running);
-
- while (running) {
- if (!bm_ctx_reload(ctx)) {
- fprintf(stderr, "blogc-make: warning: failed to reload context. "
- "retrying in 5 seconds ...\n\n");
- sleep(5);
- continue;
- }
- if (0 != rule_exec(*ctx, outputs, args)) {
- fprintf(stderr, "blogc-make: warning: failed to rebuild website. "
- "retrying in 5 seconds ...\n\n");
- sleep(5);
- continue;
- }
- sleep(1);
- }
-
- return reloader_status_code;
-}
-
-
-void
-bm_reloader_stop(int status_code)
-{
- pthread_mutex_lock(&mutex_running);
-
- running = false;
- reloader_status_code = status_code;
-
- // reraise if SIGINT
- if (status_code == SIGINT + 128) {
-
- // reinstall old ^C handler
- struct sigaction new_action;
- new_action.sa_handler = handler_func;
- sigemptyset(&new_action.sa_mask);
- new_action.sa_flags = 0;
- sigaction(SIGINT, &new_action, NULL);
-
- // run it
- raise(SIGINT);
-
- // SIGINT will usually kill the process, but in the case that the
- // `handler_func` prevents it, our custom handler will be reinstalled
- // by `bm_reloader_run`.
- }
-
- pthread_mutex_unlock(&mutex_running);
-}
diff --git a/src/blogc-make/reloader.h b/src/blogc-make/reloader.h
deleted file mode 100644
index f3fddf4..0000000
--- a/src/blogc-make/reloader.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _MAKE_RELOADER_H
-#define _MAKE_RELOADER_H
-
-#include "../common/utils.h"
-#include "ctx.h"
-#include "rules.h"
-
-int bm_reloader_run(bm_ctx_t **ctx, bm_rule_exec_func_t rule_exec,
- bc_slist_t *outputs, bc_trie_t *args);
-void bm_reloader_stop(int status_code);
-
-#endif /* _MAKE_RELOADER_H */
diff --git a/src/blogc-make/rules.c b/src/blogc-make/rules.c
deleted file mode 100644
index 7d92b95..0000000
--- a/src/blogc-make/rules.c
+++ /dev/null
@@ -1,1078 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-#include "../common/utils.h"
-#include "atom.h"
-#include "ctx.h"
-#include "exec.h"
-#include "exec-native.h"
-#include "httpd.h"
-#include "reloader.h"
-#include "settings.h"
-#include "utils.h"
-#include "rules.h"
-
-
-static void
-posts_ordering(bm_ctx_t *ctx, bc_trie_t *variables, const char *variable)
-{
- if (ctx == NULL)
- return; // something is wrong, let's not add any variable
-
- const char *value = bm_ctx_settings_lookup_str(ctx, variable);
- bool asc = 0 == strcasecmp(value, "asc");
- bool sort = bc_str_to_bool(bm_ctx_settings_lookup(ctx, "posts_sort"));
-
- if (sort) {
- bc_trie_insert(variables, "FILTER_SORT", bc_strdup("1"));
- }
-
- if ((sort && asc) || (!sort && !asc)) {
- bc_trie_insert(variables, "FILTER_REVERSE", bc_strdup("1"));
- }
-}
-
-
-static void
-posts_pagination(bm_ctx_t *ctx, bc_trie_t *variables, const char *variable)
-{
- if (ctx == NULL)
- return; // something is wrong, let's not add any variable
-
- long posts_per_page = strtol(bm_ctx_settings_lookup_str(ctx, variable), NULL, 10);
- if (posts_per_page >= 0) {
- bc_trie_insert(variables, "FILTER_PAGE", bc_strdup("1"));
- bc_trie_insert(variables, "FILTER_PER_PAGE",
- bc_strdup(bm_ctx_settings_lookup(ctx, variable)));
- }
-}
-
-
-static bool
-posts_pagination_enabled(bm_ctx_t *ctx, const char *variable)
-{
- if (ctx == NULL)
- return false;
-
- long posts_per_page = strtol(bm_ctx_settings_lookup_str(ctx, variable), NULL, 10);
- return posts_per_page != 0;
-}
-
-
-// INDEX RULE
-
-static bc_slist_t*
-index_outputlist(bm_ctx_t *ctx)
-{
- if (ctx == NULL || ctx->settings->posts == NULL)
- return NULL;
-
- if (!posts_pagination_enabled(ctx, "posts_per_page"))
- return NULL;
-
- bc_slist_t *rv = NULL;
-
- const char *index_prefix = bm_ctx_settings_lookup(ctx, "index_prefix");
- const char *html_ext = bm_ctx_settings_lookup(ctx, "html_ext");
-
- char *f = bm_generate_filename(ctx->short_output_dir, index_prefix, NULL,
- html_ext);
- rv = bc_slist_append(rv, bm_filectx_new(ctx, f, NULL, NULL));
- free(f);
-
- return rv;
-}
-
-static int
-index_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
-{
- if (ctx == NULL || ctx->settings->posts == NULL)
- return 0;
-
- int rv = 0;
-
- bc_trie_t *variables = bc_trie_new(free);
- posts_pagination(ctx, variables, "posts_per_page");
- posts_ordering(ctx, variables, "html_order");
- bc_trie_insert(variables, "DATE_FORMAT",
- bc_strdup(bm_ctx_settings_lookup_str(ctx, "date_format")));
- bc_trie_insert(variables, "MAKE_RULE", bc_strdup("index"));
- bc_trie_insert(variables, "MAKE_TYPE", bc_strdup("post"));
-
- for (bc_slist_t *l = outputs; l != NULL; l = l->next) {
- bm_filectx_t *fctx = l->data;
- if (fctx == NULL)
- continue;
- if (bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx,
- ctx->listing_entry_fctx, ctx->main_template_fctx, fctx, false))
- {
- rv = bm_exec_blogc(ctx, variables, NULL, true, ctx->listing_entry_fctx,
- ctx->main_template_fctx, fctx, ctx->posts_fctx, false);
- if (rv != 0)
- break;
- }
- }
-
- bc_trie_free(variables);
-
- return rv;
-}
-
-
-// ATOM RULE
-
-static bc_slist_t*
-atom_outputlist(bm_ctx_t *ctx)
-{
- if (ctx == NULL || ctx->settings->posts == NULL)
- return NULL;
-
- if (!posts_pagination_enabled(ctx, "atom_posts_per_page"))
- return NULL;
-
- bc_slist_t *rv = NULL;
-
- const char *atom_prefix = bm_ctx_settings_lookup(ctx, "atom_prefix");
- const char *atom_ext = bm_ctx_settings_lookup(ctx, "atom_ext");
-
- char *f = bm_generate_filename(ctx->short_output_dir, atom_prefix, NULL,
- atom_ext);
- rv = bc_slist_append(rv, bm_filectx_new(ctx, f, NULL, NULL));
- free(f);
-
- return rv;
-}
-
-static int
-atom_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
-{
- if (ctx == NULL || ctx->settings->posts == NULL)
- return 0;
-
- int rv = 0;
-
- bc_trie_t *variables = bc_trie_new(free);
- posts_pagination(ctx, variables, "atom_posts_per_page");
- posts_ordering(ctx, variables, "atom_order");
- bc_trie_insert(variables, "DATE_FORMAT", bc_strdup("%Y-%m-%dT%H:%M:%SZ"));
- bc_trie_insert(variables, "MAKE_RULE", bc_strdup("atom"));
- bc_trie_insert(variables, "MAKE_TYPE", bc_strdup("atom"));
-
- for (bc_slist_t *l = outputs; l != NULL; l = l->next) {
- bm_filectx_t *fctx = l->data;
- if (fctx == NULL)
- continue;
- if (bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx, NULL,
- ctx->atom_template_tmp ? NULL : ctx->atom_template_fctx,
- fctx, false))
- {
- rv = bm_exec_blogc(ctx, variables, NULL, true, NULL, ctx->atom_template_fctx,
- fctx, ctx->posts_fctx, false);
- if (rv != 0)
- break;
- }
- }
-
- bc_trie_free(variables);
-
- return rv;
-}
-
-
-// ATOM TAGS RULE
-
-static bc_slist_t*
-atom_tags_outputlist(bm_ctx_t *ctx)
-{
- if (ctx == NULL || ctx->settings->posts == NULL || ctx->settings->tags == NULL)
- return NULL;
-
- if (!posts_pagination_enabled(ctx, "atom_posts_per_page"))
- return NULL;
-
- bc_slist_t *rv = NULL;
-
- const char *atom_prefix = bm_ctx_settings_lookup(ctx, "atom_prefix");
- const char *atom_ext = bm_ctx_settings_lookup(ctx, "atom_ext");
-
- for (size_t i = 0; ctx->settings->tags[i] != NULL; i++) {
- char *f = bm_generate_filename(ctx->short_output_dir, atom_prefix,
- ctx->settings->tags[i], atom_ext);
- rv = bc_slist_append(rv, bm_filectx_new(ctx, f, NULL, NULL));
- free(f);
- }
-
- return rv;
-}
-
-static int
-atom_tags_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
-{
- if (ctx == NULL || ctx->settings->posts == NULL || ctx->settings->tags == NULL)
- return 0;
-
- int rv = 0;
- size_t i = 0;
-
- bc_trie_t *variables = bc_trie_new(free);
- posts_pagination(ctx, variables, "atom_posts_per_page");
- posts_ordering(ctx, variables, "atom_order");
- bc_trie_insert(variables, "DATE_FORMAT", bc_strdup("%Y-%m-%dT%H:%M:%SZ"));
- bc_trie_insert(variables, "MAKE_RULE", bc_strdup("atom_tags"));
- bc_trie_insert(variables, "MAKE_TYPE", bc_strdup("atom"));
-
- for (bc_slist_t *l = outputs; l != NULL; l = l->next, i++) {
- bm_filectx_t *fctx = l->data;
- if (fctx == NULL)
- continue;
-
- bc_trie_insert(variables, "FILTER_TAG",
- bc_strdup(ctx->settings->tags[i]));
-
- if (bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx, NULL,
- ctx->atom_template_tmp ? NULL : ctx->atom_template_fctx,
- fctx, false))
- {
- rv = bm_exec_blogc(ctx, variables, NULL, true, NULL, ctx->atom_template_fctx,
- fctx, ctx->posts_fctx, false);
- if (rv != 0)
- break;
- }
- }
-
- bc_trie_free(variables);
-
- return rv;
-}
-
-
-// PAGINATION RULE
-
-static bc_slist_t*
-pagination_outputlist(bm_ctx_t *ctx)
-{
- if (ctx == NULL || ctx->settings->posts == NULL)
- return NULL;
-
- if (!posts_pagination_enabled(ctx, "posts_per_page"))
- return NULL;
-
- bc_trie_t *variables = bc_trie_new(free);
- posts_pagination(ctx, variables, "posts_per_page");
-
- char *last_page = bm_exec_blogc_get_variable(ctx, variables, NULL, "LAST_PAGE",
- true, ctx->posts_fctx, false);
-
- bc_trie_free(variables);
-
- if (last_page == NULL)
- return NULL;
-
- long pages = strtol(last_page, NULL, 10);
- free(last_page);
-
- bc_slist_t *rv = NULL;
-
- const char *pagination_prefix = bm_ctx_settings_lookup(ctx, "pagination_prefix");
- const char *html_ext = bm_ctx_settings_lookup(ctx, "html_ext");
-
- for (size_t i = 0; i < pages; i++) {
- char *j = bc_strdup_printf("%d", i + 1);
- char *f = bm_generate_filename(ctx->short_output_dir, pagination_prefix,
- j, html_ext);
- rv = bc_slist_append(rv, bm_filectx_new(ctx, f, NULL, NULL));
- free(j);
- free(f);
- }
-
- return rv;
-}
-
-static int
-pagination_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
-{
- if (ctx == NULL || ctx->settings->posts == NULL)
- return 0;
-
- int rv = 0;
- size_t page = 1;
-
- bc_trie_t *variables = bc_trie_new(free);
- // not using posts_pagination because we set FILTER_PAGE anyway, and the
- // first value inserted in that function would be useless
- bc_trie_insert(variables, "FILTER_PER_PAGE",
- bc_strdup(bm_ctx_settings_lookup_str(ctx, "posts_per_page")));
- posts_ordering(ctx, variables, "html_order");
- bc_trie_insert(variables, "DATE_FORMAT",
- bc_strdup(bm_ctx_settings_lookup_str(ctx, "date_format")));
- bc_trie_insert(variables, "MAKE_RULE", bc_strdup("pagination"));
- bc_trie_insert(variables, "MAKE_TYPE", bc_strdup("post"));
-
- for (bc_slist_t *l = outputs; l != NULL; l = l->next, page++) {
- bm_filectx_t *fctx = l->data;
- if (fctx == NULL)
- continue;
- bc_trie_insert(variables, "FILTER_PAGE", bc_strdup_printf("%zu", page));
- if (bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx,
- ctx->listing_entry_fctx, ctx->main_template_fctx, fctx, false))
- {
- rv = bm_exec_blogc(ctx, variables, NULL, true, ctx->listing_entry_fctx,
- ctx->main_template_fctx, fctx, ctx->posts_fctx, false);
- if (rv != 0)
- break;
- }
- }
-
- bc_trie_free(variables);
-
- return rv;
-}
-
-
-// PAGINATION TAGS RULE
-
-static bc_slist_t*
-pagination_tags_outputlist(bm_ctx_t *ctx)
-{
- if (ctx == NULL || ctx->settings->posts == NULL || ctx->settings->tags == NULL)
- return NULL;
-
- if (!posts_pagination_enabled(ctx, "posts_per_page"))
- return NULL;
-
- bc_trie_t *variables = bc_trie_new(free);
- posts_pagination(ctx, variables, "posts_per_page");
-
- const char *tag_prefix = bm_ctx_settings_lookup(ctx, "tag_prefix");
- const char *pagination_prefix = bm_ctx_settings_lookup(ctx, "pagination_prefix");
- const char *html_ext = bm_ctx_settings_lookup(ctx, "html_ext");
-
- bc_slist_t *rv = NULL;
-
- for (size_t k = 0; ctx->settings->tags[k] != NULL; k++) {
- bc_trie_t *local = bc_trie_new(free);
- bc_trie_insert(local, "FILTER_TAG", bc_strdup(ctx->settings->tags[k]));
-
- char *last_page = bm_exec_blogc_get_variable(ctx, variables, local,
- "LAST_PAGE", true, ctx->posts_fctx, false);
-
- bc_trie_free(local);
-
- if (last_page == NULL)
- continue;
-
- long pages = strtol(last_page, NULL, 10);
- free(last_page);
-
- for (size_t i = 0; i < pages; i++) {
- char *j = bc_strdup_printf("%d", i + 1);
- char *f = bm_generate_filename2(ctx->short_output_dir, tag_prefix,
- ctx->settings->tags[k], pagination_prefix, j, html_ext);
- rv = bc_slist_append(rv, bm_filectx_new(ctx, f, NULL, NULL));
- free(j);
- free(f);
- }
- }
-
- bc_trie_free(variables);
-
- return rv;
-}
-
-static int
-pagination_tags_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
-{
- if (ctx == NULL || ctx->settings->posts == NULL || ctx->settings->tags == NULL)
- return 0;
-
- int rv = 0;
- size_t page = 1;
-
- bc_trie_t *variables = bc_trie_new(free);
- // not using posts_pagination because we set FILTER_PAGE anyway, and the
- // first value inserted in that function would be useless
- bc_trie_insert(variables, "FILTER_PER_PAGE",
- bc_strdup(bm_ctx_settings_lookup_str(ctx, "posts_per_page")));
- posts_ordering(ctx, variables, "html_order");
- bc_trie_insert(variables, "DATE_FORMAT",
- bc_strdup(bm_ctx_settings_lookup_str(ctx, "date_format")));
- bc_trie_insert(variables, "MAKE_RULE", bc_strdup("pagination_tags"));
- bc_trie_insert(variables, "MAKE_TYPE", bc_strdup("post"));
-
- const char *tag_prefix = bm_ctx_settings_lookup(ctx, "tag_prefix");
- const char *pagination_prefix = bm_ctx_settings_lookup(ctx, "pagination_prefix");
- const char *html_ext = bm_ctx_settings_lookup(ctx, "html_ext");
-
- for (bc_slist_t *l = outputs; l != NULL; l = l->next) {
- bm_filectx_t *fctx = l->data;
- if (fctx == NULL)
- continue;
-
- // this is very expensive, but we don't have another way to detect the
- // tag and page from the file path right now :/
- char *tag = NULL;
- for (size_t i = 0; ctx->settings->tags[i] != NULL; i++) {
- bool b = false;
-
- // it is impossible to have more output files per tag than the whole
- // amount of output pages
- for (size_t k = 1; k <= bc_slist_length(outputs); k++) {
- char *j = bc_strdup_printf("%d", k);
- char *f = bm_generate_filename2(ctx->short_output_dir, tag_prefix,
- ctx->settings->tags[i], pagination_prefix, j, html_ext);
- free(j);
- if (0 == strcmp(fctx->short_path, f)) {
- tag = ctx->settings->tags[i];
- page = k;
- b = true;
- free(f);
- break;
- }
- free(f);
- }
- if (b)
- break;
- }
- if (tag == NULL)
- continue;
-
- bc_trie_insert(variables, "FILTER_TAG", bc_strdup(tag));
- bc_trie_insert(variables, "FILTER_PAGE", bc_strdup_printf("%zu", page));
-
- if (bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx,
- ctx->listing_entry_fctx, ctx->main_template_fctx, fctx, false))
- {
- rv = bm_exec_blogc(ctx, variables, NULL, true, ctx->listing_entry_fctx,
- ctx->main_template_fctx, fctx, ctx->posts_fctx, false);
- if (rv != 0)
- break;
- }
- }
-
- bc_trie_free(variables);
-
- return rv;
-}
-
-
-// POSTS RULE
-
-static bc_slist_t*
-posts_outputlist(bm_ctx_t *ctx)
-{
- if (ctx == NULL || ctx->settings->posts == NULL)
- return NULL;
-
- bc_slist_t *rv = NULL;
-
- const char *post_prefix = bm_ctx_settings_lookup(ctx, "post_prefix");
- const char *html_ext = bm_ctx_settings_lookup(ctx, "html_ext");
-
- for (size_t i = 0; ctx->settings->posts[i] != NULL; i++) {
- char *f = bm_generate_filename(ctx->short_output_dir, post_prefix,
- ctx->settings->posts[i], html_ext);
- rv = bc_slist_append(rv, bm_filectx_new(ctx, f, NULL, NULL));
- free(f);
- }
-
- return rv;
-}
-
-static int
-posts_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
-{
- if (ctx == NULL || ctx->settings->posts == NULL)
- return 0;
-
- int rv = 0;
-
- bc_trie_t *variables = bc_trie_new(free);
- bc_trie_insert(variables, "IS_POST", bc_strdup("1"));
- bc_trie_insert(variables, "DATE_FORMAT",
- bc_strdup(bm_ctx_settings_lookup(ctx, "date_format")));
- posts_ordering(ctx, variables, "html_order");
- bc_trie_insert(variables, "MAKE_RULE", bc_strdup("posts"));
- bc_trie_insert(variables, "MAKE_TYPE", bc_strdup("post"));
-
- bc_slist_t *s, *o;
-
- for (s = ctx->posts_fctx, o = outputs; s != NULL && o != NULL;
- s = s->next, o = o->next)
- {
- bm_filectx_t *s_fctx = s->data;
- bm_filectx_t *o_fctx = o->data;
- if (o_fctx == NULL)
- continue;
- if (bm_rule_need_rebuild(s, ctx->settings_fctx, NULL,
- ctx->main_template_fctx, o_fctx, true))
- {
- bc_trie_t *local = bc_trie_new(NULL);
- bc_trie_insert(local, "MAKE_SLUG", s_fctx->slug); // no need to copy
- rv = bm_exec_blogc(ctx, variables, local, false, NULL, ctx->main_template_fctx,
- o_fctx, s, true);
- bc_trie_free(local);
- if (rv != 0)
- break;
- }
- }
-
- bc_trie_free(variables);
-
- return rv;
-}
-
-
-// TAGS RULE
-
-static bc_slist_t*
-tags_outputlist(bm_ctx_t *ctx)
-{
- if (ctx == NULL || ctx->settings->posts == NULL || ctx->settings->tags == NULL)
- return NULL;
-
- if (!posts_pagination_enabled(ctx, "posts_per_page"))
- return NULL;
-
- bc_slist_t *rv = NULL;
-
- const char *tag_prefix = bm_ctx_settings_lookup(ctx, "tag_prefix");
- const char *html_ext = bm_ctx_settings_lookup(ctx, "html_ext");
-
- for (size_t i = 0; ctx->settings->tags[i] != NULL; i++) {
- char *f = bm_generate_filename(ctx->short_output_dir, tag_prefix,
- ctx->settings->tags[i], html_ext);
- rv = bc_slist_append(rv, bm_filectx_new(ctx, f, NULL, NULL));
- free(f);
- }
-
- return rv;
-}
-
-static int
-tags_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
-{
- if (ctx == NULL || ctx->settings->posts == NULL || ctx->settings->tags == NULL)
- return 0;
-
- int rv = 0;
- size_t i = 0;
-
- bc_trie_t *variables = bc_trie_new(free);
- posts_pagination(ctx, variables, "posts_per_page");
- posts_ordering(ctx, variables, "html_order");
- bc_trie_insert(variables, "DATE_FORMAT",
- bc_strdup(bm_ctx_settings_lookup_str(ctx, "date_format")));
- bc_trie_insert(variables, "MAKE_RULE", bc_strdup("tags"));
- bc_trie_insert(variables, "MAKE_TYPE", bc_strdup("post"));
-
- for (bc_slist_t *l = outputs; l != NULL; l = l->next, i++) {
- bm_filectx_t *fctx = l->data;
- if (fctx == NULL)
- continue;
-
- bc_trie_insert(variables, "FILTER_TAG",
- bc_strdup(ctx->settings->tags[i]));
-
- if (bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx,
- ctx->listing_entry_fctx, ctx->main_template_fctx, fctx, false))
- {
- rv = bm_exec_blogc(ctx, variables, NULL, true, ctx->listing_entry_fctx,
- ctx->main_template_fctx, fctx, ctx->posts_fctx, false);
- if (rv != 0)
- break;
- }
- }
-
- bc_trie_free(variables);
-
- return rv;
-}
-
-
-// PAGES RULE
-
-static bc_slist_t*
-pages_outputlist(bm_ctx_t *ctx)
-{
- if (ctx == NULL || ctx->settings->pages == NULL)
- return NULL;
-
- bc_slist_t *rv = NULL;
-
- const char *html_ext = bm_ctx_settings_lookup(ctx, "html_ext");
-
- for (size_t i = 0; ctx->settings->pages[i] != NULL; i++) {
- char *f = bm_generate_filename(ctx->short_output_dir, NULL,
- ctx->settings->pages[i], html_ext);
- rv = bc_slist_append(rv, bm_filectx_new(ctx, f, NULL, NULL));
- free(f);
- }
-
- return rv;
-}
-
-static int
-pages_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
-{
- if (ctx == NULL || ctx->settings->pages == NULL)
- return 0;
-
- int rv = 0;
-
- bc_trie_t *variables = bc_trie_new(free);
- bc_trie_insert(variables, "DATE_FORMAT",
- bc_strdup(bm_ctx_settings_lookup(ctx, "date_format")));
- bc_trie_insert(variables, "MAKE_RULE", bc_strdup("pages"));
- bc_trie_insert(variables, "MAKE_TYPE", bc_strdup("page"));
-
- bc_slist_t *s, *o;
-
- for (s = ctx->pages_fctx, o = outputs; s != NULL && o != NULL;
- s = s->next, o = o->next)
- {
- bm_filectx_t *s_fctx = s->data;
- bm_filectx_t *o_fctx = o->data;
- if (o_fctx == NULL)
- continue;
- if (bm_rule_need_rebuild(s, ctx->settings_fctx, NULL,
- ctx->main_template_fctx, o_fctx, true))
- {
- bc_trie_t *local = bc_trie_new(NULL);
- bc_trie_insert(local, "MAKE_SLUG", s_fctx->slug); // no need to copy
- rv = bm_exec_blogc(ctx, variables, local, false, NULL, ctx->main_template_fctx,
- o_fctx, s, true);
- bc_trie_free(local);
- if (rv != 0)
- break;
- }
- }
-
- bc_trie_free(variables);
-
- return rv;
-}
-
-
-// COPY FILES RULE
-
-static bc_slist_t*
-copy_outputlist(bm_ctx_t *ctx)
-{
- if (ctx == NULL || ctx->settings->copy == NULL)
- return NULL;
-
- bc_slist_t *rv = NULL;
-
- // we iterate over ctx->copy_fctx list instead of ctx->settings->copy,
- // because bm_ctx_new() expands directories into its files, recursively.
- for (bc_slist_t *s = ctx->copy_fctx; s != NULL; s = s->next) {
- char *f = bc_strdup_printf("%s/%s", ctx->short_output_dir,
- ((bm_filectx_t*) s->data)->short_path);
- rv = bc_slist_append(rv, bm_filectx_new(ctx, f, NULL, NULL));
- free(f);
- }
-
- return rv;
-}
-
-static int
-copy_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
-{
- if (ctx == NULL || ctx->settings->copy == NULL)
- return 0;
-
- int rv = 0;
-
- bc_slist_t *s, *o;
-
- for (s = ctx->copy_fctx, o = outputs; s != NULL && o != NULL;
- s = s->next, o = o->next)
- {
- bm_filectx_t *o_fctx = o->data;
- if (o_fctx == NULL)
- continue;
-
- if (bm_rule_need_rebuild(s, ctx->settings_fctx, NULL, NULL, o_fctx, true)) {
- rv = bm_exec_native_cp(s->data, o_fctx, ctx->verbose);
- if (rv != 0)
- break;
- }
- }
-
- return rv;
-}
-
-
-// CLEAN RULE
-
-static int
-clean_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
-{
- int rv = 0;
-
- bc_slist_t *files = bm_rule_list_built_files(ctx);
- for (bc_slist_t *l = files; l != NULL; l = l->next) {
- bm_filectx_t *fctx = l->data;
- if (fctx == NULL)
- continue;
-
- if (fctx->readable) {
- rv = bm_exec_native_rm(ctx->output_dir, fctx, ctx->verbose);
- if (rv != 0)
- break;
- }
- }
- bc_slist_free_full(files, (bc_free_func_t) bm_filectx_free);
-
- if (!bm_exec_native_is_empty_dir(ctx->output_dir, NULL)) {
- fprintf(stderr, "blogc-make: warning: output directory is not empty!\n");
- }
-
- return rv;
-}
-
-
-static int all_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args);
-
-
-// RUNSERVER RULE
-
-static int
-runserver_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
-{
- return bm_httpd_run(&ctx, all_exec, outputs, args);
-}
-
-
-// WATCH RULE
-
-static int
-watch_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
-{
- return bm_reloader_run(&ctx, all_exec, outputs, args);
-}
-
-
-// ATOM DUMP RULE
-
-static int
-atom_dump_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
-{
- char *content = bm_atom_generate(ctx->settings);
- if (content == NULL)
- return 1;
- printf("%s", content);
- free(content);
- return 0;
-}
-
-
-const bm_rule_t rules[] = {
- {
- .name = "all",
- .help = "run all build rules",
- .outputlist_func = NULL,
- .exec_func = all_exec,
- },
- {
- .name = "index",
- .help = "build website index from posts",
- .outputlist_func = index_outputlist,
- .exec_func = index_exec,
- },
- {
- .name = "atom",
- .help = "build main atom feed from posts",
- .outputlist_func = atom_outputlist,
- .exec_func = atom_exec,
- },
- {
- .name = "atom_tags",
- .help = "build atom feeds for each tag from posts",
- .outputlist_func = atom_tags_outputlist,
- .exec_func = atom_tags_exec,
- },
- {
- .name = "pagination",
- .help = "build pagination pages from posts",
- .outputlist_func = pagination_outputlist,
- .exec_func = pagination_exec,
- },
- {
- .name = "pagination_tags",
- .help = "build pagination pages for each tag from posts",
- .outputlist_func = pagination_tags_outputlist,
- .exec_func = pagination_tags_exec,
- },
- {
- .name = "posts",
- .help = "build individual pages for each post",
- .outputlist_func = posts_outputlist,
- .exec_func = posts_exec,
- },
- {
- .name = "tags",
- .help = "build post listings for each tag from posts",
- .outputlist_func = tags_outputlist,
- .exec_func = tags_exec,
- },
- {
- .name = "pages",
- .help = "build individual pages for each page",
- .outputlist_func = pages_outputlist,
- .exec_func = pages_exec,
- },
- {
- .name = "copy",
- .help = "copy static files from source directory to output directory",
- .outputlist_func = copy_outputlist,
- .exec_func = copy_exec,
- },
- {
- .name = "clean",
- .help = "clean built files and empty directories in output directory",
- .outputlist_func = NULL,
- .exec_func = clean_exec,
- },
- {
- .name = "runserver",
- .help = "run blogc-runserver pointing to output directory, if available,\n"
- " rebuilding as needed\n"
- " arguments: host (127.0.0.1), port (8080) and threads (20)",
- .outputlist_func = NULL,
- .exec_func = runserver_exec,
- },
- {
- .name = "watch",
- .help = "watch for changes in the source files, rebuilding as needed",
- .outputlist_func = NULL,
- .exec_func = watch_exec,
- },
- {
- .name = "atom_dump",
- .help = "dump default Atom feed template based on current settings",
- .outputlist_func = NULL,
- .exec_func = atom_dump_exec,
- },
- {NULL, NULL, NULL, NULL},
-};
-
-
-// ALL RULE
-
-static int
-all_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
-{
- for (size_t i = 0; rules[i].name != NULL; i++) {
- if (rules[i].outputlist_func == NULL) {
- continue;
- }
-
- int rv = bm_rule_execute(ctx, &(rules[i]), NULL);
- if (rv != 0) {
- return rv;
- }
- }
-
- return 0;
-}
-
-
-bc_trie_t*
-bm_rule_parse_args(const char *sep)
-{
- if (sep == NULL || *sep == '\0' || *sep != ':')
- return NULL;
-
- bc_trie_t *rv = bc_trie_new(free);
- char *end = (char*) sep + 1;
- char *kv_sep;
- while (NULL != (kv_sep = strchr(end, '='))) {
- char *key = bc_strndup(end, kv_sep - end);
- end = kv_sep + 1;
- kv_sep = strchr(end, ',');
- if (kv_sep == NULL)
- kv_sep = strchr(end, '\0');
- char *value = bc_strndup(end, kv_sep - end);
- bc_trie_insert(rv, key, value);
- free(key);
- if (*kv_sep == '\0')
- break;
- end = kv_sep + 1;
- }
- if (kv_sep == NULL) {
- bc_trie_free(rv);
- return NULL;
- }
-
- return rv;
-}
-
-
-int
-bm_rule_executor(bm_ctx_t *ctx, bc_slist_t *rule_list)
-{
- if (ctx == NULL)
- return 1;
-
- const bm_rule_t *rule = NULL;
- int rv = 0;
-
- for (bc_slist_t *l = rule_list; l != NULL; l = l->next) {
-
- char *rule_str = l->data;
- char *sep = strchr(rule_str, ':');
-
- bc_trie_t *args = NULL;
- if (sep == NULL) {
- sep = strchr(rule_str, '\0');
- }
- else {
- args = bm_rule_parse_args(sep);
- if (args == NULL) {
- fprintf(stderr, "blogc-make: warning: failed to parse rule "
- "arguments, ignoring: %s\n", rule_str);
- }
- }
-
- rule = NULL;
- for (size_t i = 0; rules[i].name != NULL; i++) {
- if (strlen(rules[i].name) != (sep - rule_str))
- continue;
- if (0 == strncmp(rule_str, rules[i].name, sep - rule_str)) {
- rule = &(rules[i]);
- rv = bm_rule_execute(ctx, rule, args);
- if (rv != 0)
- return rv;
- break;
- }
- }
- if (rule == NULL) {
- fprintf(stderr, "blogc-make: error: rule not found: %.*s\n",
- (int) (sep - rule_str), rule_str);
- rv = 1;
- }
- }
-
- return rv;
-}
-
-
-int
-bm_rule_execute(bm_ctx_t *ctx, const bm_rule_t *rule, bc_trie_t *args)
-{
- if (ctx == NULL || rule == NULL)
- return 1;
-
- bc_slist_t *outputs = NULL;
- if (rule->outputlist_func != NULL) {
- outputs = rule->outputlist_func(ctx);
- }
-
- int rv = rule->exec_func(ctx, outputs, args);
-
- bc_slist_free_full(outputs, (bc_free_func_t) bm_filectx_free);
-
- return rv;
-}
-
-
-bool
-bm_rule_need_rebuild(bc_slist_t *sources, bm_filectx_t *settings,
- bm_filectx_t *listing_entry, bm_filectx_t *template, bm_filectx_t *output,
- bool only_first_source)
-{
- if (output == NULL || !output->readable)
- return true;
-
- bool rv = false;
-
- bc_slist_t *s = NULL;
- if (settings != NULL)
- s = bc_slist_append(s, settings);
- if (template != NULL)
- s = bc_slist_append(s, template);
- if (listing_entry != NULL)
- s = bc_slist_append(s, listing_entry);
-
- for (bc_slist_t *l = sources; l != NULL; l = l->next) {
- s = bc_slist_append(s, l->data);
- if (only_first_source)
- break;
- }
-
- for (bc_slist_t *l = s; l != NULL; l = l->next) {
- bm_filectx_t *source = l->data;
- if (source == NULL || !source->readable) {
- // this is unlikely to happen, but lets just say that we need
- // a rebuild and let blogc bail out.
- rv = true;
- break;
- }
- if (source->tv_sec == output->tv_sec) {
- if (source->tv_nsec > output->tv_nsec) {
- rv = true;
- break;
- }
- }
- else if (source->tv_sec > output->tv_sec) {
- rv = true;
- break;
- }
- }
-
- bc_slist_free(s);
-
- return rv;
-}
-
-
-bc_slist_t*
-bm_rule_list_built_files(bm_ctx_t *ctx)
-{
- if (ctx == NULL)
- return NULL;
-
- bc_slist_t *rv = NULL;
- for (size_t i = 0; rules[i].name != NULL; i++) {
- if (rules[i].outputlist_func == NULL) {
- continue;
- }
-
- bc_slist_t *o = rules[i].outputlist_func(ctx);
- for (bc_slist_t *l = o; l != NULL; l = l->next) {
- rv = bc_slist_append(rv, l->data);
- }
- bc_slist_free(o);
- }
-
- return rv;
-}
-
-
-void
-bm_rule_print_help(void)
-{
- printf("\nhelper rules:\n");
- for (size_t i = 0; rules[i].name != NULL; i++) {
- if (rules[i].outputlist_func == NULL) {
- printf(" %-15s %s\n", rules[i].name, rules[i].help);
- }
- }
- printf("\nbuild rules:\n");
- for (size_t i = 0; rules[i].name != NULL; i++) {
- if (rules[i].outputlist_func != NULL) {
- printf(" %-15s %s\n", rules[i].name, rules[i].help);
- }
- }
-}
diff --git a/src/blogc-make/rules.h b/src/blogc-make/rules.h
deleted file mode 100644
index 9ff39ca..0000000
--- a/src/blogc-make/rules.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _MAKE_RULES_H
-#define _MAKE_RULES_H
-
-#include <stdbool.h>
-#include "ctx.h"
-#include "../common/utils.h"
-
-typedef bc_slist_t* (*bm_rule_outputlist_func_t) (bm_ctx_t *ctx);
-typedef int (*bm_rule_exec_func_t) (bm_ctx_t *ctx, bc_slist_t *outputs,
- bc_trie_t *args);
-
-typedef struct {
- const char *name;
- const char *help;
- bm_rule_outputlist_func_t outputlist_func;
- bm_rule_exec_func_t exec_func;
-} bm_rule_t;
-
-bc_trie_t* bm_rule_parse_args(const char *sep);
-int bm_rule_executor(bm_ctx_t *ctx, bc_slist_t *rule_list);
-int bm_rule_execute(bm_ctx_t *ctx, const bm_rule_t *rule, bc_trie_t *args);
-bool bm_rule_need_rebuild(bc_slist_t *sources, bm_filectx_t *settings,
- bm_filectx_t *listing_entry, bm_filectx_t *template, bm_filectx_t *output,
- bool only_first_source);
-bc_slist_t* bm_rule_list_built_files(bm_ctx_t *ctx);
-void bm_rule_print_help(void);
-
-#endif /* _MAKE_RULES_H */
diff --git a/src/blogc-make/settings.c b/src/blogc-make/settings.c
deleted file mode 100644
index 1079fc0..0000000
--- a/src/blogc-make/settings.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <libgen.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include "../common/config-parser.h"
-#include "../common/error.h"
-#include "../common/file.h"
-#include "../common/utils.h"
-#include "settings.h"
-
-
-static const struct default_settings_map {
- const char *key;
- const char *default_value;
-} default_settings[] = {
-
- // source
- {"content_dir", "content"},
- {"template_dir", "templates"},
- {"atom_template", NULL}, // default: atom.c
- {"main_template", "main.tmpl"},
- {"source_ext", ".txt"},
- {"listing_entry", NULL},
- {"posts_sort", NULL},
-
- // pagination
- {"pagination_prefix", "page"},
- {"posts_per_page", "10"},
- {"atom_posts_per_page", "10"},
-
- // html
- {"html_ext", "/index.html"},
- {"index_prefix", ""},
- {"post_prefix", "post"},
- {"tag_prefix", "tag"},
- {"html_order", "DESC"},
-
- // atom
- {"atom_prefix", "atom"},
- {"atom_ext", ".xml"},
- {"atom_order", "DESC"},
- {"atom_legacy_entry_id", NULL},
-
- // generic
- {"date_format", "%b %d, %Y, %I:%M %p GMT"},
- {"locale", NULL},
-
- {NULL, NULL},
-};
-
-
-static const char* required_global[] = {
- "AUTHOR_NAME",
- "AUTHOR_EMAIL",
- "SITE_TITLE",
- "SITE_TAGLINE",
- "BASE_DOMAIN",
- NULL,
-};
-
-
-static const char* list_sections[] = {
- "posts",
- "pages",
- "copy",
- "copy_files", // backward compatibility
- "tags",
- NULL,
-};
-
-
-bm_settings_t*
-bm_settings_parse(const char *content, size_t content_len, bc_error_t **err)
-{
- if (err == NULL || *err != NULL)
- return NULL;
-
- if (content == NULL)
- return NULL;
-
- bc_config_t *config = bc_config_parse(content, content_len, list_sections,
- err);
- if (config == NULL || (err != NULL && *err != NULL))
- return NULL;
-
- bm_settings_t *rv = bc_malloc(sizeof(bm_settings_t));
- rv->global = bc_trie_new(free);
- rv->settings = bc_trie_new(free);
- rv->posts = NULL;
- rv->pages = NULL;
- rv->copy = NULL;
- rv->tags = NULL;
-
- // this is some code for compatibility with the [environment] section,
- // even if I never released a version with it, but some people is using
- // it already.
- const char *section = NULL;
- char **global = bc_config_list_keys(config, "global");
- if (global != NULL) {
- section = "global";
- }
- else {
- global = bc_config_list_keys(config, "environment");
- if (global != NULL) {
- section = "environment";
- }
- else {
- section = "global";
- }
- }
-
- if (global != NULL) {
- for (size_t i = 0; global[i] != NULL; i++) {
- for (size_t j = 0; global[i][j] != '\0'; j++) {
- if (j == 0) {
- if (!(global[i][j] >= 'A' && global[i][j] <= 'Z')) {
- *err = bc_error_new_printf(BLOGC_MAKE_ERROR_SETTINGS,
- "Invalid [%s] key (first character must be uppercase): %s",
- section, global[i]);
- bc_strv_free(global);
- bm_settings_free(rv);
- rv = NULL;
- goto cleanup;
- }
- continue;
- }
- if (!((global[i][j] >= 'A' && global[i][j] <= 'Z') ||
- (global[i][j] >= '0' && global[i][j] <= '9') ||
- global[i][j] == '_')) {
- *err = bc_error_new_printf(BLOGC_MAKE_ERROR_SETTINGS,
- "Invalid [%s] key (must be uppercase with '_' and digits after first character): %s",
- section, global[i]);
- bc_strv_free(global);
- bm_settings_free(rv);
- rv = NULL;
- goto cleanup;
- }
- }
- bc_trie_insert(rv->global, global[i],
- bc_strdup(bc_config_get(config, section, global[i])));
- }
- }
- bc_strv_free(global);
-
- for (size_t i = 0; required_global[i] != NULL; i++) {
- const char *value = bc_trie_lookup(rv->global, required_global[i]);
- if (value == NULL || value[0] == '\0') {
- *err = bc_error_new_printf(BLOGC_MAKE_ERROR_SETTINGS,
- "[%s] key required but not found or empty: %s", section,
- required_global[i]);
- bm_settings_free(rv);
- rv = NULL;
- goto cleanup;
- }
- }
-
- for (size_t i = 0; default_settings[i].key != NULL; i++) {
- const char *value = bc_config_get_with_default(
- config, "settings", default_settings[i].key,
- default_settings[i].default_value);
- if (value != NULL) {
- bc_trie_insert(rv->settings, default_settings[i].key,
- bc_strdup(value));
- }
- }
-
- rv->posts = bc_config_get_list(config, "posts");
- rv->pages = bc_config_get_list(config, "pages");
- rv->tags = bc_config_get_list(config, "tags");
-
- // this is for backward compatibility too.
- rv->copy = bc_config_get_list(config, "copy");
- if (rv->copy == NULL)
- rv->copy = bc_config_get_list(config, "copy_files");
-
-cleanup:
-
- bc_config_free(config);
-
- return rv;
-}
-
-
-void
-bm_settings_free(bm_settings_t *settings)
-{
- if (settings == NULL)
- return;
- bc_trie_free(settings->global);
- bc_trie_free(settings->settings);
- bc_strv_free(settings->posts);
- bc_strv_free(settings->pages);
- bc_strv_free(settings->copy);
- bc_strv_free(settings->tags);
- free(settings);
-}
diff --git a/src/blogc-make/settings.h b/src/blogc-make/settings.h
deleted file mode 100644
index 69fdbb6..0000000
--- a/src/blogc-make/settings.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _MAKE_SETTINGS_H
-#define _MAKE_SETTINGS_H
-
-#include <stddef.h>
-#include "../common/error.h"
-#include "../common/utils.h"
-
-typedef struct {
- bc_trie_t *global;
- bc_trie_t *settings;
- char **posts;
- char **pages;
- char **copy;
- char **tags;
-} bm_settings_t;
-
-bm_settings_t* bm_settings_parse(const char *content, size_t content_len,
- bc_error_t **err);
-void bm_settings_free(bm_settings_t *settings);
-
-#endif /* _MAKE_SETTINGS_H */
diff --git a/src/blogc-make/utils.c b/src/blogc-make/utils.c
deleted file mode 100644
index 8f69e44..0000000
--- a/src/blogc-make/utils.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <errno.h>
-#include <limits.h>
-#include <stdbool.h>
-#include <string.h>
-#include <unistd.h>
-#include "../common/error.h"
-#include "../common/utils.h"
-
-#ifndef PATH_MAX
-#define PATH_MAX 4096
-#endif
-
-
-char*
-bm_generate_filename(const char *dir, const char *prefix, const char *fname,
- const char *ext)
-{
- bool have_prefix = prefix != NULL && prefix[0] != '\0';
- bool have_fname = fname != NULL && fname[0] != '\0';
- bool have_ext = ext != NULL && ext[0] != '\0';
- bool have_ext_noslash = have_ext && ext[0] != '/';
- bool is_index = have_fname && have_ext && (
- (0 == strcmp(fname, "index")) && ext[0] == '/') && !have_prefix;
-
- bc_string_t *rv = bc_string_new();
-
- if (dir != NULL && (have_prefix || have_fname || have_ext))
- bc_string_append(rv, dir);
-
- if ((have_prefix || have_fname || have_ext_noslash) && !is_index)
- bc_string_append_c(rv, '/');
-
- if (have_prefix)
- bc_string_append(rv, prefix);
-
- // with fname we have posts, pages and tags
- if (have_fname) {
- if (have_prefix && have_fname && fname[0] != '/')
- bc_string_append_c(rv, '/');
- if (!is_index)
- bc_string_append(rv, fname);
- }
-
- // no fname means index
- else if (have_ext_noslash) {
- if (have_fname)
- bc_string_append_c(rv, '/');
- if (!have_prefix)
- bc_string_append(rv, "index");
- }
-
- if (have_ext)
- bc_string_append(rv, ext);
-
- if (rv->len == 0) {
- bc_string_free(rv, true);
- return NULL;
- }
-
- return bc_string_free(rv, false);
-}
-
-
-char*
-bm_generate_filename2(const char *dir, const char *prefix, const char *fname,
- const char *prefix2, const char *fname2, const char *ext)
-{
- bool have_prefix = prefix != NULL && prefix[0] != '\0';
- bool have_fname = fname != NULL && fname[0] != '\0';
- bool have_prefix2 = prefix2 != NULL && prefix2[0] != '\0';
-
- bc_string_t *p = bc_string_new();
-
- if (have_prefix)
- bc_string_append(p, prefix);
-
- if (have_prefix && (have_fname || have_prefix2))
- bc_string_append_c(p, '/');
-
- if (have_fname)
- bc_string_append(p, fname);
-
- if (have_fname && have_prefix2)
- bc_string_append_c(p, '/');
-
- if (have_prefix2)
- bc_string_append(p, prefix2);
-
- char *rv = bm_generate_filename(dir, p->str, fname2, ext);
- bc_string_free(p, true);
-
- return rv;
-}
-
-
-char*
-bm_abspath(const char *path, bc_error_t **err)
-{
- if (err == NULL || *err != NULL)
- return NULL;
-
- if (path[0] == '/') {
- return bc_strdup(path);
- }
-
- char cwd[PATH_MAX];
- if (NULL == getcwd(cwd, sizeof(cwd))) {
- *err = bc_error_new_printf(BLOGC_MAKE_ERROR_UTILS,
- "Failed to detect absolute path (%s): %s", path, strerror(errno));
- return NULL;
- }
-
- if (cwd[0] != '/') {
- *err = bc_error_new_printf(BLOGC_MAKE_ERROR_UTILS,
- "Failed to get current working directory: %s", cwd);
- return NULL;
- }
-
- return bc_strdup_printf("%s/%s", cwd, path);
-}
diff --git a/src/blogc-make/utils.h b/src/blogc-make/utils.h
deleted file mode 100644
index cbcfc0e..0000000
--- a/src/blogc-make/utils.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _MAKE_UTILS_H
-#define _MAKE_UTILS_H
-
-#include "../common/error.h"
-
-char* bm_generate_filename(const char *dir, const char *prefix, const char *fname,
- const char *ext);
-char* bm_generate_filename2(const char *dir, const char *prefix, const char *fname,
- const char *prefix2, const char *fname2, const char *ext);
-char* bm_abspath(const char *path, bc_error_t **err);
-
-#endif /* _MAKE_UTILS_H */
diff --git a/src/blogc-runserver.c b/src/blogc-runserver.c
new file mode 100644
index 0000000..2fbbbc7
--- /dev/null
+++ b/src/blogc-runserver.c
@@ -0,0 +1,386 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <event2/event.h>
+#include <event2/http.h>
+#include <event2/buffer.h>
+#include <magic.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "utils.h"
+
+
+/**
+ * this mapping is used to declare "supported" file types, that are forced over
+ * whatever detected by libmagic, but we will still use the charset provided by
+ * libmagic anyway. it also helps detecting index files when the client asks
+ * for a directory.
+ */
+static const struct content_type_map {
+ const char *mimetype;
+ const char *extension;
+ const char *index;
+} content_types[] = {
+ {"text/html", "html", "index.html"},
+ {"text/html", "htm", "index.htm"},
+ {"text/xml", "xml", "index.xml"},
+ {"text/plain", "txt", "index.txt"},
+ {"text/css", "css", NULL},
+ {"application/javascript", "js", NULL},
+ {NULL, NULL, NULL}
+};
+
+
+static magic_t magic_all = NULL;
+static magic_t magic_charset = NULL;
+
+
+static const char*
+get_extension(const char *filename)
+{
+ const char *ext = NULL;
+ unsigned int i;
+ for (i = strlen(filename); i > 0; i--) {
+ if (filename[i] == '.') {
+ ext = filename + i + 1;
+ break;
+ }
+ }
+ if (i == 0)
+ return NULL;
+ return ext;
+}
+
+
+static char*
+guess_content_type(const char *filename, int fd)
+{
+ int newfd;
+
+ // try "supported" types first, and just use libmagic for charset
+ const char *extension = get_extension(filename);
+ if (extension == NULL)
+ goto libmagic;
+ const char *supported = NULL;
+ for (unsigned int i = 0; content_types[i].extension != NULL; i++)
+ if (0 == strcmp(content_types[i].extension, extension))
+ supported = content_types[i].mimetype;
+ if (supported != NULL) {
+ newfd = dup(fd);
+ if (-1 != newfd) {
+ const char* charset = magic_descriptor(magic_charset, newfd);
+ close(newfd);
+ if (charset != NULL)
+ return sb_strdup_printf("%s; charset=%s", supported, charset);
+ }
+ return sb_strdup(supported);
+ }
+
+libmagic:
+
+ // fallback to use libmagic for everything
+ newfd = dup(fd);
+ if (-1 != newfd) {
+ const char* content_type = magic_descriptor(magic_all, newfd);
+ close(newfd);
+ if (content_type != NULL)
+ return sb_strdup(content_type);
+ }
+ return sb_strdup("application/octet-stream");
+}
+
+
+static void
+handler(struct evhttp_request *request, void *ptr)
+{
+ const char *root = ptr;
+ const char *uri = evhttp_request_get_uri(request);
+
+ struct evhttp_uri *decoded_uri = evhttp_uri_parse(uri);
+ if (decoded_uri == NULL) {
+ evhttp_send_error(request, 400, "Bad request");
+ return;
+ }
+
+ const char *path = evhttp_uri_get_path(decoded_uri);
+ if (path == NULL)
+ path = "/";
+
+ char *decoded_path = evhttp_uridecode(path, 0, NULL);
+ if (decoded_path == NULL) {
+ evhttp_send_error(request, 400, "Bad request");
+ goto point1;
+ }
+
+ char *abs_path = sb_strdup_printf("%s/%s", root, decoded_path);
+ char *real_path = realpath(abs_path, NULL);
+ free(abs_path);
+
+ if (real_path == NULL) {
+ evhttp_send_error(request, 404, "Not found");
+ goto point2;
+ }
+
+ char *real_root = realpath(root, NULL);
+ if (real_root == NULL) {
+ evhttp_send_error(request, 500, "Internal server error");
+ goto point3;
+ }
+
+ if (0 != strncmp(real_root, real_path, strlen(real_root))) {
+ evhttp_send_error(request, 404, "Not found");
+ goto point4;
+ }
+
+ struct stat st;
+ if (0 > stat(real_path, &st)) {
+ evhttp_send_error(request, 404, "Not found");
+ goto point4;
+ }
+
+ bool add_slash = false;
+
+ if (S_ISDIR(st.st_mode)) {
+ char *found = NULL;
+
+ for (unsigned int i = 0; content_types[i].mimetype != NULL; i++) {
+ if (content_types[i].index == NULL)
+ continue;
+ char *f = sb_strdup_printf("%s/%s", real_path,
+ content_types[i].index);
+ if (0 == access(f, F_OK)) {
+ found = sb_strdup(f);
+ break;
+ }
+ free(f);
+ }
+
+ if (found == NULL) {
+ evhttp_send_error(request, 403, "Forbidden");
+ goto point4;
+ }
+
+ size_t path_len = strlen(path);
+ if (path_len > 0 && path[path_len - 1] != '/')
+ add_slash = true;
+
+ free(real_path);
+ real_path = found;
+ }
+
+ int fd;
+ if ((fd = open(real_path, O_RDONLY)) < 0) {
+ evhttp_send_error(request, 500, "Internal server error");
+ goto point4;
+ }
+
+ char *type = guess_content_type(real_path, fd);
+
+ if (fstat(fd, &st) < 0) {
+ evhttp_send_error(request, 500, "Internal server error");
+ goto point5;
+ }
+
+ struct evkeyvalq *headers = evhttp_request_get_output_headers(request);
+
+ if (add_slash) {
+ char *tmp = sb_strdup_printf("%s/", path);
+ evhttp_add_header(headers, "Location", tmp);
+ free(tmp);
+ // production webservers usually returns 301 in such cases, but 302 is
+ // better for development/testing.
+ evhttp_send_reply(request, 302, "Found", NULL);
+ goto point5;
+ }
+
+ evhttp_add_header(headers, "Content-Type", type);
+ char *content_length = sb_strdup_printf("%zu", st.st_size);
+ evhttp_add_header(headers, "Content-Length", content_length);
+ free(content_length);
+
+ struct evbuffer *evb = evbuffer_new();
+ evbuffer_add_file(evb, fd, 0, st.st_size);
+ evhttp_send_reply(request, 200, "OK", evb);
+
+point5:
+ free(type);
+point4:
+ free(real_root);
+point3:
+ free(real_path);
+point2:
+ free(decoded_path);
+point1:
+ evhttp_uri_free(decoded_uri);
+}
+
+
+static int
+runserver(const char *address, unsigned short port, const char *root)
+{
+ struct event_base *base = event_base_new();
+ if (base == NULL) {
+ fprintf(stderr, "error: failed to initialize event base\n");
+ return 1;
+ }
+
+ struct evhttp *http = evhttp_new(base);
+ if (http == NULL) {
+ fprintf(stderr, "error: failed to initialize HTTP server\n");
+ return 1;
+ }
+
+ evhttp_set_gencb(http, handler, (char*) root);
+
+ evhttp_set_allowed_methods(http, EVHTTP_REQ_GET | EVHTTP_REQ_HEAD);
+
+ if (0 != evhttp_bind_socket(http, address, port)) {
+ fprintf(stderr, "error: failed to bind socket to %s:%d\n", address,
+ port);
+ return 1;
+ }
+
+ fprintf(stderr, " * Running on http://%s:%d/\n", address, port);
+
+ event_base_dispatch(base);
+
+ return 0;
+}
+
+
+static void
+print_help(void)
+{
+ printf(
+ "usage:\n"
+ " blogc-runserver [-h] [-v] [-t HOST] [-p PORT] DOCROOT\n"
+ " - A simple HTTP server to test blogc websites.\n"
+ "\n"
+ "positional arguments:\n"
+ " DOCROOT document root directory\n"
+ "\n"
+ "optional arguments:\n"
+ " -h show this help message and exit\n"
+ " -v show version and exit\n"
+ " -t HOST set server listen address (default: 127.0.0.1)\n"
+ " -p PORT set server listen port (default: 8080)\n");
+}
+
+
+static void
+print_usage(void)
+{
+ printf("usage: blogc-runserver [-h] [-v] [-t HOST] [-p PORT] DOCROOT\n");
+}
+
+
+int
+main(int argc, char **argv)
+{
+ signal(SIGPIPE, SIG_IGN);
+
+ int rv = 0;
+ char *host = NULL;
+ char *docroot = NULL;
+ unsigned short port = 8080;
+
+ unsigned int args = 0;
+
+ for (unsigned int i = 1; i < argc; i++) {
+ if (argv[i][0] == '-') {
+ switch (argv[i][1]) {
+ case 'h':
+ print_help();
+ goto cleanup;
+ case 'v':
+ printf("%s\n", PACKAGE_STRING);
+ goto cleanup;
+ case 't':
+ if (argv[i][2] != '\0')
+ host = sb_strdup(argv[i] + 2);
+ else
+ host = sb_strdup(argv[++i]);
+ break;
+ case 'p':
+ if (argv[i][2] != '\0')
+ port = strtoul(argv[i] + 2, NULL, 10);
+ else
+ port = strtoul(argv[++i], NULL, 10);
+ break;
+ default:
+ print_usage();
+ fprintf(stderr, "blogc-runserver: error: invalid "
+ "argument: -%c\n", argv[i][1]);
+ rv = 2;
+ goto cleanup;
+ }
+ }
+ else {
+ if (args > 0) {
+ print_usage();
+ fprintf(stderr, "blogc-runserver: error: only one positional "
+ "argument allowed\n");
+ rv = 2;
+ goto cleanup;
+ }
+ args++;
+ docroot = sb_strdup(argv[i]);
+ }
+ }
+
+ if (docroot == NULL) {
+ print_usage();
+ fprintf(stderr, "blogc-runserver: error: document root directory "
+ "required\n");
+ rv = 2;
+ goto cleanup;
+ }
+
+ if (host == NULL)
+ host = sb_strdup("127.0.0.1");
+
+ magic_all = magic_open(MAGIC_MIME);
+ magic_charset = magic_open(MAGIC_MIME_ENCODING);
+ if (magic_all == NULL || magic_charset == NULL) {
+ fprintf(stderr, "error: failed to initialize libmagic\n");
+ rv = 1;
+ goto cleanup;
+ }
+
+ if ((0 != magic_load(magic_all, NULL)) ||
+ (0 != magic_load(magic_charset, NULL)))
+ {
+ fprintf(stderr, "error: failed to load libmagic data\n");
+ magic_close(magic_all);
+ magic_close(magic_charset);
+ rv = 1;
+ goto cleanup;
+ }
+
+ rv = runserver(host, port, docroot);
+
+ magic_close(magic_all);
+ magic_close(magic_charset);
+
+cleanup:
+ free(host);
+ free(docroot);
+
+ return rv;
+}
diff --git a/src/blogc-runserver/httpd-utils.c b/src/blogc-runserver/httpd-utils.c
deleted file mode 100644
index 9d374ae..0000000
--- a/src/blogc-runserver/httpd-utils.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdbool.h>
-#include <string.h>
-#include <unistd.h>
-#include "../common/utils.h"
-#include "httpd-utils.h"
-
-
-char*
-br_readline(int socket)
-{
- bc_string_t *rv = bc_string_new();
- char buffer[READLINE_BUFFER_SIZE];
- ssize_t len;
- bool end = false;
-
- while ((len = read(socket, buffer, READLINE_BUFFER_SIZE)) > 0) {
- if (!end) {
- for (ssize_t i = 0; i < len; i++) {
- if (buffer[i] == '\r' || buffer[i] == '\n' || buffer[i] == '\0') {
- // we finished "recording", but still need to exhaust
- // request data.
- end = true;
- break;
- }
- bc_string_append_c(rv, buffer[i]);
- }
- }
- if (len < READLINE_BUFFER_SIZE) {
- break;
- }
- }
-
- return bc_string_free(rv, false);
-}
-
-
-int
-br_hextoi(const char c)
-{
- if (c >= '0' && c <= '9')
- return c - '0';
- if (c >= 'a' && c <= 'f')
- return c - 'a' + 10;
- if (c >= 'A' && c <= 'F')
- return c - 'A' + 10;
- return -1;
-}
-
-
-char*
-br_urldecode(const char *str)
-{
- bc_string_t *rv = bc_string_new();
-
- for (size_t i = 0; i < strlen(str); i++) {
- switch (str[i]) {
- case '%':
- if (i + 2 < strlen(str)) {
- int p1 = br_hextoi(str[i + 1]) * 16;
- int p2 = br_hextoi(str[i + 2]);
- if (p1 >= 0 && p2 >= 0) {
- bc_string_append_c(rv, p1 + p2);
- i += 2;
- continue;
- }
- }
- bc_string_append_c(rv, '%');
- break;
- case '+':
- bc_string_append_c(rv, ' ');
- break;
- default:
- bc_string_append_c(rv, str[i]);
- }
- }
-
- return bc_string_free(rv, false);
-}
-
-
-const char*
-br_get_extension(const char *filename)
-{
- const char *ext = NULL;
- size_t i;
- for (i = strlen(filename); i > 0; i--) {
- if (filename[i] == '.') {
- ext = filename + i + 1;
- break;
- }
- if ((filename[i] == '/') || (filename[i] == '\\'))
- return NULL;
- }
- if (i == 0)
- return NULL;
- return ext;
-}
diff --git a/src/blogc-runserver/httpd-utils.h b/src/blogc-runserver/httpd-utils.h
deleted file mode 100644
index 06ad6e1..0000000
--- a/src/blogc-runserver/httpd-utils.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _HTTPD_UTILS_H
-#define _HTTPD_UTILS_H
-
-#define READLINE_BUFFER_SIZE 2048
-
-char* br_readline(int socket);
-int br_hextoi(const char c);
-char* br_urldecode(const char *str);
-const char* br_get_extension(const char *filename);
-
-#endif /* _HTTPD_UTILS_H */
diff --git a/src/blogc-runserver/httpd.c b/src/blogc-runserver/httpd.c
deleted file mode 100644
index fe98288..0000000
--- a/src/blogc-runserver/httpd.c
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <pthread.h>
-#include "../common/error.h"
-#include "../common/file.h"
-#include "../common/utils.h"
-#include "mime.h"
-#include "httpd-utils.h"
-
-#define LISTEN_BACKLOG 100
-
-typedef struct {
- pthread_t thread;
- bool initialized;
-} thread_data_t;
-
-typedef struct {
- size_t thread_id;
- int socket;
- char *ip;
- const char *docroot;
-} request_data_t;
-
-
-static void
-error(int socket, int status_code, const char *error)
-{
- char *str = bc_strdup_printf(
- "HTTP/1.0 %d %s\r\n"
- "Content-Type: text/html\r\n"
- "Content-Length: %zu\r\n"
- "Connection: close\r\n"
- "\r\n"
- "<h1>%s</h1>\n", status_code, error, strlen(error) + 10, error);
- size_t str_len = strlen(str);
- if (str_len != write(socket, str, str_len)) {
- fprintf(stderr, "warning: Failed to write full response header!\n");
- }
- free(str);
-}
-
-
-static void*
-handle_request(void *arg)
-{
- request_data_t *req = arg;
- size_t thread_id = req->thread_id;
- int client_socket = req->socket;
- char *ip = req->ip;
- const char *docroot = req->docroot;
- free(arg);
-
- char *conn_line = br_readline(client_socket);
- if (conn_line == NULL || conn_line[0] == '\0')
- goto point0;
-
- unsigned short status_code = 200;
-
- char **pieces = bc_str_split(conn_line, ' ', 3);
- if (bc_strv_length(pieces) != 3) {
- status_code = 400;
- error(client_socket, 400, "Bad Request");
- goto point1;
- }
-
- if (strcmp(pieces[0], "GET") != 0) {
- status_code = 405;
- error(client_socket, 405, "Method Not Allowed");
- goto point1;
- }
-
- char **pieces2 = bc_str_split(pieces[1], '?', 2);
- char *path = br_urldecode(pieces2[0]);
- bc_strv_free(pieces2);
-
- if (path == NULL) {
- status_code = 400;
- error(client_socket, 400, "Bad Request");
- goto point2;
- }
-
- char *abs_path = bc_strdup_printf("%s/%s", docroot, path);
- char *real_path = realpath(abs_path, NULL);
- free(abs_path);
-
- if (real_path == NULL) {
- if (errno == ENOENT) {
- status_code = 404;
- error(client_socket, 404, "Not Found");
- }
- else {
- status_code = 500;
- error(client_socket, 500, "Internal Server Error");
- }
- goto point2;
- }
-
- char *real_root = realpath(docroot, NULL);
- if (real_root == NULL) {
- status_code = 500;
- error(client_socket, 500, "Internal Server Error");
- goto point3;
- }
-
- if (0 != strncmp(real_root, real_path, strlen(real_root))) {
- status_code = 404;
- error(client_socket, 404, "Not Found");
- goto point4;
- }
-
- struct stat st;
- if (0 > stat(real_path, &st)) {
- status_code = 404;
- error(client_socket, 404, "Not Found");
- goto point4;
- }
-
- bool add_slash = false;
-
- if (S_ISDIR(st.st_mode)) {
- char *found = br_mime_guess_index(real_path);
-
- if (found == NULL) {
- status_code = 403;
- error(client_socket, 403, "Forbidden");
- goto point4;
- }
-
- size_t path_len = strlen(path);
- if (path_len > 0 && path[path_len - 1] != '/')
- add_slash = true;
-
- free(real_path);
- real_path = found;
- }
-
- if (0 != access(real_path, F_OK)) {
- status_code = 500;
- error(client_socket, 500, "Internal Server Error");
- goto point4;
- }
-
- if (add_slash) {
- // production webservers usually returns 301 in such cases, but 302 is
- // better for development/testing.
- char *tmp = bc_strdup_printf(
- "HTTP/1.0 302 Found\r\n"
- "Location: %s/\r\n"
- "Content-Length: 0\r\n"
- "Connection: close\r\n"
- "\r\n", path);
- status_code = 302;
- size_t tmp_len = strlen(tmp);
- if (tmp_len != write(client_socket, tmp, tmp_len)) {
- fprintf(stderr, "warning: Failed to write full response header!\n");
- }
- free(tmp);
- goto point4;
- }
-
- size_t len;
- bc_error_t *err = NULL;
- char* contents = bc_file_get_contents(real_path, false, &len, &err);
- if (err != NULL) {
- status_code = 500;
- error(client_socket, 500, "Internal Server Error");
- bc_error_free(err);
- goto point4;
- }
-
- char *out = bc_strdup_printf(
- "HTTP/1.0 200 OK\r\n"
- "Content-Type: %s\r\n"
- "Content-Length: %zu\r\n"
- "Connection: close\r\n"
- "\r\n", br_mime_guess_content_type(real_path), len);
- size_t out_len = strlen(out);
- if (out_len != write(client_socket, out, out_len)) {
- fprintf(stderr, "warning: Failed to write full response header!\n");
- }
- free(out);
-
- if (len != write(client_socket, contents, len)) {
- fprintf(stderr, "warning: Failed to write full response body!\n");
- }
- free(contents);
-
-point4:
- free(real_root);
-point3:
- free(real_path);
-point2:
- free(path);
-point1:
- fprintf(stderr, "[Thread-%zu] %s - - \"%s\" %d\n", thread_id + 1,
- ip, conn_line, status_code);
- free(conn_line);
- bc_strv_free(pieces);
-point0:
- free(ip);
- close(client_socket);
- return NULL;
-}
-
-
-static char*
-br_httpd_get_ip(int af, const struct sockaddr *addr)
-{
- char host[INET6_ADDRSTRLEN];
- if (af == AF_INET6) {
- struct sockaddr_in6 *a = (struct sockaddr_in6*) addr;
- inet_ntop(af, &(a->sin6_addr), host, INET6_ADDRSTRLEN);
- }
- else {
- struct sockaddr_in *a = (struct sockaddr_in*) addr;
- inet_ntop(af, &(a->sin_addr), host, INET6_ADDRSTRLEN);
- }
- return bc_strdup(host);
-}
-
-
-static uint16_t
-br_httpd_get_port(int af, const struct sockaddr *addr)
-{
- in_port_t port = 0;
- if (af == AF_INET6) {
- struct sockaddr_in6 *a = (struct sockaddr_in6*) addr;
- port = a->sin6_port;
- }
- else {
- struct sockaddr_in *a = (struct sockaddr_in*) addr;
- port = a->sin_port;
- }
- return ntohs(port);
-}
-
-
-int
-br_httpd_run(const char *host, const char *port, const char *docroot,
- size_t max_threads)
-{
- int err;
- struct addrinfo *result;
- struct addrinfo hints = {
- .ai_family = AF_UNSPEC,
- .ai_socktype = SOCK_STREAM,
- .ai_flags = AI_PASSIVE,
- .ai_protocol = 0,
- .ai_canonname = NULL,
- .ai_addr = NULL,
- .ai_next = NULL,
- };
- if (0 != (err = getaddrinfo(host, port, &hints, &result))) {
- fprintf(stderr, "Failed to get host:port info: %s\n",
- gai_strerror(err));
- return 1;
- }
-
- thread_data_t threads[max_threads];
- for (size_t i = 0; i < max_threads; i++)
- threads[i].initialized = false;
-
- int rv = 0;
-
- struct addrinfo *rp;
- int server_socket = 0;
-
- int ai_family = 0;
- char *final_host = NULL;
- uint16_t final_port = 0;
-
- for (rp = result; rp != NULL; rp = rp->ai_next) {
- final_host = br_httpd_get_ip(rp->ai_family, rp->ai_addr);
- final_port = br_httpd_get_port(rp->ai_family, rp->ai_addr);
- server_socket = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
- if (server_socket == -1) {
- if (rp->ai_next == NULL) {
- fprintf(stderr, "Failed to open server socket (%s:%d): %s\n",
- final_host, final_port, strerror(errno));
- rv = 1;
- goto cleanup0;
- }
- continue;
- }
- int value = 1;
- if (0 > setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &value,
- sizeof(int)))
- {
- if (rp->ai_next == NULL) {
- fprintf(stderr, "Failed to set socket option (%s:%d): %s\n",
- final_host, final_port, strerror(errno));
- rv = 1;
- goto cleanup;
- }
- close(server_socket);
- continue;
- }
- if (0 == bind(server_socket, rp->ai_addr, rp->ai_addrlen)) {
- ai_family = rp->ai_family;
- break;
- }
- else {
- if (rp->ai_next == NULL) {
- fprintf(stderr, "Failed to bind to server socket (%s:%d): %s\n",
- final_host, final_port, strerror(errno));
- rv = 1;
- goto cleanup;
- }
- }
- free(final_host);
- close(server_socket);
- }
-
- if (-1 == listen(server_socket, LISTEN_BACKLOG)) {
- fprintf(stderr, "Failed to listen to server socket (%s:%d): %s\n",
- final_host, final_port, strerror(errno));
- rv = 1;
- goto cleanup;
- }
-
- fprintf(stderr, " * Running on http://");
- if (ai_family == AF_INET6)
- fprintf(stderr, "[%s]", final_host);
- else
- fprintf(stderr, "%s", final_host);
- if (final_port != 80)
- fprintf(stderr, ":%d", final_port);
- fprintf(stderr, "/ (max threads: %zu)\n"
- "\n"
- "WARNING!!! This is a development server, DO NOT RUN IT IN PRODUCTION!\n"
- "\n", max_threads);
-
- size_t current_thread = 0;
-
- while (1) {
- struct sockaddr_in6 addr6;
- struct sockaddr_in addr;
-
- socklen_t addrlen;
- struct sockaddr *client_addr = NULL;
-
- if (ai_family == AF_INET6) {
- addrlen = sizeof(addr6);
- client_addr = (struct sockaddr*) &addr6;
- }
- else {
- addrlen = sizeof(addr);
- client_addr = (struct sockaddr*) &addr;
- }
-
- int client_socket = accept(server_socket, client_addr, &addrlen);
- if (client_socket == -1) {
- fprintf(stderr, "Failed to accept connection: %s\n", strerror(errno));
- rv = 1;
- goto cleanup;
- }
-
- request_data_t *arg = malloc(sizeof(request_data_t));
- arg->thread_id = current_thread;
- arg->socket = client_socket;
- arg->ip = br_httpd_get_ip(ai_family, client_addr);
- arg->docroot = docroot;
-
- if (threads[current_thread].initialized) {
- if (pthread_join(threads[current_thread].thread, NULL) != 0) {
- fprintf(stderr, "Failed to join thread\n");
- free(arg->ip);
- free(arg);
- rv = 1;
- goto cleanup;
- }
- }
-
- if (pthread_create(&(threads[current_thread].thread), NULL,
- handle_request, arg) != 0)
- {
- fprintf(stderr, "Failed to create thread\n");
- rv = 1;
- goto cleanup;
- }
-
- threads[current_thread++].initialized = true;
-
- if (current_thread >= max_threads)
- current_thread = 0;
- }
-
-cleanup:
- close(server_socket);
-
-cleanup0:
- free(final_host);
- freeaddrinfo(result);
- return rv;
-}
diff --git a/src/blogc-runserver/httpd.h b/src/blogc-runserver/httpd.h
deleted file mode 100644
index b71a8d9..0000000
--- a/src/blogc-runserver/httpd.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _HTTPD_H
-#define _HTTPD_H
-
-int br_httpd_run(const char *host, const char *port, const char *docroot,
- size_t max_threads);
-
-#endif /* _HTTPD_H */
diff --git a/src/blogc-runserver/main.c b/src/blogc-runserver/main.c
deleted file mode 100644
index 1c5be29..0000000
--- a/src/blogc-runserver/main.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif /* HAVE_CONFIG_H */
-
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "../common/utils.h"
-#include "httpd.h"
-
-
-static void
-print_help(const char *default_host, const char *default_port)
-{
- printf(
- "usage:\n"
- " blogc-runserver [-h] [-v] [-t HOST] [-p PORT] [-m THREADS] DOCROOT\n"
- " - A simple HTTP server to test blogc websites.\n"
- "\n"
- "positional arguments:\n"
- " DOCROOT document root directory\n"
- "\n"
- "optional arguments:\n"
- " -h show this help message and exit\n"
- " -v show version and exit\n"
- " -t HOST set server listen address (default: %s)\n"
- " -p PORT set server listen port (default: %s)\n"
- " -m THREADS set maximum number of threads to spawn (default: 20)\n",
- default_host, default_port);
-}
-
-
-static void
-print_usage(void)
-{
- printf("usage: blogc-runserver [-h] [-v] [-t HOST] [-p PORT] [-m THREADS] DOCROOT\n");
-}
-
-
-int
-main(int argc, char **argv)
-{
- struct sigaction new_action;
- new_action.sa_handler = SIG_IGN;
- sigemptyset(&new_action.sa_mask);
- new_action.sa_flags = 0;
- sigaction(SIGPIPE, &new_action, NULL);
-
- int rv = 0;
- char *host = NULL;
- char *port = NULL;
- char *docroot = NULL;
- size_t max_threads = 20;
- char *ptr;
- char *endptr;
-
- char *tmp_host = getenv("BLOGC_RUNSERVER_DEFAULT_HOST");
- char *default_host = bc_strdup(tmp_host != NULL ? tmp_host : "127.0.0.1");
- char *tmp_port = getenv("BLOGC_RUNSERVER_DEFAULT_PORT");
- char *default_port = bc_strdup(tmp_port != NULL ? tmp_port : "8080");
-
- size_t args = 0;
-
- for (size_t i = 1; i < argc; i++) {
- if (argv[i][0] == '-') {
- switch (argv[i][1]) {
- case 'h':
- print_help(default_host, default_port);
- goto cleanup;
- case 'v':
- printf("%s\n", PACKAGE_STRING);
- goto cleanup;
- case 't':
- if (argv[i][2] != '\0')
- host = bc_strdup(argv[i] + 2);
- else
- host = bc_strdup(argv[++i]);
- break;
- case 'p':
- if (argv[i][2] != '\0')
- port = bc_strdup(argv[i] + 2);
- else
- port = bc_strdup(argv[++i]);
- break;
- case 'm':
- if (argv[i][2] != '\0')
- ptr = argv[i] + 2;
- else
- ptr = argv[++i];
- max_threads = strtoul(ptr, &endptr, 10);
- if (*ptr != '\0' && *endptr != '\0')
- fprintf(stderr, "blogc-runserver: warning: invalid value "
- "for -m argument: %s. using %zu instead\n", ptr, max_threads);
- break;
- default:
- print_usage();
- fprintf(stderr, "blogc-runserver: error: invalid "
- "argument: -%c\n", argv[i][1]);
- rv = 1;
- goto cleanup;
- }
- }
- else {
- if (args > 0) {
- print_usage();
- fprintf(stderr, "blogc-runserver: error: only one positional "
- "argument allowed\n");
- rv = 1;
- goto cleanup;
- }
- args++;
- docroot = bc_strdup(argv[i]);
- }
- }
-
- if (docroot == NULL) {
- print_usage();
- fprintf(stderr, "blogc-runserver: error: document root directory "
- "required\n");
- rv = 1;
- goto cleanup;
- }
-
- if (max_threads <= 0 || max_threads > 1000) {
- print_usage();
- fprintf(stderr, "blogc-runserver: error: invalid value for -m. "
- "Must be integer > 0 and <= 1000\n");
- rv = 1;
- goto cleanup;
- }
-
- rv = br_httpd_run(
- host != NULL ? host : default_host,
- port != NULL ? port : default_port,
- docroot, max_threads);
-
-cleanup:
- free(default_host);
- free(default_port);
- free(host);
- free(port);
- free(docroot);
-
- return rv;
-}
diff --git a/src/blogc-runserver/mime.c b/src/blogc-runserver/mime.c
deleted file mode 100644
index 636c496..0000000
--- a/src/blogc-runserver/mime.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include "../common/utils.h"
-#include "httpd-utils.h"
-
-
-// mime types with index should be in the begin of the list. first NULL
-// index aborts the lookup, for optimization
-static const struct content_type_map {
- const char *mimetype;
- const char *extension;
- const char *index;
-} content_types[] = {
-
- // with index
- {"text/html", "html", "index.html"},
- {"text/html", "htm", "index.htm"},
- {"text/html", "shtml", "index.shtml"},
- {"text/xml", "xml", "index.xml"},
- {"text/plain", "txt", "index.txt"},
- {"application/xhtml+xml", "xhtml", "index.xhtml"},
-
- // without index
- {"text/css", "css", NULL},
- {"image/gif", "gif", NULL},
- {"image/jpeg", "jpeg", NULL},
- {"image/jpeg", "jpg", NULL},
- {"application/javascript", "js", NULL},
- {"application/atom+xml", "atom", NULL},
- {"application/rss+xml", "rss", NULL},
- {"text/mathml", "mml", NULL},
- {"text/vnd.sun.j2me.app-descriptor", "jad", NULL},
- {"text/vnd.wap.wml", "wml", NULL},
- {"text/x-component", "htc", NULL},
- {"image/png", "png", NULL},
- {"image/tiff", "tif", NULL},
- {"image/tiff", "tiff", NULL},
- {"image/vnd.wap.wbmp", "wbmp", NULL},
- {"image/x-icon", "ico", NULL},
- {"image/x-jng", "jng", NULL},
- {"image/x-ms-bmp", "bmp", NULL},
- {"image/svg+xml", "svg", NULL},
- {"image/svg+xml", "svgz", NULL},
- {"image/webp", "webp", NULL},
- {"application/font-woff", "woff", NULL},
- {"application/java-archive", "jar", NULL},
- {"application/java-archive", "war", NULL},
- {"application/java-archive", "ear", NULL},
- {"application/json", "json", NULL},
- {"application/mac-binhex40", "hqx", NULL},
- {"application/msword", "doc", NULL},
- {"application/pdf", "pdf", NULL},
- {"application/postscript", "ps", NULL},
- {"application/postscript", "eps", NULL},
- {"application/postscript", "ai", NULL},
- {"application/rtf", "rtf", NULL},
- {"application/vnd.apple.mpegurl", "m3u8", NULL},
- {"application/vnd.ms-excel", "xls", NULL},
- {"application/vnd.ms-fontobject", "eot", NULL},
- {"application/vnd.ms-powerpoint", "ppt", NULL},
- {"application/vnd.wap.wmlc", "wmlc", NULL},
- {"application/vnd.google-earth.kml+xml", "kml", NULL},
- {"application/vnd.google-earth.kmz", "kmz", NULL},
- {"application/x-7z-compressed", "7z", NULL},
- {"application/x-cocoa", "cco", NULL},
- {"application/x-java-archive-diff", "jardiff", NULL},
- {"application/x-java-jnlp-file", "jnlp", NULL},
- {"application/x-makeself", "run", NULL},
- {"application/x-perl", "pl", NULL},
- {"application/x-perl", "pm", NULL},
- {"application/x-pilot", "prc", NULL},
- {"application/x-pilot", "pdb", NULL},
- {"application/x-rar-compressed", "rar", NULL},
- {"application/x-redhat-package-manager", "rpm", NULL},
- {"application/x-sea", "sea", NULL},
- {"application/x-shockwave-flash", "swf", NULL},
- {"application/x-stuffit", "sit", NULL},
- {"application/x-tcl", "tcl", NULL},
- {"application/x-tcl", "tk", NULL},
- {"application/x-x509-ca-cert", "der", NULL},
- {"application/x-x509-ca-cert", "pem", NULL},
- {"application/x-x509-ca-cert", "crt", NULL},
- {"application/x-xpinstall", "xpi", NULL},
- {"application/xspf+xml", "xspf", NULL},
- {"application/zip", "zip", NULL},
- {"application/octet-stream", "bin", NULL},
- {"application/octet-stream", "exe", NULL},
- {"application/octet-stream", "dll", NULL},
- {"application/octet-stream", "deb", NULL},
- {"application/octet-stream", "dmg", NULL},
- {"application/octet-stream", "iso", NULL},
- {"application/octet-stream", "img", NULL},
- {"application/octet-stream", "msi", NULL},
- {"application/octet-stream", "msp", NULL},
- {"application/octet-stream", "msm", NULL},
- {"application/vnd.openxmlformats-officedocument.wordprocessingml.document", "docx", NULL},
- {"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "xlsx", NULL},
- {"application/vnd.openxmlformats-officedocument.presentationml.presentation", "pptx", NULL},
- {"audio/midi", "mid", NULL},
- {"audio/midi", "midi", NULL},
- {"audio/midi", "kar", NULL},
- {"audio/mpeg", "mp3", NULL},
- {"audio/ogg", "ogg", NULL},
- {"audio/x-m4a", "m4a", NULL},
- {"audio/x-realaudio", "ra", NULL},
- {"video/3gpp", "3gpp", NULL},
- {"video/3gpp", "3gp", NULL},
- {"video/mp2t", "ts", NULL},
- {"video/mp4", "mp4", NULL},
- {"video/mpeg", "mpeg", NULL},
- {"video/mpeg", "mpg", NULL},
- {"video/quicktime", "mov", NULL},
- {"video/webm", "webm", NULL},
- {"video/x-flv", "flv", NULL},
- {"video/x-m4v", "m4v", NULL},
- {"video/x-mng", "mng", NULL},
- {"video/x-ms-asf", "asx", NULL},
- {"video/x-ms-asf", "asf", NULL},
- {"video/x-ms-wmv", "wmv", NULL},
- {"video/x-msvideo", "avi", NULL},
- {NULL, NULL, NULL}
-};
-
-
-const char*
-br_mime_guess_content_type(const char *filename)
-{
- const char *extension = br_get_extension(filename);
- if (extension == NULL)
- goto default_type;
- for (size_t i = 0; content_types[i].extension != NULL; i++) {
- if (0 == strcmp(content_types[i].extension, extension)) {
- return content_types[i].mimetype;
- }
- }
-
-default_type:
- return "application/octet-stream";
-}
-
-
-char*
-br_mime_guess_index(const char *path)
-{
- char *found = NULL;
- for (size_t i = 0; content_types[i].index != NULL; i++) {
- char *f = bc_strdup_printf("%s/%s", path, content_types[i].index);
- if (0 == access(f, F_OK)) {
- found = f;
- break;
- }
- free(f);
- }
- return found;
-}
diff --git a/src/blogc-runserver/mime.h b/src/blogc-runserver/mime.h
deleted file mode 100644
index b9fb013..0000000
--- a/src/blogc-runserver/mime.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _MIME_H
-#define _MIME_H
-
-const char* br_mime_guess_content_type(const char *filename);
-char* br_mime_guess_index(const char *path);
-
-#endif /* _MIME_H */
diff --git a/src/blogc.c b/src/blogc.c
new file mode 100644
index 0000000..c90070d
--- /dev/null
+++ b/src/blogc.c
@@ -0,0 +1,297 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif /* HAVE_SYS_STAT_H */
+
+#include <errno.h>
+#include <locale.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "debug.h"
+#include "template-parser.h"
+#include "loader.h"
+#include "renderer.h"
+#include "error.h"
+#include "utf8.h"
+#include "utils.h"
+
+#ifndef PACKAGE_VERSION
+#define PACKAGE_VERSION "Unknown"
+#endif
+
+
+static void
+blogc_print_help(void)
+{
+ printf(
+ "usage:\n"
+ " blogc [-h] [-v] [-d] [-l] [-D KEY=VALUE ...] [-p KEY] [-t TEMPLATE]\n"
+ " [-o OUTPUT] [SOURCE ...] - A blog compiler.\n"
+ "\n"
+ "positional arguments:\n"
+ " SOURCE source file(s)\n"
+ "\n"
+ "optional arguments:\n"
+ " -h show this help message and exit\n"
+ " -v show version and exit\n"
+ " -d enable debug\n"
+ " -l build listing page, from multiple source files\n"
+ " -D KEY=VALUE set global configuration parameter\n"
+ " -p KEY show the value of a global configuration parameter\n"
+ " after source parsing and exit\n"
+ " -t TEMPLATE template file\n"
+ " -o OUTPUT output file\n");
+}
+
+
+static void
+blogc_print_usage(void)
+{
+ printf(
+ "usage: blogc [-h] [-v] [-d] [-l] [-D KEY=VALUE ...] [-p KEY] [-t TEMPLATE]\n"
+ " [-o OUTPUT] [SOURCE ...]\n");
+}
+
+
+static void
+blogc_mkdir_recursive(const char *filename)
+{
+ char *fname = sb_strdup(filename);
+ for (char *tmp = fname; *tmp != '\0'; tmp++) {
+ if (*tmp != '/' && *tmp != '\\')
+ continue;
+#ifdef HAVE_SYS_STAT_H
+ char bkp = *tmp;
+ *tmp = '\0';
+ if ((strlen(fname) > 0) &&
+#if defined(WIN32) || defined(_WIN32)
+ (-1 == mkdir(fname)) &&
+#else
+ (-1 == mkdir(fname, 0777)) &&
+#endif
+ (errno != EEXIST))
+ {
+ fprintf(stderr, "blogc: error: failed to create output "
+ "directory (%s): %s\n", fname, strerror(errno));
+ free(fname);
+ exit(2);
+ }
+ *tmp = bkp;
+#else
+ // FIXME: show this warning only if actually trying to create a directory.
+ fprintf(stderr, "blogc: warning: can't create output directories "
+ "for your platform. please create the directories yourself.\n");
+ break;
+#endif
+ }
+ free(fname);
+}
+
+
+int
+main(int argc, char **argv)
+{
+ setlocale(LC_ALL, "");
+
+ int rv = 0;
+
+ bool debug = false;
+ bool listing = false;
+ char *template = NULL;
+ char *output = NULL;
+ char *print = NULL;
+ char *tmp = NULL;
+ char **pieces = NULL;
+
+ sb_slist_t *sources = NULL;
+ sb_trie_t *config = sb_trie_new(free);
+ sb_trie_insert(config, "BLOGC_VERSION", sb_strdup(PACKAGE_VERSION));
+
+ for (unsigned int i = 1; i < argc; i++) {
+ tmp = NULL;
+ if (argv[i][0] == '-') {
+ switch (argv[i][1]) {
+ case 'h':
+ blogc_print_help();
+ goto cleanup;
+ case 'v':
+ printf("%s\n", PACKAGE_STRING);
+ goto cleanup;
+ case 'd':
+ debug = true;
+ break;
+ case 'l':
+ listing = true;
+ break;
+ case 't':
+ if (argv[i][2] != '\0')
+ template = sb_strdup(argv[i] + 2);
+ else if (i + 1 < argc)
+ template = sb_strdup(argv[++i]);
+ break;
+ case 'o':
+ if (argv[i][2] != '\0')
+ output = sb_strdup(argv[i] + 2);
+ else if (i + 1 < argc)
+ output = sb_strdup(argv[++i]);
+ break;
+ case 'p':
+ if (argv[i][2] != '\0')
+ print = sb_strdup(argv[i] + 2);
+ else if (i + 1 < argc)
+ print = sb_strdup(argv[++i]);
+ break;
+ case 'D':
+ if (argv[i][2] != '\0')
+ tmp = argv[i] + 2;
+ else if (i + 1 < argc)
+ tmp = argv[++i];
+ if (tmp != NULL) {
+ if (!blogc_utf8_validate((uint8_t*) tmp, strlen(tmp))) {
+ fprintf(stderr, "blogc: error: invalid value for "
+ "-D (must be valid UTF-8 string): %s\n", tmp);
+ goto cleanup;
+ }
+ pieces = sb_str_split(tmp, '=', 2);
+ if (sb_strv_length(pieces) != 2) {
+ fprintf(stderr, "blogc: error: invalid value for "
+ "-D (must have an '='): %s\n", tmp);
+ sb_strv_free(pieces);
+ rv = 2;
+ goto cleanup;
+ }
+ for (unsigned int j = 0; pieces[0][j] != '\0'; j++) {
+ if (!((pieces[0][j] >= 'A' && pieces[0][j] <= 'Z') ||
+ pieces[0][j] == '_'))
+ {
+ fprintf(stderr, "blogc: error: invalid value "
+ "for -D (configuration key must be uppercase "
+ "with '_'): %s\n", pieces[0]);
+ sb_strv_free(pieces);
+ rv = 2;
+ goto cleanup;
+ }
+ }
+ sb_trie_insert(config, pieces[0], sb_strdup(pieces[1]));
+ sb_strv_free(pieces);
+ pieces = NULL;
+ }
+ break;
+ default:
+ blogc_print_usage();
+ fprintf(stderr, "blogc: error: invalid argument: -%c\n",
+ argv[i][1]);
+ rv = 2;
+ goto cleanup;
+ }
+ }
+ else
+ sources = sb_slist_append(sources, sb_strdup(argv[i]));
+ }
+
+ if (!listing && sb_slist_length(sources) == 0) {
+ blogc_print_usage();
+ fprintf(stderr, "blogc: error: one source file is required\n");
+ rv = 2;
+ goto cleanup;
+ }
+
+ if (!listing && sb_slist_length(sources) > 1) {
+ blogc_print_usage();
+ fprintf(stderr, "blogc: error: only one source file should be provided, "
+ "if running without '-l'\n");
+ rv = 2;
+ goto cleanup;
+ }
+
+ blogc_error_t *err = NULL;
+
+ sb_slist_t *s = blogc_source_parse_from_files(config, sources, &err);
+ if (err != NULL) {
+ blogc_error_print(err);
+ rv = 2;
+ goto cleanup2;
+ }
+
+ if (print != NULL) {
+ const char *val = sb_trie_lookup(config, print);
+ if (val == NULL) {
+ fprintf(stderr, "blogc: error: configuration variable not found: %s\n",
+ print);
+ rv = 2;
+ }
+ else {
+ printf("%s\n", val);
+ }
+ goto cleanup2;
+ }
+
+ if (template == NULL) {
+ blogc_print_usage();
+ fprintf(stderr, "blogc: error: argument -t is required when rendering content\n");
+ rv = 2;
+ goto cleanup2;
+ }
+
+ sb_slist_t* l = blogc_template_parse_from_file(template, &err);
+ if (err != NULL) {
+ blogc_error_print(err);
+ rv = 2;
+ goto cleanup3;
+ }
+
+ if (debug)
+ blogc_debug_template(l);
+
+ char *out = blogc_render(l, s, config, listing);
+
+ bool write_to_stdout = (output == NULL || (0 == strcmp(output, "-")));
+
+ FILE *fp = stdout;
+ if (!write_to_stdout) {
+ blogc_mkdir_recursive(output);
+ fp = fopen(output, "w");
+ if (fp == NULL) {
+ fprintf(stderr, "blogc: error: failed to open output file (%s): %s\n",
+ output, strerror(errno));
+ rv = 2;
+ goto cleanup4;
+ }
+ }
+
+ if (out != NULL)
+ fprintf(fp, "%s", out);
+
+ if (!write_to_stdout)
+ fclose(fp);
+
+cleanup4:
+ free(out);
+cleanup3:
+ blogc_template_free_stmts(l);
+cleanup2:
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ blogc_error_free(err);
+cleanup:
+ sb_trie_free(config);
+ free(template);
+ free(output);
+ free(print);
+ sb_slist_free_full(sources, free);
+ return rv;
+}
diff --git a/src/blogc/content-parser.h b/src/blogc/content-parser.h
deleted file mode 100644
index a321155..0000000
--- a/src/blogc/content-parser.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _CONTENT_PARSER_H
-#define _CONTENT_PARSER_H
-
-#include <stddef.h>
-#include <stdbool.h>
-#include "../common/utils.h"
-
-char* blogc_slugify(const char *str);
-char* blogc_htmlentities(const char *str);
-char* blogc_fix_description(const char *paragraph);
-char* blogc_content_parse_inline(const char *src);
-bool blogc_is_ordered_list_item(const char *str, size_t prefix_len);
-char* blogc_content_parse(const char *src, size_t *end_excerpt,
- char **first_header, char **description, char **endl,
- bc_slist_t **headers);
-
-#endif /* _CONTENT_PARSER_H */
diff --git a/src/blogc/debug.c b/src/blogc/debug.c
deleted file mode 100644
index 11e7973..0000000
--- a/src/blogc/debug.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdio.h>
-
-#include "template-parser.h"
-#include "../common/utils.h"
-#include "debug.h"
-
-
-static const char*
-get_operator(blogc_template_operator_t op)
-{
- if (op & BLOGC_TEMPLATE_OP_NEQ)
- return "!=";
- if (op & BLOGC_TEMPLATE_OP_EQ) {
- if (op & BLOGC_TEMPLATE_OP_LT)
- return "<=";
- else if (op & BLOGC_TEMPLATE_OP_GT)
- return ">=";
- return "==";
- }
- if (op & BLOGC_TEMPLATE_OP_LT)
- return "<";
- else if (op & BLOGC_TEMPLATE_OP_GT)
- return ">";
- return "";
-}
-
-
-void
-blogc_debug_template(bc_slist_t *ast)
-{
- for (bc_slist_t *tmp = ast; tmp != NULL; tmp = tmp->next) {
- blogc_template_node_t *data = tmp->data;
- fprintf(stderr, "DEBUG: <TEMPLATE ");
- switch (data->type) {
- case BLOGC_TEMPLATE_NODE_IFDEF:
- fprintf(stderr, "IFDEF: %s", data->data[0]);
- break;
- case BLOGC_TEMPLATE_NODE_IFNDEF:
- fprintf(stderr, "IFNDEF: %s", data->data[0]);
- break;
- case BLOGC_TEMPLATE_NODE_IF:
- fprintf(stderr, "IF: %s %s %s", data->data[0],
- get_operator(data->op), data->data[1]);
- break;
- case BLOGC_TEMPLATE_NODE_ELSE:
- fprintf(stderr, "ELSE");
- break;
- case BLOGC_TEMPLATE_NODE_ENDIF:
- fprintf(stderr, "ENDIF");
- break;
- case BLOGC_TEMPLATE_NODE_FOREACH:
- fprintf(stderr, "FOREACH: %s", data->data[0]);
- break;
- case BLOGC_TEMPLATE_NODE_ENDFOREACH:
- fprintf(stderr, "ENDFOREACH");
- break;
- case BLOGC_TEMPLATE_NODE_BLOCK:
- fprintf(stderr, "BLOCK: %s", data->data[0]);
- break;
- case BLOGC_TEMPLATE_NODE_ENDBLOCK:
- fprintf(stderr, "ENDBLOCK");
- break;
- case BLOGC_TEMPLATE_NODE_VARIABLE:
- fprintf(stderr, "VARIABLE: %s", data->data[0]);
- break;
- case BLOGC_TEMPLATE_NODE_CONTENT:
- fprintf(stderr, "CONTENT: `%s`", data->data[0]);
- break;
- }
- fprintf(stderr, ">\n");
- }
-}
diff --git a/src/blogc/filelist-parser.c b/src/blogc/filelist-parser.c
deleted file mode 100644
index 984f25f..0000000
--- a/src/blogc/filelist-parser.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include "../common/utils.h"
-
-
-typedef enum {
- LINE_START = 1,
- LINE,
-} blogc_filelist_parser_state_t;
-
-
-bc_slist_t*
-blogc_filelist_parse(const char *src, size_t src_len)
-{
- size_t current = 0;
- bc_slist_t *rv = NULL;
- bc_string_t *line = bc_string_new();
- blogc_filelist_parser_state_t state = LINE_START;
-
- while (current < src_len) {
- char c = src[current];
- bool is_last = current == src_len - 1;
-
- switch (state) {
-
- case LINE_START:
- if (c == '#') {
- while (current < src_len) {
- if (src[current] == '\r' || src[current] == '\n')
- break;
- current++;
- }
- break;
- }
- if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
- break;
- state = LINE;
- continue;
-
- case LINE:
- if (c == '\r' || c == '\n' || is_last) {
- if (is_last && c != '\r' && c != '\n')
- bc_string_append_c(line, c);
- rv = bc_slist_append(rv, bc_str_strip(line->str));
- bc_string_free(line, false);
- line = bc_string_new();
- state = LINE_START;
- break;
- }
- bc_string_append_c(line, c);
- break;
-
- }
-
- current++;
- }
-
- bc_string_free(line, true);
-
- return rv;
-}
diff --git a/src/blogc/filelist-parser.h b/src/blogc/filelist-parser.h
deleted file mode 100644
index b068554..0000000
--- a/src/blogc/filelist-parser.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _FILELIST_PARSER_H
-#define _FILELIST_PARSER_H
-
-#include "../common/utils.h"
-
-bc_slist_t* blogc_filelist_parse(const char *src, size_t src_len);
-
-#endif /* _FILELIST_PARSER_H */
diff --git a/src/blogc/funcvars.c b/src/blogc/funcvars.c
deleted file mode 100644
index 6f0700b..0000000
--- a/src/blogc/funcvars.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "funcvars.h"
-#include "rusage.h"
-#include "sysinfo.h"
-#include "../common/utils.h"
-
-
-static const struct func_map {
- const char *variable;
- const blogc_funcvars_func_t func;
-} funcs[] = {
-
-#ifdef HAVE_RUSAGE
- {"BLOGC_RUSAGE_CPU_TIME", blogc_rusage_inject},
- {"BLOGC_RUSAGE_MEMORY", blogc_rusage_inject},
-#endif
-
-#ifdef HAVE_SYSINFO_HOSTNAME
- {"BLOGC_SYSINFO_HOSTNAME", blogc_sysinfo_inject_hostname},
-#endif
-
-#ifdef HAVE_SYSINFO_DATETIME
- {"BLOGC_SYSINFO_DATETIME", blogc_sysinfo_inject_datetime},
-#endif
-
- {"BLOGC_SYSINFO_USERNAME", blogc_sysinfo_inject_username},
- {"BLOGC_SYSINFO_INSIDE_DOCKER", blogc_sysinfo_inject_inside_docker},
- {NULL, NULL},
-};
-
-
-void
-blogc_funcvars_eval(bc_trie_t *global, const char *name)
-{
- if (global == NULL || name == NULL)
- return;
-
- // protect against evaluating the same function twice in the same global
- // context
- if (NULL != bc_trie_lookup(global, name))
- return;
-
- for (size_t i = 0; funcs[i].variable != NULL; i++) {
- if (0 == strcmp(name, funcs[i].variable)) {
- funcs[i].func(global);
- return;
- }
- }
-
- return;
-}
diff --git a/src/blogc/funcvars.h b/src/blogc/funcvars.h
deleted file mode 100644
index aae1bc3..0000000
--- a/src/blogc/funcvars.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef ___FUNCVARS_H
-#define ___FUNCVARS_H
-
-#include <stdbool.h>
-#include "../common/utils.h"
-
-typedef void (*blogc_funcvars_func_t) (bc_trie_t*);
-
-void blogc_funcvars_eval(bc_trie_t *global, const char *name);
-
-#endif /* ___FUNCVARS_H */
diff --git a/src/blogc/loader.c b/src/blogc/loader.c
deleted file mode 100644
index af30a1b..0000000
--- a/src/blogc/loader.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <math.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "datetime-parser.h"
-#include "source-parser.h"
-#include "template-parser.h"
-#include "loader.h"
-#include "../common/error.h"
-#include "../common/file.h"
-#include "../common/utils.h"
-#include "../common/sort.h"
-
-
-char*
-blogc_get_filename(const char *f)
-{
- if (f == NULL)
- return NULL;
-
- if (strlen(f) == 0)
- return NULL;
-
- char *filename = bc_strdup(f);
-
- // keep a pointer to original string
- char *tmp = filename;
-
- bool removed_dot = false;
- for (int i = strlen(tmp); i >= 0 ; i--) {
-
- // remove last extension
- if (!removed_dot && tmp[i] == '.') {
- tmp[i] = '\0';
- removed_dot = true;
- continue;
- }
-
- if (tmp[i] == '/' || tmp[i] == '\\') {
- tmp += i + 1;
- break;
- }
- }
-
- char *final_filename = bc_strdup(tmp);
- free(filename);
-
- return final_filename;
-}
-
-
-bc_slist_t*
-blogc_template_parse_from_file(const char *f, bc_error_t **err)
-{
- if (err == NULL || *err != NULL)
- return NULL;
-
- size_t len;
- char *s = bc_file_get_contents(f, true, &len, err);
- if (s == NULL)
- return NULL;
- bc_slist_t *rv = blogc_template_parse(s, len, err);
- free(s);
- return rv;
-}
-
-
-bc_trie_t*
-blogc_source_parse_from_file(bc_trie_t *conf, const char *f, bc_error_t **err)
-{
- if (err == NULL || *err != NULL)
- return NULL;
-
- size_t len;
- char *s = bc_file_get_contents(f, true, &len, err);
- if (s == NULL)
- return NULL;
-
- int toctree_maxdepth = -1;
- const char *maxdepth = bc_trie_lookup(conf, "TOCTREE_MAXDEPTH");
- if (maxdepth != NULL) {
- char *endptr;
- toctree_maxdepth = strtol(maxdepth, &endptr, 10);
- if (*maxdepth != '\0' && *endptr != '\0') {
- fprintf(stderr, "warning: invalid value for 'TOCTREE_MAXDEPTH' "
- "variable: %s. using %d instead\n", maxdepth, toctree_maxdepth);
- }
- }
-
- bc_trie_t *rv = blogc_source_parse(s, len, toctree_maxdepth, err);
-
- // set FILENAME variable
- if (rv != NULL) {
- char *filename = blogc_get_filename(f);
- if (filename != NULL)
- bc_trie_insert(rv, "FILENAME", filename);
- }
-
- free(s);
- return rv;
-}
-
-
-static int
-sort_source(const void *a, const void *b)
-{
- const char *ca = bc_trie_lookup((bc_trie_t*) a, "c");
- const char *cb = bc_trie_lookup((bc_trie_t*) b, "c");
-
- if (ca == NULL || cb == NULL) {
- return 0; // wat
- }
-
- unsigned long la = strtoul(ca, NULL, 10);
- unsigned long lb = strtoul(cb, NULL, 10);
-
- return (int) (lb - la);
-}
-
-
-static int
-sort_source_reverse(const void *a, const void *b)
-{
- return sort_source(b, a);
-}
-
-
-bc_slist_t*
-blogc_source_parse_from_files(bc_trie_t *conf, bc_slist_t *l, bc_error_t **err)
-{
- if (err == NULL || *err != NULL)
- return NULL;
-
- bool sort = bc_str_to_bool(bc_trie_lookup(conf, "FILTER_SORT"));
-
- bc_slist_t* sources = NULL;
- bc_error_t *tmp_err = NULL;
- size_t with_date = 0;
- for (bc_slist_t *tmp = l; tmp != NULL; tmp = tmp->next) {
- char *f = tmp->data;
- bc_trie_t *s = blogc_source_parse_from_file(conf, f, &tmp_err);
- if (s == NULL) {
- *err = bc_error_new_printf(BLOGC_ERROR_LOADER,
- "An error occurred while parsing source file: %s\n\n%s",
- f, tmp_err->msg);
- bc_error_free(tmp_err);
- bc_slist_free_full(sources, (bc_free_func_t) bc_trie_free);
- return NULL;
- }
-
- const char *date = bc_trie_lookup(s, "DATE");
- if (date != NULL) {
- with_date++;
- }
-
- if (sort) {
- if (date == NULL) {
- *err = bc_error_new_printf(BLOGC_ERROR_LOADER,
- "'FILTER_SORT' requires that 'DATE' variable is set for "
- "every source file: %s", f);
- bc_trie_free(s);
- bc_slist_free_full(sources, (bc_free_func_t) bc_trie_free);
- return NULL;
- }
-
- char *timestamp = blogc_convert_datetime(date, "%s", &tmp_err);
- if (timestamp == NULL) {
- *err = bc_error_new_printf(BLOGC_ERROR_LOADER,
- "An error occurred while parsing 'DATE' variable: %s"
- "\n\n%s", f, tmp_err->msg);
- bc_error_free(tmp_err);
- bc_trie_free(s);
- bc_slist_free_full(sources, (bc_free_func_t) bc_trie_free);
- return NULL;
- }
-
- bc_trie_insert(s, "c", timestamp);
- }
-
- sources = bc_slist_append(sources, s);
- }
-
- if (with_date > 0 && with_date < bc_slist_length(l)) {
- *err = bc_error_new_printf(BLOGC_ERROR_LOADER,
- "'DATE' variable provided for at least one source file, but not "
- "for all source files. It must be provided for all files.");
- bc_slist_free_full(sources, (bc_free_func_t) bc_trie_free);
- return NULL;
- }
-
- bool reverse = bc_str_to_bool(bc_trie_lookup(conf, "FILTER_REVERSE"));
-
- if (sort) {
- sources = bc_slist_sort(sources,
- (bc_sort_func_t) (reverse ? sort_source_reverse : sort_source));
- }
- else if (reverse) {
- bc_slist_t *tmp_sources = NULL;
- for (bc_slist_t *tmp = sources; tmp != NULL; tmp = tmp->next) {
- tmp_sources = bc_slist_prepend(tmp_sources, tmp->data);
- }
- bc_slist_t *tmp = sources;
- sources = tmp_sources;
- bc_slist_free(tmp);
- }
-
- const char *filter_tag = bc_trie_lookup(conf, "FILTER_TAG");
- const char *filter_page = bc_trie_lookup(conf, "FILTER_PAGE");
- const char *filter_per_page = bc_trie_lookup(conf, "FILTER_PER_PAGE");
-
- const char *ptr;
- char *endptr;
-
- ptr = filter_page != NULL ? filter_page : "";
- long page = strtol(ptr, &endptr, 10);
- if (*ptr != '\0' && *endptr != '\0')
- fprintf(stderr, "warning: invalid value for 'FILTER_PAGE' variable: "
- "%s. using %ld instead\n", ptr, page);
- if (page <= 0)
- page = 1;
-
- ptr = filter_per_page != NULL ? filter_per_page : "10";
- long per_page = strtol(ptr, &endptr, 10);
- if (*ptr != '\0' && *endptr != '\0')
- fprintf(stderr, "warning: invalid value for 'FILTER_PER_PAGE' variable: "
- "%s. using %ld instead\n", ptr, per_page);
- if (per_page < 0)
- per_page = 0;
-
- // poor man's pagination
- size_t start = (page - 1) * per_page;
- size_t end = start + per_page;
- size_t counter = 0;
-
- bc_slist_t *rv = NULL;
- for (bc_slist_t *tmp = sources; tmp != NULL; tmp = tmp->next) {
- bc_trie_t *s = tmp->data;
- if (filter_tag != NULL) {
- const char *tags_str = bc_trie_lookup(s, "TAGS");
- // if user wants to filter by tag and no tag is provided, skip it
- if (tags_str == NULL) {
- bc_trie_free(s);
- continue;
- }
- char **tags = bc_str_split(tags_str, ' ', 0);
- bool found = false;
- for (size_t i = 0; tags[i] != NULL; i++) {
- if (tags[i][0] == '\0')
- continue;
- if (0 == strcmp(tags[i], filter_tag))
- found = true;
- }
- bc_strv_free(tags);
- if (!found) {
- bc_trie_free(s);
- continue;
- }
- }
- if (filter_page != NULL) {
- if (counter < start || counter >= end) {
- counter++;
- bc_trie_free(s);
- continue;
- }
- counter++;
- }
- rv = bc_slist_append(rv, s);
- }
-
- bc_slist_free(sources);
-
- bool first = true;
- for (bc_slist_t *tmp = rv; tmp != NULL; tmp = tmp->next) {
- bc_trie_t *s = tmp->data;
- if (first) {
- const char *val = bc_trie_lookup(s, "DATE");
- if (val != NULL)
- bc_trie_insert(conf, "DATE_FIRST", bc_strdup(val));
- val = bc_trie_lookup(s, "FILENAME");
- if (val != NULL)
- bc_trie_insert(conf, "FILENAME_FIRST", bc_strdup(val));
- first = false;
- }
- if (tmp->next == NULL) { // last
- const char *val = bc_trie_lookup(s, "DATE");
- if (val != NULL)
- bc_trie_insert(conf, "DATE_LAST", bc_strdup(val));
- val = bc_trie_lookup(s, "FILENAME");
- if (val != NULL)
- bc_trie_insert(conf, "FILENAME_LAST", bc_strdup(val));
- }
- }
-
- if (filter_page != NULL) {
- size_t last_page = ceilf(((float) counter) / per_page);
- bc_trie_insert(conf, "CURRENT_PAGE", bc_strdup_printf("%ld", page));
- if (page > 1)
- bc_trie_insert(conf, "PREVIOUS_PAGE", bc_strdup_printf("%ld", page - 1));
- if (page < last_page)
- bc_trie_insert(conf, "NEXT_PAGE", bc_strdup_printf("%ld", page + 1));
- if (bc_slist_length(rv) > 0)
- bc_trie_insert(conf, "FIRST_PAGE", bc_strdup("1"));
- if (last_page > 0)
- bc_trie_insert(conf, "LAST_PAGE", bc_strdup_printf("%d", last_page));
- }
-
- return rv;
-}
diff --git a/src/blogc/loader.h b/src/blogc/loader.h
deleted file mode 100644
index fe88730..0000000
--- a/src/blogc/loader.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _LOADER_H
-#define _LOADER_H
-
-#include "../common/error.h"
-#include "../common/utils.h"
-
-char* blogc_get_filename(const char *f);
-bc_slist_t* blogc_template_parse_from_file(const char *f, bc_error_t **err);
-bc_trie_t* blogc_source_parse_from_file(bc_trie_t *conf, const char *f,
- bc_error_t **err);
-bc_slist_t* blogc_source_parse_from_files(bc_trie_t *conf, bc_slist_t *l,
- bc_error_t **err);
-
-#endif /* _LOADER_H */
diff --git a/src/blogc/main.c b/src/blogc/main.c
deleted file mode 100644
index 9bfa9cf..0000000
--- a/src/blogc/main.c
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif /* HAVE_CONFIG_H */
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif /* HAVE_SYS_STAT_H */
-
-#ifdef HAVE_SYSEXITS_H
-#include <sysexits.h>
-#else
-#define EX_CONFIG 78
-#endif /* HAVE_SYSEXITS_H */
-
-#include <errno.h>
-#include <locale.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "debug.h"
-#include "filelist-parser.h"
-#include "template-parser.h"
-#include "loader.h"
-#include "renderer.h"
-#include "../common/error.h"
-#include "../common/utf8.h"
-#include "../common/utils.h"
-#include "../common/stdin.h"
-
-#ifdef MAKE_EMBEDDED
-extern int bm_main(int argc, char **argv);
-#endif
-
-#ifndef PACKAGE_VERSION
-#define PACKAGE_VERSION "Unknown"
-#endif
-
-
-static void
-blogc_print_help(void)
-{
- printf(
- "usage:\n"
- " blogc "
-#ifdef MAKE_EMBEDDED
- "[-m] "
-#endif
- "[-h] [-v] [-d] [-i] [-l [-e SOURCE]] [-D KEY=VALUE ...] [-p KEY]\n"
- " [-t TEMPLATE] [-o OUTPUT] [SOURCE ...] - A blog compiler.\n"
- "\n"
- "positional arguments:\n"
- " SOURCE source file(s)\n"
- "\n"
- "optional arguments:\n"
- " -h show this help message and exit\n"
- " -v show version and exit\n"
- " -d enable debug\n"
- " -i read list of source files from standard input\n"
- " -l build listing page, from multiple source files\n"
- " -e SOURCE source file with content for listing page. requires '-l'\n"
- " -D KEY=VALUE set global variable\n"
- " -p KEY show the value of a variable after source parsing and exit\n"
- " -t TEMPLATE template file\n"
- " -o OUTPUT output file\n"
-#ifdef MAKE_EMBEDDED
- " -m call and pass arguments to embedded blogc-make\n"
-#endif
- );
-}
-
-
-static void
-blogc_print_usage(void)
-{
- printf(
- "usage: blogc "
-#ifdef MAKE_EMBEDDED
- "[-m] "
-#endif
- "[-h] [-v] [-d] [-i] [-l [-e SOURCE]] [-D KEY=VALUE ...] [-p KEY]\n"
- " [-t TEMPLATE] [-o OUTPUT] [SOURCE ...]\n");
-}
-
-
-static void
-blogc_mkdir_recursive(const char *filename)
-{
- char *fname = bc_strdup(filename);
- for (char *tmp = fname; *tmp != '\0'; tmp++) {
- if (*tmp != '/' && *tmp != '\\')
- continue;
-#ifdef HAVE_SYS_STAT_H
- char bkp = *tmp;
- *tmp = '\0';
- if ((strlen(fname) > 0) &&
-#if defined(WIN32) || defined(_WIN32)
- (-1 == mkdir(fname)) &&
-#else
- (-1 == mkdir(fname, 0777)) &&
-#endif
- (errno != EEXIST))
- {
- fprintf(stderr, "blogc: error: failed to create output "
- "directory (%s): %s\n", fname, strerror(errno));
- free(fname);
- exit(2);
- }
- *tmp = bkp;
-#else
- // FIXME: show this warning only if actually trying to create a directory.
- fprintf(stderr, "blogc: warning: can't create output directories "
- "for your platform. please create the directories yourself.\n");
- break;
-#endif
- }
- free(fname);
-}
-
-
-int
-main(int argc, char **argv)
-{
- setlocale(LC_ALL, "");
-
- int rv = 0;
-
-#ifdef MAKE_EMBEDDED
- bool embedded = false;
-#endif
- bool debug = false;
- bool input_stdin = false;
- bool listing = false;
- char *template = NULL;
- char *output = NULL;
- char *print = NULL;
- char *tmp = NULL;
- char **pieces = NULL;
-
- bc_slist_t *sources = NULL;
- bc_slist_t *listing_entries = NULL;
- bc_slist_t *listing_entries_source = NULL;
- bc_trie_t *config = bc_trie_new(free);
- bc_trie_insert(config, "BLOGC_VERSION", bc_strdup(PACKAGE_VERSION));
-
- for (size_t i = 1; i < argc; i++) {
- tmp = NULL;
- if (argv[i][0] == '-') {
- switch (argv[i][1]) {
- case 'h':
- blogc_print_help();
- goto cleanup;
- case 'v':
- printf("%s\n", PACKAGE_STRING);
- goto cleanup;
- case 'd':
- debug = true;
- break;
- case 'i':
- input_stdin = true;
- break;
- case 'l':
- listing = true;
- break;
- case 'e':
- if (argv[i][2] != '\0')
- listing_entries = bc_slist_append(listing_entries, bc_strdup(argv[i] + 2));
- else if (i + 1 < argc)
- listing_entries = bc_slist_append(listing_entries, bc_strdup(argv[++i]));
- break;
- case 't':
- if (argv[i][2] != '\0')
- template = bc_strdup(argv[i] + 2);
- else if (i + 1 < argc)
- template = bc_strdup(argv[++i]);
- break;
- case 'o':
- if (argv[i][2] != '\0')
- output = bc_strdup(argv[i] + 2);
- else if (i + 1 < argc)
- output = bc_strdup(argv[++i]);
- break;
- case 'p':
- if (argv[i][2] != '\0')
- print = bc_strdup(argv[i] + 2);
- else if (i + 1 < argc)
- print = bc_strdup(argv[++i]);
- break;
- case 'D':
- if (argv[i][2] != '\0')
- tmp = argv[i] + 2;
- else if (i + 1 < argc)
- tmp = argv[++i];
- if (tmp != NULL) {
- if (!bc_utf8_validate((uint8_t*) tmp, strlen(tmp))) {
- fprintf(stderr, "blogc: error: invalid value for "
- "-D (must be valid UTF-8 string): %s\n", tmp);
- goto cleanup;
- }
- pieces = bc_str_split(tmp, '=', 2);
- if (bc_strv_length(pieces) != 2) {
- fprintf(stderr, "blogc: error: invalid value for "
- "-D (must have an '='): %s\n", tmp);
- bc_strv_free(pieces);
- rv = 1;
- goto cleanup;
- }
- for (size_t j = 0; pieces[0][j] != '\0'; j++) {
- char c = pieces[0][j];
- if (j == 0) {
- if (!(c >= 'A' && c <= 'Z')) {
- fprintf(stderr, "blogc: error: invalid value "
- "for -D (first character in configuration "
- "key must be uppercase): %s\n", pieces[0]);
- bc_strv_free(pieces);
- rv = 1;
- goto cleanup;
- }
- continue;
- }
- if (!((c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_')) {
- fprintf(stderr, "blogc: error: invalid value "
- "for -D (configuration key must be uppercase "
- "with '_' and digits after first character): %s\n",
- pieces[0]);
- bc_strv_free(pieces);
- rv = 1;
- goto cleanup;
- }
- }
- bc_trie_insert(config, pieces[0], bc_strdup(pieces[1]));
- bc_strv_free(pieces);
- pieces = NULL;
- }
- break;
-#ifdef MAKE_EMBEDDED
- case 'm':
- embedded = true;
- break;
-#endif
- default:
- blogc_print_usage();
- fprintf(stderr, "blogc: error: invalid argument: -%c\n",
- argv[i][1]);
- rv = 1;
- goto cleanup;
- }
- }
- else {
- sources = bc_slist_append(sources, bc_strdup(argv[i]));
- }
-
-#ifdef MAKE_EMBEDDED
- if (embedded) {
- rv = bm_main(argc, argv);
- goto cleanup;
- }
-#endif
-
- }
-
- if (input_stdin) {
- size_t input_len;
- char *input = bc_stdin_read(&input_len);
- bc_slist_t *input_list = blogc_filelist_parse(input, input_len);
- free(input);
- sources = bc_slist_append_list(sources, input_list);
- }
-
- if (!listing && bc_slist_length(sources) == 0) {
- blogc_print_usage();
- fprintf(stderr, "blogc: error: one source file is required\n");
- rv = 1;
- goto cleanup;
- }
-
- if (!listing && bc_slist_length(sources) > 1) {
- blogc_print_usage();
- fprintf(stderr, "blogc: error: only one source file should be provided, "
- "if running without '-l'\n");
- rv = 1;
- goto cleanup;
- }
-
- bc_error_t *err = NULL;
-
- bc_slist_t *s = blogc_source_parse_from_files(config, sources, &err);
- if (err != NULL) {
- bc_error_print(err, "blogc");
- rv = 1;
- goto cleanup2;
- }
-
- if (listing) {
- for (bc_slist_t *tmp = listing_entries; tmp != NULL; tmp = tmp->next) {
- if (0 == strlen(tmp->data)) {
- listing_entries_source = bc_slist_append(listing_entries_source, NULL);
- continue;
- }
- bc_trie_t *e = blogc_source_parse_from_file(config, tmp->data, &err);
- if (err != NULL) {
- bc_error_print(err, "blogc");
- rv = 1;
- goto cleanup2;
- }
- listing_entries_source = bc_slist_append(listing_entries_source, e);
- }
- }
-
- if (print != NULL) {
- bc_trie_t *local = NULL;
- if (!listing && s != NULL) {
- local = s->data;
- }
- char *val = blogc_format_variable(print, config, local, NULL, NULL);
- if (val == NULL) {
- fprintf(stderr, "blogc: error: variable not found: %s\n",
- print);
- rv = EX_CONFIG;
- }
- else {
- printf("%s\n", val);
- }
- free(val);
- goto cleanup2;
- }
-
- if (template == NULL) {
- blogc_print_usage();
- fprintf(stderr, "blogc: error: argument -t is required when rendering content\n");
- rv = 1;
- goto cleanup2;
- }
-
- bc_slist_t* l = blogc_template_parse_from_file(template, &err);
- if (err != NULL) {
- bc_error_print(err, "blogc");
- rv = 1;
- goto cleanup3;
- }
-
- if (debug)
- blogc_debug_template(l);
-
- char *out = blogc_render(l, s, listing_entries_source, config, listing);
-
- bool write_to_stdout = (output == NULL || (0 == strcmp(output, "-")));
-
- FILE *fp = stdout;
- if (!write_to_stdout) {
- blogc_mkdir_recursive(output);
- fp = fopen(output, "w");
- if (fp == NULL) {
- fprintf(stderr, "blogc: error: failed to open output file (%s): %s\n",
- output, strerror(errno));
- rv = 1;
- goto cleanup4;
- }
- }
-
- if (out != NULL)
- fprintf(fp, "%s", out);
-
- if (!write_to_stdout)
- fclose(fp);
-
-cleanup4:
- free(out);
-cleanup3:
- blogc_template_free_ast(l);
-cleanup2:
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- bc_error_free(err);
-cleanup:
- bc_trie_free(config);
- free(template);
- free(output);
- free(print);
- bc_slist_free_full(listing_entries, free);
- bc_slist_free_full(listing_entries_source, (bc_free_func_t) bc_trie_free);
- bc_slist_free_full(sources, free);
- return rv;
-}
diff --git a/src/blogc/renderer.h b/src/blogc/renderer.h
deleted file mode 100644
index 77c660a..0000000
--- a/src/blogc/renderer.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _RENDERER_H
-#define _RENDERER_H
-
-#include <stdbool.h>
-#include "../common/utils.h"
-
-const char* blogc_get_variable(const char *name, bc_trie_t *global, bc_trie_t *local);
-char* blogc_format_date(const char *date, bc_trie_t *global, bc_trie_t *local);
-char* blogc_format_variable(const char *name, bc_trie_t *global, bc_trie_t *local,
- const char *foreach_name, bc_slist_t *foreach_var);
-bc_slist_t* blogc_split_list_variable(const char *name, bc_trie_t *global,
- bc_trie_t *local);
-char* blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_slist_t *listing_entries,
- bc_trie_t *config, bool listing);
-
-#endif /* _RENDERER_H */
diff --git a/src/blogc/rusage.c b/src/blogc/rusage.c
deleted file mode 100644
index a38848d..0000000
--- a/src/blogc/rusage.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif /* HAVE_CONFIG_H */
-
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif /* HAVE_SYS_TIME_H */
-
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
-#endif /* HAVE_SYS_RESOURCE_H */
-
-#include <stdlib.h>
-#include "../common/utils.h"
-#include "rusage.h"
-
-
-blogc_rusage_t*
-blogc_rusage_get(void)
-{
-#ifndef HAVE_RUSAGE
- return NULL;
-#else
- struct rusage usage;
- if (0 != getrusage(RUSAGE_SELF, &usage))
- return NULL;
-
- blogc_rusage_t *rv = bc_malloc(sizeof(blogc_rusage_t));
- rv->cpu_time = (
- (usage.ru_utime.tv_sec * 1000000) + usage.ru_utime.tv_usec +
- (usage.ru_stime.tv_sec * 1000000) + usage.ru_stime.tv_usec);
- rv->memory = usage.ru_maxrss;
-
- return rv;
-#endif
-}
-
-
-char*
-blogc_rusage_format_cpu_time(long long time)
-{
- if (time >= 1000000)
- return bc_strdup_printf("%.3fs", ((float) time) / 1000000.0);
-
- // this is a special case: some systems may report the cpu time rounded up to the
- // milisecond. it is useless to show ".000" in this case.
- if (time >= 1000)
- return bc_strdup_printf("%.*fms", time % 1000 ? 3 : 0, ((float) time) / 1000.0);
-
- return bc_strdup_printf("%dus", time);
-}
-
-
-char*
-blogc_rusage_format_memory(long mem)
-{
- if (mem >= 1048576)
- return bc_strdup_printf("%.3fGB", ((float) mem) / 1048576.0);
- if (mem >= 1024)
- return bc_strdup_printf("%.3fMB", ((float) mem) / 1024.0);
- return bc_strdup_printf("%dKB", mem);
-}
-
-
-void
-blogc_rusage_inject(bc_trie_t *global)
-{
- blogc_rusage_t *usage = blogc_rusage_get();
- if (usage == NULL)
- return;
-
- bc_trie_insert(global, "BLOGC_RUSAGE_CPU_TIME",
- blogc_rusage_format_cpu_time(usage->cpu_time));
- bc_trie_insert(global, "BLOGC_RUSAGE_MEMORY",
- blogc_rusage_format_memory(usage->memory));
-
- free(usage);
-}
diff --git a/src/blogc/rusage.h b/src/blogc/rusage.h
deleted file mode 100644
index 6344066..0000000
--- a/src/blogc/rusage.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef ___RUSAGE_H
-#define ___RUSAGE_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif /* HAVE_CONFIG_H */
-
-#ifdef HAVE_SYS_TIME_H
-#ifdef HAVE_SYS_RESOURCE_H
-#define HAVE_RUSAGE 1
-#endif
-#endif
-
-#include "../common/utils.h"
-
-typedef struct {
- long long cpu_time; // in microseconds
- long memory; // in kilobytes
-} blogc_rusage_t;
-
-blogc_rusage_t* blogc_rusage_get(void);
-
-char* blogc_rusage_format_cpu_time(long long time);
-char* blogc_rusage_format_memory(long mem);
-
-void blogc_rusage_inject(bc_trie_t *global);
-
-#endif /* ___RUSAGE_H */
diff --git a/src/blogc/sysinfo.c b/src/blogc/sysinfo.c
deleted file mode 100644
index 3c30996..0000000
--- a/src/blogc/sysinfo.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif /* HAVE_CONFIG_H */
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif /* HAVE_TIME_H */
-
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include "../common/error.h"
-#include "../common/file.h"
-#include "../common/utils.h"
-#include "sysinfo.h"
-
-
-char*
-blogc_sysinfo_get_hostname(void)
-{
-#ifndef HAVE_SYSINFO_HOSTNAME
- return NULL;
-#else
- char buf[1024]; // could be 256 according to gethostname(2), but *shrug*.
- buf[1023] = '\0';
- if (-1 == gethostname(buf, 1024))
- return NULL;
-
-#ifdef HAVE_NETDB_H
- struct hostent *h = gethostbyname(buf);
- if (h != NULL && h->h_name != NULL)
- return bc_strdup(h->h_name);
-#endif
-
- // FIXME: return FQDN instead of local host name
- return bc_strdup(buf);
-#endif
-}
-
-
-void
-blogc_sysinfo_inject_hostname(bc_trie_t *global)
-{
- char *hostname = blogc_sysinfo_get_hostname();
- if (hostname == NULL)
- return;
-
- bc_trie_insert(global, "BLOGC_SYSINFO_HOSTNAME", hostname);
-}
-
-
-char*
-blogc_sysinfo_get_username(void)
-{
- return bc_strdup(getenv("LOGNAME"));
-}
-
-
-void
-blogc_sysinfo_inject_username(bc_trie_t *global)
-{
- char *username = blogc_sysinfo_get_username();
- if (username == NULL)
- return;
-
- bc_trie_insert(global, "BLOGC_SYSINFO_USERNAME", username);
-}
-
-
-char*
-blogc_sysinfo_get_datetime(void)
-{
-#ifndef HAVE_SYSINFO_DATETIME
- return NULL;
-#else
- time_t tmp;
- if (-1 == time(&tmp))
- return NULL;
-
- struct tm *t = gmtime(&tmp);
- if (t == NULL)
- return NULL;
-
- char buf[1024];
- if (0 == strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", t))
- return NULL;
-
- return bc_strdup(buf);
-#endif
-}
-
-
-void
-blogc_sysinfo_inject_datetime(bc_trie_t *global)
-{
- char *t = blogc_sysinfo_get_datetime();
- if (t == NULL)
- return;
-
- bc_trie_insert(global, "BLOGC_SYSINFO_DATETIME", t);
-}
-
-
-// it is obviously impossible that the same process runs inside and outside
-// docker at the same time, then an unprotected global variable should be fine
-// here
-static bool inside_docker_evaluated = false;
-static bool inside_docker = false;
-
-bool
-blogc_sysinfo_get_inside_docker(void)
-{
- if (inside_docker_evaluated)
- return inside_docker;
- inside_docker_evaluated = true;
-
- size_t len;
- bc_error_t *err = NULL;
- char *contents = bc_file_get_contents("/proc/1/cgroup", false, &len, &err);
- if (err != NULL) {
- bc_error_free(err);
- inside_docker = false;
- return inside_docker;
- }
-
- bool inside_docker = NULL != strstr(contents, "/docker/");
- free(contents);
- return inside_docker;
-}
-
-
-void
-blogc_sysinfo_inject_inside_docker(bc_trie_t *global)
-{
- if (blogc_sysinfo_get_inside_docker())
- bc_trie_insert(global, "BLOGC_SYSINFO_INSIDE_DOCKER", bc_strdup("1"));
-}
diff --git a/src/blogc/sysinfo.h b/src/blogc/sysinfo.h
deleted file mode 100644
index b249661..0000000
--- a/src/blogc/sysinfo.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef ___SYSINFO_H
-#define ___SYSINFO_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif /* HAVE_CONFIG_H */
-
-#ifdef HAVE_UNISTD_H
-#ifdef HAVE_GETHOSTNAME
-#define HAVE_SYSINFO_HOSTNAME 1
-#endif /* HAVE_GETHOSTNAME */
-#endif /* HAVE_UNISTD_H */
-
-#ifdef HAVE_TIME_H
-#define HAVE_SYSINFO_DATETIME 1
-#endif /* HAVE_TIME_H */
-
-#include <stdbool.h>
-#include "../common/utils.h"
-
-char* blogc_sysinfo_get_hostname(void);
-void blogc_sysinfo_inject_hostname(bc_trie_t *global);
-char* blogc_sysinfo_get_username(void);
-void blogc_sysinfo_inject_username(bc_trie_t *global);
-char* blogc_sysinfo_get_datetime(void);
-void blogc_sysinfo_inject_datetime(bc_trie_t *global);
-bool blogc_sysinfo_get_inside_docker(void);
-void blogc_sysinfo_inject_inside_docker(bc_trie_t *global);
-
-#endif /* ___SYSINFO_H */
diff --git a/src/blogc/template-parser.h b/src/blogc/template-parser.h
deleted file mode 100644
index 6183016..0000000
--- a/src/blogc/template-parser.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _TEMPLATE_PARSER_H
-#define _TEMPLATE_PARSER_H
-
-#include <stddef.h>
-#include "../common/error.h"
-#include "../common/utils.h"
-
-/*
- * note: whitespace cleaners are NOT added to AST. we fix strings right during
- * template parsing. renderer does not need to care about it, for the sake of
- * simplicity.
- *
- * another note: technically this is not an AST, because it is not a tree. duh!
- */
-typedef enum {
- BLOGC_TEMPLATE_NODE_IFDEF = 1,
- BLOGC_TEMPLATE_NODE_IFNDEF,
- BLOGC_TEMPLATE_NODE_IF,
- BLOGC_TEMPLATE_NODE_ELSE,
- BLOGC_TEMPLATE_NODE_ENDIF,
- BLOGC_TEMPLATE_NODE_FOREACH,
- BLOGC_TEMPLATE_NODE_ENDFOREACH,
- BLOGC_TEMPLATE_NODE_BLOCK,
- BLOGC_TEMPLATE_NODE_ENDBLOCK,
- BLOGC_TEMPLATE_NODE_VARIABLE,
- BLOGC_TEMPLATE_NODE_CONTENT,
-} blogc_template_node_type_t;
-
-typedef enum {
- BLOGC_TEMPLATE_OP_NEQ = 1 << 0,
- BLOGC_TEMPLATE_OP_EQ = 1 << 1,
- BLOGC_TEMPLATE_OP_LT = 1 << 2,
- BLOGC_TEMPLATE_OP_GT = 1 << 3,
-} blogc_template_operator_t;
-
-typedef struct {
- blogc_template_node_type_t type;
- blogc_template_operator_t op;
-
- // 2 slots to store node data.
- char *data[2];
-
- bc_slist_t *childs;
-} blogc_template_node_t;
-
-bc_slist_t* blogc_template_parse(const char *src, size_t src_len,
- bc_error_t **err);
-void blogc_template_free_ast(bc_slist_t *ast);
-
-#endif /* _TEMPLATE_PARSER_H */
diff --git a/src/blogc/toctree.c b/src/blogc/toctree.c
deleted file mode 100644
index 307c62c..0000000
--- a/src/blogc/toctree.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdlib.h>
-#include "../common/utils.h"
-#include "toctree.h"
-
-bc_slist_t*
-blogc_toctree_append(bc_slist_t *headers, size_t level, const char *slug, const char *text)
-{
- if (level == 0)
- return headers;
-
- blogc_toctree_header_t *t = bc_malloc(sizeof(blogc_toctree_header_t));
- t->level = level;
- t->slug = bc_strdup(slug);
- t->text = bc_strdup(text);
- return bc_slist_append(headers, t);
-}
-
-
-char*
-blogc_toctree_render(bc_slist_t *headers, int maxdepth, const char *endl)
-{
- if (headers == NULL || maxdepth == 0)
- return NULL;
-
- // find lower level
- size_t lower_level = 0;
- for (bc_slist_t *l = headers; l != NULL; l = l->next) {
- size_t lv = ((blogc_toctree_header_t*) l->data)->level;
- if (lower_level == 0 || lower_level > lv) {
- lower_level = lv;
- }
- }
-
- if (lower_level == 0)
- return NULL;
-
- // render
- bc_string_t *rv = bc_string_new();
- bc_string_append_printf(rv, "<ul>%s", endl == NULL ? "\n" : endl);
- size_t spacing = 4;
- size_t current_level = lower_level;
- for (bc_slist_t *l = headers; l != NULL; l = l->next) {
- blogc_toctree_header_t *t = l->data;
- if (t->level - lower_level >= maxdepth) {
- continue;
- }
- while (current_level > t->level) {
- spacing -= 4;
- bc_string_append_printf(rv, "%*s</ul>%s", spacing, "",
- endl == NULL ? "\n" : endl);
- current_level--;
- }
- while (current_level < t->level) {
- bc_string_append_printf(rv, "%*s<ul>%s", spacing, "",
- endl == NULL ? "\n" : endl);
- current_level++;
- spacing += 4;
- }
- bc_string_append_printf(rv, "%*s<li>", spacing, "");
- if (t->slug != NULL) {
- bc_string_append_printf(rv, "<a href=\"#%s\">%s</a>", t->slug,
- t->text != NULL ? t->text : "");
- }
- else {
- bc_string_append(rv, t->text);
- }
- bc_string_append_printf(rv, "</li>%s", endl == NULL ? "\n" : endl);
- }
-
- // close leftovers
- while (current_level >= lower_level) {
- spacing -= 4;
- bc_string_append_printf(rv, "%*s</ul>%s", spacing, "",
- endl == NULL ? "\n" : endl);
- current_level--;
- }
-
- return bc_string_free(rv, false);
-}
-
-
-static void
-free_header(blogc_toctree_header_t *h)
-{
- free(h->slug);
- free(h->text);
- free(h);
-}
-
-
-void
-blogc_toctree_free(bc_slist_t *l)
-{
- bc_slist_free_full(l, (bc_free_func_t) free_header);
-}
diff --git a/src/blogc/toctree.h b/src/blogc/toctree.h
deleted file mode 100644
index 460119b..0000000
--- a/src/blogc/toctree.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef ___TOCTREE_H
-#define ___TOCTREE_H
-
-#include "../common/utils.h"
-
-typedef struct {
- size_t level;
- char *slug;
- char *text;
-} blogc_toctree_header_t;
-
-bc_slist_t* blogc_toctree_append(bc_slist_t *headers, size_t level,
- const char *slug, const char *text);
-char* blogc_toctree_render(bc_slist_t *headers, int maxdepth,
- const char *endl);
-void blogc_toctree_free(bc_slist_t *l);
-
-#endif /* ___TOCTREE_H */
diff --git a/src/common/compat.c b/src/common/compat.c
deleted file mode 100644
index f7394c8..0000000
--- a/src/common/compat.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif /* HAVE_CONFIG_H */
-
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif /* HAVE_SYS_WAIT_H */
-
-#include <signal.h>
-#include "compat.h"
-
-
-int
-bc_compat_status_code(int waitstatus)
-{
- int rv = waitstatus;
-#if defined(WIFEXITED) && defined(WEXITSTATUS) && defined(WIFSIGNALED) && defined(WTERMSIG)
- if (WIFEXITED(waitstatus)) {
- rv = WEXITSTATUS(waitstatus);
- }
- else if (WIFSIGNALED(waitstatus)) {
- rv = WTERMSIG(waitstatus);
- rv += 128;
- }
-#elif defined(WIN32) || defined(_WIN32)
- if (waitstatus == 3) {
- rv = SIGTERM + 128; // can't get signal on windows.
- }
-#endif
- return rv;
-}
diff --git a/src/common/compat.h b/src/common/compat.h
deleted file mode 100644
index 1e743db..0000000
--- a/src/common/compat.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _COMPAT_H
-#define _COMPAT_H
-
-int bc_compat_status_code(int waitstatus);
-
-#endif /* _COMPAT_H */
diff --git a/src/common/config-parser.c b/src/common/config-parser.c
deleted file mode 100644
index fbb79af..0000000
--- a/src/common/config-parser.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include "error.h"
-#include "utils.h"
-#include "config-parser.h"
-
-
-typedef enum {
- CONFIG_START = 1,
- CONFIG_SECTION_START,
- CONFIG_SECTION,
- CONFIG_SECTION_KEY,
- CONFIG_SECTION_VALUE_START,
- CONFIG_SECTION_VALUE_QUOTE,
- CONFIG_SECTION_VALUE_POST_QUOTED,
- CONFIG_SECTION_VALUE,
- CONFIG_SECTION_LIST_START,
- CONFIG_SECTION_LIST_QUOTE,
- CONFIG_SECTION_LIST_POST_QUOTED,
- CONFIG_SECTION_LIST,
-} bc_configparser_state_t;
-
-typedef enum {
- CONFIG_SECTION_TYPE_MAP = 1,
- CONFIG_SECTION_TYPE_LIST,
-} bc_configparser_section_type_t;
-
-typedef struct {
- bc_configparser_section_type_t type;
- void *data;
-} bc_configparser_section_t;
-
-
-static void
-free_section(bc_configparser_section_t *section)
-{
- if (section == NULL)
- return;
-
- switch (section->type) {
- case CONFIG_SECTION_TYPE_MAP:
- bc_trie_free(section->data);
- break;
- case CONFIG_SECTION_TYPE_LIST:
- bc_slist_free_full(section->data, free);
- break;
- }
- free(section);
-}
-
-
-bc_config_t*
-bc_config_parse(const char *src, size_t src_len, const char *list_sections[],
- bc_error_t **err)
-{
- if (err == NULL || *err != NULL)
- return NULL;
-
- size_t current = 0;
- size_t start = 0;
-
- bc_configparser_section_t *section = NULL;
-
- char *section_name = NULL;
- char *key = NULL;
- bc_string_t *value = NULL;
- bool escaped = false;
-
- bc_config_t *rv = bc_malloc(sizeof(bc_config_t));
- rv->root = bc_trie_new((bc_free_func_t) free_section);
-
- bc_configparser_state_t state = CONFIG_START;
-
- while (current < src_len) {
- char c = src[current];
- bool is_last = current == src_len - 1;
-
- if (escaped) {
- bc_string_append_c(value, c);
- escaped = false;
- current++;
- continue;
- }
-
- if (value != NULL && c == '\\') {
- escaped = true;
- current++;
- continue;
- }
-
- switch (state) {
-
- case CONFIG_START:
- if (c == '#' || c == ';') {
- while (current < src_len) {
- if (src[current] == '\r' || src[current] == '\n')
- break;
- current++;
- }
- break;
- }
- if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
- break;
- if (c == '[') {
- state = CONFIG_SECTION_START;
- break;
- }
- if (section != NULL) {
- start = current;
- switch (section->type) {
- case CONFIG_SECTION_TYPE_MAP:
- state = CONFIG_SECTION_KEY;
- break;
- case CONFIG_SECTION_TYPE_LIST:
- state = CONFIG_SECTION_LIST_START;
- if (value == NULL)
- value = bc_string_new();
- break;
- }
- continue;
- }
- *err = bc_error_parser(BC_ERROR_CONFIG_PARSER, src, src_len,
- current, "File must start with section.");
- break;
-
- case CONFIG_SECTION_START:
- start = current;
- state = CONFIG_SECTION;
- break;
-
- case CONFIG_SECTION:
- if (c == ']') {
- section_name = bc_strndup(src + start, current - start);
- section = bc_malloc(sizeof(bc_configparser_section_t));
- section->type = CONFIG_SECTION_TYPE_MAP;
- if (list_sections != NULL) {
- for (size_t i = 0; list_sections[i] != NULL; i++) {
- if (0 == strcmp(section_name, list_sections[i])) {
- section->type = CONFIG_SECTION_TYPE_LIST;
- break;
- }
- }
- }
- switch (section->type) {
- case CONFIG_SECTION_TYPE_MAP:
- section->data = bc_trie_new(free);
- break;
- case CONFIG_SECTION_TYPE_LIST:
- section->data = NULL;
- break;
- }
- bc_trie_insert(rv->root, section_name, section);
- free(section_name);
- section_name = NULL;
- state = CONFIG_START;
- break;
- }
- if (c != '\r' && c != '\n')
- break;
- *err = bc_error_parser(BC_ERROR_CONFIG_PARSER, src, src_len,
- current, "Section names can't have new lines.");
- break;
-
- case CONFIG_SECTION_KEY:
- if (c == '=') {
- key = bc_strndup(src + start, current - start);
- state = CONFIG_SECTION_VALUE_START;
- if (is_last) {
- bc_trie_insert(section->data, bc_str_strip(key),
- bc_strdup(""));
- free(key);
- key = NULL;
- break;
- }
- if (value == NULL)
- value = bc_string_new();
- break;
- }
- if (c != '\r' && c != '\n' && !is_last)
- break;
- // key without value, should we support it?
- size_t end = is_last && c != '\n' && c != '\r' ? src_len :
- current;
- key = bc_strndup(src + start, end - start);
- *err = bc_error_parser(BC_ERROR_CONFIG_PARSER, src, src_len,
- current, "Key without value: %s.", key);
- free(key);
- key = NULL;
- break;
-
- case CONFIG_SECTION_VALUE_START:
- if (c == ' ' || c == '\t' || c == '\f' || c == '\v')
- break;
- if (c == '"') {
- state = CONFIG_SECTION_VALUE_QUOTE;
- break;
- }
- if (c == '\r' || c == '\n' || is_last) {
- state = CONFIG_SECTION_VALUE;
- continue;
- }
- bc_string_append_c(value, c);
- state = CONFIG_SECTION_VALUE;
- break;
-
- case CONFIG_SECTION_VALUE_QUOTE:
- if (c == '"') {
- bc_trie_insert(section->data, bc_str_strip(key),
- bc_string_free(value, false));
- free(key);
- key = NULL;
- value = NULL;
- state = CONFIG_SECTION_VALUE_POST_QUOTED;
- break;
- }
- bc_string_append_c(value, c);
- break;
-
- case CONFIG_SECTION_VALUE_POST_QUOTED:
- if (c == ' ' || c == '\t' || c == '\f' || c == '\v')
- break;
- if (c == '\r' || c == '\n' || is_last) {
- state = CONFIG_START;
- break;
- }
- *err = bc_error_parser(BC_ERROR_CONFIG_PARSER, src, src_len,
- current, "Invalid value for key, should not have anything "
- "after quotes.");
- break;
-
- case CONFIG_SECTION_VALUE:
- if (c == '\r' || c == '\n' || is_last) {
- if (is_last && c != '\r' && c != '\n')
- bc_string_append_c(value, c);
- bc_trie_insert(section->data, bc_str_strip(key),
- bc_strdup(bc_str_rstrip(value->str)));
- free(key);
- key = NULL;
- bc_string_free(value, true);
- value = NULL;
- state = CONFIG_START;
- break;
- }
- bc_string_append_c(value, c);
- break;
-
- case CONFIG_SECTION_LIST_START:
- if (c == ' ' || c == '\t' || c == '\f' || c == '\v')
- break;
- if (c == '"') {
- state = CONFIG_SECTION_LIST_QUOTE;
- break;
- }
- bc_string_append_c(value, c);
- state = CONFIG_SECTION_LIST;
- break;
-
- case CONFIG_SECTION_LIST_QUOTE:
- if (c == '"') {
- section->data = bc_slist_append(section->data,
- bc_string_free(value, false));
- value = NULL;
- state = CONFIG_SECTION_LIST_POST_QUOTED;
- break;
-
- }
- bc_string_append_c(value, c);
- break;
-
- case CONFIG_SECTION_LIST_POST_QUOTED:
- if (c == ' ' || c == '\t' || c == '\f' || c == '\v')
- break;
- if (c == '\r' || c == '\n' || is_last) {
- state = CONFIG_START;
- break;
- }
- *err = bc_error_parser(BC_ERROR_CONFIG_PARSER, src, src_len,
- current, "Invalid value for list item, should not have "
- "anything after quotes.");
- break;
-
- case CONFIG_SECTION_LIST:
- if (c == '\r' || c == '\n' || is_last) {
- if (is_last && c != '\r' && c != '\n')
- bc_string_append_c(value, c);
- section->data = bc_slist_append(section->data,
- bc_strdup(bc_str_strip(value->str)));
- bc_string_free(value, true);
- value = NULL;
- state = CONFIG_START;
- break;
-
- }
- bc_string_append_c(value, c);
- break;
-
- }
-
- if (*err != NULL) {
- bc_config_free(rv);
- rv = NULL;
- break;
- }
-
- current++;
- }
-
- free(section_name);
- free(key);
- bc_string_free(value, true);
-
- return rv;
-}
-
-
-static void
-list_keys(const char *key, const char *value, bc_slist_t **l)
-{
- *l = bc_slist_append(*l, bc_strdup(key));
-}
-
-
-char**
-bc_config_list_sections(bc_config_t *config)
-{
- if (config == NULL)
- return NULL;
-
- bc_slist_t *l = NULL;
- bc_trie_foreach(config->root, (bc_trie_foreach_func_t) list_keys, &l);
-
- char **rv = bc_malloc(sizeof(char*) * (bc_slist_length(l) + 1));
-
- size_t i = 0;
- for (bc_slist_t *tmp = l; tmp != NULL; tmp = tmp->next, i++)
- rv[i] = tmp->data;
- rv[i] = NULL;
-
- bc_slist_free(l);
-
- return rv;
-}
-
-
-char**
-bc_config_list_keys(bc_config_t *config, const char *section)
-{
- if (config == NULL)
- return NULL;
-
- const bc_configparser_section_t *s = bc_trie_lookup(config->root, section);
- if (s == NULL)
- return NULL;
-
- if (s->type != CONFIG_SECTION_TYPE_MAP)
- return NULL;
-
- bc_slist_t *l = NULL;
- bc_trie_foreach(s->data, (bc_trie_foreach_func_t) list_keys, &l);
-
- char **rv = bc_malloc(sizeof(char*) * (bc_slist_length(l) + 1));
-
- size_t i = 0;
- for (bc_slist_t *tmp = l; tmp != NULL; tmp = tmp->next, i++)
- rv[i] = tmp->data;
- rv[i] = NULL;
-
- bc_slist_free(l);
-
- return rv;
-}
-
-
-const char*
-bc_config_get(bc_config_t *config, const char *section, const char *key)
-{
- if (config == NULL)
- return NULL;
-
- const bc_configparser_section_t *s = bc_trie_lookup(config->root, section);
- if (s == NULL)
- return NULL;
-
- if (s->type != CONFIG_SECTION_TYPE_MAP)
- return NULL;
-
- return bc_trie_lookup(s->data, key);
-}
-
-
-const char*
-bc_config_get_with_default(bc_config_t *config, const char *section, const char *key,
- const char *default_)
-{
- const char *rv = bc_config_get(config, section, key);
- if (rv == NULL)
- return default_;
- return rv;
-}
-
-
-char**
-bc_config_get_list(bc_config_t *config, const char *section)
-{
- if (config == NULL)
- return NULL;
-
- const bc_configparser_section_t *s = bc_trie_lookup(config->root, section);
- if (s == NULL)
- return NULL;
-
- if (s->type != CONFIG_SECTION_TYPE_LIST)
- return NULL;
-
- char **rv = bc_malloc(sizeof(char*) * (bc_slist_length(s->data) + 1));
-
- size_t i = 0;
- for (bc_slist_t *tmp = s->data; tmp != NULL; tmp = tmp->next, i++)
- rv[i] = bc_strdup(tmp->data);
- rv[i] = NULL;
-
- return rv;
-}
-
-
-void
-bc_config_free(bc_config_t *config)
-{
- if (config == NULL)
- return;
- bc_trie_free(config->root);
- free(config);
-}
diff --git a/src/common/config-parser.h b/src/common/config-parser.h
deleted file mode 100644
index 0b75ff8..0000000
--- a/src/common/config-parser.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _CONFIG_PARSER_H
-#define _CONFIG_PARSER_H
-
-#include <stddef.h>
-#include "utils.h"
-#include "error.h"
-
-typedef struct {
- bc_trie_t *root;
-} bc_config_t;
-
-bc_config_t* bc_config_parse(const char *src, size_t src_len,
- const char *list_sections[], bc_error_t **err);
-char** bc_config_list_sections(bc_config_t *config);
-char** bc_config_list_keys(bc_config_t *config, const char *section);
-const char* bc_config_get(bc_config_t *config, const char *section,
- const char *key);
-const char* bc_config_get_with_default(bc_config_t *config, const char *section,
- const char *key, const char *default_);
-char** bc_config_get_list(bc_config_t *config, const char *section);
-void bc_config_free(bc_config_t *config);
-
-#endif /* _CONFIG_PARSER_H */
diff --git a/src/common/error.h b/src/common/error.h
deleted file mode 100644
index b85f006..0000000
--- a/src/common/error.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _ERROR_H
-#define _ERROR_H
-
-#include <stddef.h>
-
-// error handling is centralized here for the sake of simplicity :/
-typedef enum {
-
- // errors for src/common
- BC_ERROR_CONFIG_PARSER = 1,
- BC_ERROR_FILE,
-
- // errors for src/blogc
- BLOGC_ERROR_SOURCE_PARSER = 100,
- BLOGC_ERROR_TEMPLATE_PARSER,
- BLOGC_ERROR_LOADER,
- BLOGC_WARNING_DATETIME_PARSER,
-
- // errors for src/blogc-make
- BLOGC_MAKE_ERROR_SETTINGS = 300,
- BLOGC_MAKE_ERROR_EXEC,
- BLOGC_MAKE_ERROR_ATOM,
- BLOGC_MAKE_ERROR_UTILS,
-
-} bc_error_type_t;
-
-typedef struct {
- char *msg;
- bc_error_type_t type;
-} bc_error_t;
-
-bc_error_t* bc_error_new(bc_error_type_t type, const char *msg);
-bc_error_t* bc_error_new_printf(bc_error_type_t type, const char *format, ...);
-bc_error_t* bc_error_parser(bc_error_type_t type, const char *src,
- size_t src_len, size_t current, const char *format, ...);
-void bc_error_print(bc_error_t *err, const char *prefix);
-void bc_error_free(bc_error_t *err);
-
-#endif /* _ERROR_H */
diff --git a/src/common/file.c b/src/common/file.c
deleted file mode 100644
index 1e55f64..0000000
--- a/src/common/file.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <errno.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include "file.h"
-#include "error.h"
-#include "utf8.h"
-#include "utils.h"
-
-
-char*
-bc_file_get_contents(const char *path, bool utf8, size_t *len, bc_error_t **err)
-{
- if (path == NULL || len == NULL || err == NULL || *err != NULL)
- return NULL;
-
- *len = 0;
- FILE *fp = fopen(path, "r");
-
- if (fp == NULL) {
- int tmp_errno = errno;
- *err = bc_error_new_printf(BC_ERROR_FILE,
- "Failed to open file (%s): %s", path, strerror(tmp_errno));
- return NULL;
- }
-
- bc_string_t *str = bc_string_new();
- char buffer[BC_FILE_CHUNK_SIZE];
- char *tmp;
-
- while (!feof(fp)) {
- size_t read_len = fread(buffer, sizeof(char), BC_FILE_CHUNK_SIZE, fp);
-
- tmp = buffer;
-
- if (utf8 && str->len == 0 && read_len > 0) {
- // skipping BOM before validation, for performance. should be safe
- // enough
- size_t skip = bc_utf8_skip_bom((uint8_t*) buffer, read_len);
- read_len -= skip;
- tmp += skip;
- }
-
- *len += read_len;
- bc_string_append_len(str, tmp, read_len);
- }
- fclose(fp);
-
- if (utf8 && !bc_utf8_validate_str(str)) {
- *err = bc_error_new_printf(BC_ERROR_FILE,
- "File content is not valid UTF-8: %s", path);
- bc_string_free(str, true);
- return NULL;
- }
-
- return bc_string_free(str, false);
-}
diff --git a/src/common/file.h b/src/common/file.h
deleted file mode 100644
index d002bf7..0000000
--- a/src/common/file.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _FILE_H
-#define _FILE_H
-
-#include <stddef.h>
-#include <stdbool.h>
-#include "error.h"
-
-#define BC_FILE_CHUNK_SIZE 1024
-
-char* bc_file_get_contents(const char *path, bool utf8, size_t *len, bc_error_t **err);
-
-#endif /* _FILE_H */
diff --git a/src/common/sort.c b/src/common/sort.c
deleted file mode 100644
index 3e24706..0000000
--- a/src/common/sort.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdbool.h>
-#include "utils.h"
-#include "sort.h"
-
-
-bc_slist_t*
-bc_slist_sort(bc_slist_t *l, bc_sort_func_t cmp)
-{
- if (l == NULL) {
- return NULL;
- }
-
- bool swapped = false;
- bc_slist_t *lptr = NULL;
- bc_slist_t *rptr = NULL;
-
- do {
- swapped = false;
- lptr = l;
-
- while (lptr->next != rptr) {
- if (0 < cmp(lptr->data, lptr->next->data)) {
- void *tmp = lptr->data;
- lptr->data = lptr->next->data;
- lptr->next->data = tmp;
- swapped = true;
- }
-
- lptr = lptr->next;
- }
-
- rptr = lptr;
- } while(swapped);
-
- return l;
-}
diff --git a/src/common/sort.h b/src/common/sort.h
deleted file mode 100644
index 9f4dda2..0000000
--- a/src/common/sort.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _SORT_H
-#define _SORT_H
-
-#include "utils.h"
-
-typedef int (*bc_sort_func_t) (const void *a, const void *b);
-
-bc_slist_t* bc_slist_sort(bc_slist_t *l, bc_sort_func_t cmp);
-
-#endif /* _SORT_H */
diff --git a/src/common/stdin.c b/src/common/stdin.c
deleted file mode 100644
index 556c7cf..0000000
--- a/src/common/stdin.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdbool.h>
-#include <stdio.h>
-#include "utils.h"
-#include "stdin.h"
-
-
-// splitted in single file to make it easier to test
-char*
-bc_stdin_read(size_t *len)
-{
- if (len == NULL)
- return NULL;
-
- int c;
- bc_string_t *rv = bc_string_new();
- while (EOF != (c = fgetc(stdin)))
- bc_string_append_c(rv, c);
- *len = rv->len;
- return bc_string_free(rv, false);
-}
diff --git a/src/common/stdin.h b/src/common/stdin.h
deleted file mode 100644
index b27ecaf..0000000
--- a/src/common/stdin.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _STDIN_H
-#define _STDIN_H
-
-#include <stddef.h>
-
-char* bc_stdin_read(size_t *len);
-
-#endif /* _STDIN_H */
diff --git a/src/common/utils.h b/src/common/utils.h
deleted file mode 100644
index 4bdab8c..0000000
--- a/src/common/utils.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifndef _UTILS_H
-#define _UTILS_H
-
-#include <stddef.h>
-#include <stdarg.h>
-#include <stdbool.h>
-
-
-// memory
-
-typedef void (*bc_free_func_t) (void *ptr);
-
-void* bc_malloc(size_t size);
-void* bc_realloc(void *ptr, size_t size);
-
-
-// slist
-
-typedef struct _bc_slist_t {
- struct _bc_slist_t *next;
- void *data;
-} bc_slist_t;
-
-bc_slist_t* bc_slist_append(bc_slist_t *l, void *data);
-bc_slist_t* bc_slist_prepend(bc_slist_t *l, void *data);
-bc_slist_t* bc_slist_append_list(bc_slist_t *l, bc_slist_t *n);
-void bc_slist_free(bc_slist_t *l);
-void bc_slist_free_full(bc_slist_t *l, bc_free_func_t free_func);
-size_t bc_slist_length(bc_slist_t *l);
-
-
-// strfuncs
-
-char* bc_strdup(const char *s);
-char* bc_strndup(const char *s, size_t n);
-char* bc_strdup_vprintf(const char *format, va_list ap);
-char* bc_strdup_printf(const char *format, ...);
-bool bc_isspace(int c);
-bool bc_str_starts_with(const char *str, const char *prefix);
-bool bc_str_ends_with(const char *str, const char *suffix);
-char* bc_str_lstrip(char *str);
-char* bc_str_rstrip(char *str);
-char* bc_str_strip(char *str);
-char** bc_str_split(const char *str, char c, size_t max_pieces);
-char* bc_str_replace(const char *str, const char search, const char *replace);
-char* bc_str_find(const char *str, char c);
-bool bc_str_to_bool(const char *str);
-void bc_strv_free(char **strv);
-char* bc_strv_join(char **strv, const char *separator);
-size_t bc_strv_length(char **strv);
-
-
-// string
-
-typedef struct {
- char *str;
- size_t len;
- size_t allocated_len;
-} bc_string_t;
-
-bc_string_t* bc_string_new(void);
-char* bc_string_free(bc_string_t *str, bool free_str);
-bc_string_t* bc_string_dup(bc_string_t *str);
-bc_string_t* bc_string_append_len(bc_string_t *str, const char *suffix, size_t len);
-bc_string_t* bc_string_append(bc_string_t *str, const char *suffix);
-bc_string_t* bc_string_append_c(bc_string_t *str, char c);
-bc_string_t* bc_string_append_printf(bc_string_t *str, const char *format, ...);
-bc_string_t* bc_string_append_escaped(bc_string_t *str, const char *suffix);
-
-
-// trie
-
-typedef struct _bc_trie_node_t {
- char key;
- void *data;
- struct _bc_trie_node_t *next, *child;
-} bc_trie_node_t;
-
-struct _bc_trie_t {
- bc_trie_node_t *root;
- bc_free_func_t free_func;
-};
-
-typedef struct _bc_trie_t bc_trie_t;
-
-typedef void (*bc_trie_foreach_func_t)(const char *key, void *data,
- void *user_data);
-
-bc_trie_t* bc_trie_new(bc_free_func_t free_func);
-void bc_trie_free(bc_trie_t *trie);
-void bc_trie_insert(bc_trie_t *trie, const char *key, void *data);
-void* bc_trie_lookup(bc_trie_t *trie, const char *key);
-size_t bc_trie_size(bc_trie_t *trie);
-void bc_trie_foreach(bc_trie_t *trie, bc_trie_foreach_func_t func,
- void *user_data);
-
-
-// shell
-
-char* bc_shell_quote(const char *command);
-
-#endif /* _UTILS_H */
diff --git a/src/blogc/content-parser.c b/src/content-parser.c
index a42f6f6..410fc90 100644
--- a/src/blogc/content-parser.c
+++ b/src/content-parser.c
@@ -1,18 +1,18 @@
/*
* blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
*
* This program can be distributed under the terms of the BSD License.
* See the file LICENSE.
*/
#include <stdbool.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "content-parser.h"
-#include "toctree.h"
-#include "../common/utils.h"
+#include "utils.h"
// this is a half ass implementation of a markdown-like syntax. bugs are
// expected. feel free to improve the parser and add new features.
@@ -23,7 +23,7 @@ blogc_slugify(const char *str)
{
if (str == NULL)
return NULL;
- char *new_str = bc_strdup(str);
+ char *new_str = sb_strdup(str);
int diff = 'a' - 'A'; // just to avoid magic numbers
for (size_t i = 0; new_str[i] != '\0'; i++) {
if (new_str[i] >= 'a' && new_str[i] <= 'z')
@@ -61,13 +61,13 @@ htmlentities(char c)
static void
-htmlentities_append(bc_string_t *str, char c)
+htmlentities_append(sb_string_t *str, char c)
{
const char *e = htmlentities(c);
if (e == NULL)
- bc_string_append_c(str, c);
+ sb_string_append_c(str, c);
else
- bc_string_append(str, e);
+ sb_string_append(str, e);
}
@@ -76,10 +76,10 @@ blogc_htmlentities(const char *str)
{
if (str == NULL)
return NULL;
- bc_string_t *rv = bc_string_new();
+ sb_string_t *rv = sb_string_new();
for (size_t i = 0; str[i] != '\0'; i++)
htmlentities_append(rv, str[i]);
- return bc_string_free(rv, false);
+ return sb_string_free(rv, false);
}
@@ -88,7 +88,7 @@ blogc_fix_description(const char *paragraph)
{
if (paragraph == NULL)
return NULL;
- bc_string_t *rv = bc_string_new();
+ sb_string_t *rv = sb_string_new();
bool last = false;
bool newline = false;
char *tmp = NULL;
@@ -102,12 +102,12 @@ blogc_fix_description(const char *paragraph)
case '\n':
if (newline)
break;
- tmp = bc_strndup(paragraph + start, current - start);
- bc_string_append(rv, bc_str_strip(tmp));
+ tmp = sb_strndup(paragraph + start, current - start);
+ sb_string_append(rv, sb_str_strip(tmp));
free(tmp);
tmp = NULL;
if (!last)
- bc_string_append_c(rv, ' ');
+ sb_string_append_c(rv, ' ');
start = current + 1;
newline = true;
break;
@@ -118,8 +118,8 @@ blogc_fix_description(const char *paragraph)
break;
current++;
}
- tmp = blogc_htmlentities(bc_str_strip(rv->str));
- bc_string_free(rv, true);
+ tmp = blogc_htmlentities(sb_str_strip(rv->str));
+ sb_string_free(rv, true);
return tmp;
}
@@ -139,8 +139,7 @@ typedef enum {
CONTENT_CODE,
CONTENT_CODE_START,
CONTENT_CODE_END,
- CONTENT_UNORDERED_LIST_OR_HORIZONTAL_RULE_OR_EMPHASIS,
- CONTENT_HORIZONTAL_RULE_OR_EMPHASIS,
+ CONTENT_UNORDERED_LIST_OR_HORIZONTAL_RULE,
CONTENT_HORIZONTAL_RULE,
CONTENT_UNORDERED_LIST_START,
CONTENT_UNORDERED_LIST_END,
@@ -191,7 +190,7 @@ blogc_content_parse_inline_internal(const char *src, size_t src_len)
size_t start_link = 0;
char *link1 = NULL;
- bc_string_t *rv = bc_string_new();
+ sb_string_t *rv = sb_string_new();
blogc_content_parser_inline_state_t state = CONTENT_INLINE_START;
@@ -245,15 +244,15 @@ blogc_content_parse_inline_internal(const char *src, size_t src_len)
state = CONTENT_INLINE_ASTERISK_DOUBLE;
break;
}
- tmp = bc_str_find(src + current, '*');
+ tmp = sb_str_find(src + current, '*');
if (tmp == NULL || ((tmp - src) >= src_len)) {
- bc_string_append_c(rv, '*');
+ sb_string_append_c(rv, '*');
state = CONTENT_INLINE_START;
continue;
}
tmp2 = blogc_content_parse_inline_internal(
src + current, (tmp - src) - current);
- bc_string_append_printf(rv, "<em>%s</em>", tmp2);
+ sb_string_append_printf(rv, "<em>%s</em>", tmp2);
current = tmp - src;
tmp = NULL;
free(tmp2);
@@ -264,21 +263,21 @@ blogc_content_parse_inline_internal(const char *src, size_t src_len)
case CONTENT_INLINE_ASTERISK_DOUBLE:
tmp = src + current;
do {
- tmp = bc_str_find(tmp, '*');
+ tmp = sb_str_find(tmp, '*');
if (((tmp - src) < src_len) && *(tmp + 1) == '*') {
break;
}
tmp++;
} while (tmp != NULL && (tmp - src) < src_len);
if (tmp == NULL || ((tmp - src) >= src_len)) {
- bc_string_append_c(rv, '*');
- bc_string_append_c(rv, '*');
+ sb_string_append_c(rv, '*');
+ sb_string_append_c(rv, '*');
state = CONTENT_INLINE_START;
continue;
}
tmp2 = blogc_content_parse_inline_internal(
src + current, (tmp - src) - current);
- bc_string_append_printf(rv, "<strong>%s</strong>", tmp2);
+ sb_string_append_printf(rv, "<strong>%s</strong>", tmp2);
current = tmp - src + 1;
tmp = NULL;
free(tmp2);
@@ -291,15 +290,15 @@ blogc_content_parse_inline_internal(const char *src, size_t src_len)
state = CONTENT_INLINE_UNDERSCORE_DOUBLE;
break;
}
- tmp = bc_str_find(src + current, '_');
+ tmp = sb_str_find(src + current, '_');
if (tmp == NULL || ((tmp - src) >= src_len)) {
- bc_string_append_c(rv, '_');
+ sb_string_append_c(rv, '_');
state = CONTENT_INLINE_START;
continue;
}
tmp2 = blogc_content_parse_inline_internal(
src + current, (tmp - src) - current);
- bc_string_append_printf(rv, "<em>%s</em>", tmp2);
+ sb_string_append_printf(rv, "<em>%s</em>", tmp2);
current = tmp - src;
tmp = NULL;
free(tmp2);
@@ -310,21 +309,21 @@ blogc_content_parse_inline_internal(const char *src, size_t src_len)
case CONTENT_INLINE_UNDERSCORE_DOUBLE:
tmp = src + current;
do {
- tmp = bc_str_find(tmp, '_');
+ tmp = sb_str_find(tmp, '_');
if (((tmp - src) < src_len) && *(tmp + 1) == '_') {
break;
}
tmp++;
} while (tmp != NULL && (tmp - src) < src_len);
if (tmp == NULL || ((tmp - src) >= src_len)) {
- bc_string_append_c(rv, '_');
- bc_string_append_c(rv, '_');
+ sb_string_append_c(rv, '_');
+ sb_string_append_c(rv, '_');
state = CONTENT_INLINE_START;
continue;
}
tmp2 = blogc_content_parse_inline_internal(
src + current, (tmp - src) - current);
- bc_string_append_printf(rv, "<strong>%s</strong>", tmp2);
+ sb_string_append_printf(rv, "<strong>%s</strong>", tmp2);
current = tmp - src + 1;
tmp = NULL;
free(tmp2);
@@ -337,19 +336,19 @@ blogc_content_parse_inline_internal(const char *src, size_t src_len)
state = CONTENT_INLINE_BACKTICKS_DOUBLE;
break;
}
- tmp = bc_str_find(src + current, '`');
+ tmp = sb_str_find(src + current, '`');
if (tmp == NULL || ((tmp - src) >= src_len)) {
- bc_string_append_c(rv, '`');
+ sb_string_append_c(rv, '`');
state = CONTENT_INLINE_START;
continue;
}
- tmp3 = bc_strndup(src + current, (tmp - src) - current);
+ tmp3 = sb_strndup(src + current, (tmp - src) - current);
tmp2 = blogc_htmlentities(tmp3);
free(tmp3);
tmp3 = NULL;
- bc_string_append(rv, "<code>");
- bc_string_append(rv, tmp2);
- bc_string_append(rv, "</code>");
+ sb_string_append(rv, "<code>");
+ sb_string_append_escaped(rv, tmp2);
+ sb_string_append(rv, "</code>");
current = tmp - src;
tmp = NULL;
free(tmp2);
@@ -360,25 +359,25 @@ blogc_content_parse_inline_internal(const char *src, size_t src_len)
case CONTENT_INLINE_BACKTICKS_DOUBLE:
tmp = src + current;
do {
- tmp = bc_str_find(tmp, '`');
+ tmp = sb_str_find(tmp, '`');
if (((tmp - src) < src_len) && *(tmp + 1) == '`') {
break;
}
tmp++;
} while (tmp != NULL && (tmp - src) < src_len);
if (tmp == NULL || ((tmp - src) >= src_len)) {
- bc_string_append_c(rv, '`');
- bc_string_append_c(rv, '`');
+ sb_string_append_c(rv, '`');
+ sb_string_append_c(rv, '`');
state = CONTENT_INLINE_START;
continue;
}
- tmp3 = bc_strndup(src + current, (tmp - src) - current);
+ tmp3 = sb_strndup(src + current, (tmp - src) - current);
tmp2 = blogc_htmlentities(tmp3);
free(tmp3);
tmp3 = NULL;
- bc_string_append(rv, "<code>");
- bc_string_append(rv, tmp2);
- bc_string_append(rv, "</code>");
+ sb_string_append(rv, "<code>");
+ sb_string_append_escaped(rv, tmp2);
+ sb_string_append(rv, "</code>");
current = tmp - src + 1;
tmp = NULL;
free(tmp2);
@@ -399,24 +398,24 @@ blogc_content_parse_inline_internal(const char *src, size_t src_len)
case CONTENT_INLINE_LINK_AUTO:
tmp = src + current;
do {
- tmp = bc_str_find(tmp, ']');
+ tmp = sb_str_find(tmp, ']');
if (((tmp - src) < src_len) && *(tmp + 1) == ']') {
break;
}
tmp++;
} while (tmp != NULL && (tmp - src) < src_len);
if (tmp == NULL || ((tmp - src) >= src_len)) {
- bc_string_append_c(rv, '[');
- bc_string_append_c(rv, '[');
+ sb_string_append_c(rv, '[');
+ sb_string_append_c(rv, '[');
state = CONTENT_INLINE_START;
continue;
}
- tmp2 = bc_strndup(src + current, (tmp - src) - current);
- bc_string_append(rv, "<a href=\"");
- bc_string_append_escaped(rv, tmp2);
- bc_string_append(rv, "\">");
- bc_string_append_escaped(rv, tmp2);
- bc_string_append(rv, "</a>");
+ tmp2 = sb_strndup(src + current, (tmp - src) - current);
+ sb_string_append(rv, "<a href=\"");
+ sb_string_append_escaped(rv, tmp2);
+ sb_string_append(rv, "\">");
+ sb_string_append_escaped(rv, tmp2);
+ sb_string_append(rv, "</a>");
current = tmp - src + 1;
tmp = NULL;
free(tmp2);
@@ -435,7 +434,7 @@ blogc_content_parse_inline_internal(const char *src, size_t src_len)
}
if (c == ']') {
if (--count == 0) {
- link1 = bc_strndup(src + start_link, current - start_link);
+ link1 = sb_strndup(src + start_link, current - start_link);
state = CONTENT_INLINE_LINK_URL_START;
}
}
@@ -449,7 +448,7 @@ blogc_content_parse_inline_internal(const char *src, size_t src_len)
start = current + 1;
break;
}
- bc_string_append_c(rv, '[');
+ sb_string_append_c(rv, '[');
state = CONTENT_INLINE_START;
current = start_link;
start_link = 0;
@@ -461,13 +460,13 @@ blogc_content_parse_inline_internal(const char *src, size_t src_len)
break;
}
if (c == ')') {
- tmp2 = bc_strndup(src + start, current - start);
+ tmp2 = sb_strndup(src + start, current - start);
tmp3 = blogc_content_parse_inline(link1);
free(link1);
link1 = NULL;
- bc_string_append(rv, "<a href=\"");
- bc_string_append_escaped(rv, tmp2);
- bc_string_append_printf(rv, "\">%s</a>", tmp3);
+ sb_string_append(rv, "<a href=\"");
+ sb_string_append_escaped(rv, tmp2);
+ sb_string_append_printf(rv, "\">%s</a>", tmp3);
free(tmp2);
tmp2 = NULL;
free(tmp3);
@@ -484,7 +483,7 @@ blogc_content_parse_inline_internal(const char *src, size_t src_len)
start_link = current + 1;
break;
}
- bc_string_append_c(rv, '!');
+ sb_string_append_c(rv, '!');
state = CONTENT_INLINE_START;
continue;
@@ -494,7 +493,7 @@ blogc_content_parse_inline_internal(const char *src, size_t src_len)
break;
}
if (c == ']') {
- link1 = bc_strndup(src + start_link, current - start_link);
+ link1 = sb_strndup(src + start_link, current - start_link);
state = CONTENT_INLINE_IMAGE_URL_START;
}
break;
@@ -507,8 +506,8 @@ blogc_content_parse_inline_internal(const char *src, size_t src_len)
start = current + 1;
break;
}
- bc_string_append_c(rv, '!');
- bc_string_append_c(rv, '[');
+ sb_string_append_c(rv, '!');
+ sb_string_append_c(rv, '[');
state = CONTENT_INLINE_START;
current = start_link;
start_link = 0;
@@ -520,12 +519,12 @@ blogc_content_parse_inline_internal(const char *src, size_t src_len)
break;
}
if (c == ')') {
- tmp2 = bc_strndup(src + start, current - start);
- bc_string_append(rv, "<img src=\"");
- bc_string_append_escaped(rv, tmp2);
- bc_string_append(rv, "\" alt=\"");
- bc_string_append_escaped(rv, link1);
- bc_string_append(rv, "\">");
+ tmp2 = sb_strndup(src + start, current - start);
+ sb_string_append(rv, "<img src=\"");
+ sb_string_append_escaped(rv, tmp2);
+ sb_string_append(rv, "\" alt=\"");
+ sb_string_append_escaped(rv, link1);
+ sb_string_append(rv, "\">");
free(tmp2);
tmp2 = NULL;
free(link1);
@@ -538,31 +537,31 @@ blogc_content_parse_inline_internal(const char *src, size_t src_len)
case CONTENT_INLINE_ENDASH:
if (c == '-') {
if (is_last) {
- bc_string_append(rv, "&ndash;");
+ sb_string_append(rv, "&ndash;");
state = CONTENT_INLINE_START; // wat
break;
}
state = CONTENT_INLINE_EMDASH;
break;
}
- bc_string_append_c(rv, '-');
+ sb_string_append_c(rv, '-');
state = CONTENT_INLINE_START;
continue;
case CONTENT_INLINE_EMDASH:
if (c == '-') {
- bc_string_append(rv, "&mdash;");
+ sb_string_append(rv, "&mdash;");
state = CONTENT_INLINE_START;
break;
}
- bc_string_append(rv, "&ndash;");
+ sb_string_append(rv, "&ndash;");
state = CONTENT_INLINE_START;
continue;
case CONTENT_INLINE_LINE_BREAK_START:
if (c == ' ') {
if (is_last) {
- bc_string_append(rv, "<br />");
+ sb_string_append(rv, "<br />");
state = CONTENT_INLINE_START; // wat
break;
}
@@ -570,14 +569,14 @@ blogc_content_parse_inline_internal(const char *src, size_t src_len)
state = CONTENT_INLINE_LINE_BREAK;
break;
}
- bc_string_append_c(rv, ' ');
+ sb_string_append_c(rv, ' ');
state = CONTENT_INLINE_START;
continue;
case CONTENT_INLINE_LINE_BREAK:
if (c == ' ') {
if (is_last) {
- bc_string_append(rv, "<br />");
+ sb_string_append(rv, "<br />");
state = CONTENT_INLINE_START; // wat
break;
}
@@ -585,12 +584,12 @@ blogc_content_parse_inline_internal(const char *src, size_t src_len)
break;
}
if (c == '\n' || c == '\r') {
- bc_string_append_printf(rv, "<br />%c", c);
+ sb_string_append_printf(rv, "<br />%c", c);
state = CONTENT_INLINE_START;
break;
}
for (size_t i = 0; i < count; i++)
- bc_string_append_c(rv, ' ');
+ sb_string_append_c(rv, ' ');
state = CONTENT_INLINE_START;
continue;
}
@@ -605,14 +604,14 @@ blogc_content_parse_inline_internal(const char *src, size_t src_len)
case CONTENT_INLINE_IMAGE_ALT:
case CONTENT_INLINE_IMAGE_URL_START:
case CONTENT_INLINE_IMAGE_URL:
- bc_string_append_c(rv, '!');
+ sb_string_append_c(rv, '!');
case CONTENT_INLINE_LINK_CONTENT:
case CONTENT_INLINE_LINK_URL_START:
case CONTENT_INLINE_LINK_URL:
tmp2 = blogc_content_parse_inline(src + start_link);
- bc_string_append_c(rv, '[');
- bc_string_append_escaped(rv, tmp2); // no need to free, as it wil be done below.
+ sb_string_append_c(rv, '[');
+ sb_string_append_escaped(rv, tmp2); // no need to free, as it wil be done below.
break;
// add all the other states here explicitly, so the compiler helps us
@@ -637,7 +636,7 @@ blogc_content_parse_inline_internal(const char *src, size_t src_len)
free(tmp3);
free(link1);
- return bc_string_free(rv, false);
+ return sb_string_free(rv, false);
}
@@ -675,9 +674,36 @@ blogc_is_ordered_list_item(const char *str, size_t prefix_len)
}
-char*
-blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
- char **description, char **endl, bc_slist_t **headers)
+static blogc_content_node_t*
+block_node_new(blogc_content_block_type_t type, char *content, sb_trie_t *parameters)
+{
+ blogc_content_node_t *rv = sb_malloc(sizeof(blogc_content_node_t));
+ rv->node_type = BLOGC_CONTENT_BLOCK;
+ rv->type.block_type = type;
+ rv->content = content;
+ rv->parameters = parameters;
+ rv->child = NULL;
+ rv->next = NULL;
+ return rv;
+}
+
+
+static blogc_content_node_t*
+inline_node_new(blogc_content_inline_type_t type, char *content, sb_trie_t *parameters)
+{
+ blogc_content_node_t *rv = sb_malloc(sizeof(blogc_content_node_t));
+ rv->node_type = BLOGC_CONTENT_INLINE;
+ rv->type.inline_type = type;
+ rv->content = content;
+ rv->parameters = parameters;
+ rv->child = NULL;
+ rv->next = NULL;
+ return rv;
+}
+
+
+blogc_content_node_t*
+blogc_content_parse_ast(const char *src, char **nl)
{
// src is always nul-terminated.
size_t src_len = strlen(src);
@@ -686,47 +712,30 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
size_t start = 0;
size_t start2 = 0;
size_t end = 0;
- size_t eend = 0;
size_t real_end = 0;
- size_t header_level = 0;
+ unsigned int header_level = 0;
char *prefix = NULL;
size_t prefix_len = 0;
char *tmp = NULL;
char *tmp2 = NULL;
char *parsed = NULL;
- char *slug = NULL;
-
- char *line_ending = NULL;
- bool line_ending_found = false;
- if (endl != NULL) {
- if (*endl != NULL) {
- line_ending_found = true;
- }
- else {
- *endl = bc_malloc(3 * sizeof(char));
- }
- line_ending = *endl;
- }
- else {
- line_ending = bc_malloc(3 * sizeof(char));
- }
// this isn't empty because we need some reasonable default value in the
// unlikely case that we need to print some line ending before evaluating
// the "real" value.
- if (!line_ending_found) {
- line_ending[0] = '\n';
- line_ending[1] = '\0';
- }
+ char line_ending[3] = "\n";
+ bool line_ending_found = false;
char d = '\0';
- bc_slist_t *lines = NULL;
- bc_slist_t *lines2 = NULL;
+ sb_slist_t *lines = NULL;
+ sb_slist_t *lines2 = NULL;
- bc_string_t *rv = bc_string_new();
- bc_string_t *tmp_str = NULL;
+ sb_string_t *tmp_str = NULL;
+
+ blogc_content_node_t *ast = NULL;
+ blogc_content_node_t *last = NULL;
blogc_content_parser_state_t state = CONTENT_START_LINE;
@@ -764,11 +773,8 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
break;
start = current;
if (c == '.') {
- if (end_excerpt != NULL) {
- eend = rv->len; // fuck it
- state = CONTENT_EXCERPT;
- break;
- }
+ state = CONTENT_EXCERPT;
+ break;
}
if (c == '#') {
header_level = 1;
@@ -777,7 +783,7 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
}
if (c == '*' || c == '+' || c == '-') {
start2 = current;
- state = CONTENT_UNORDERED_LIST_OR_HORIZONTAL_RULE_OR_EMPHASIS;
+ state = CONTENT_UNORDERED_LIST_OR_HORIZONTAL_RULE;
d = c;
break;
}
@@ -804,27 +810,28 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
break;
case CONTENT_EXCERPT:
- if (end_excerpt != NULL) {
- if (c == '.')
- break;
- if (c == '\n' || c == '\r') {
- state = CONTENT_EXCERPT_END;
- break;
- }
+ if (c == '.')
+ break;
+ if (c == '\n' || c == '\r') {
+ state = CONTENT_EXCERPT_END;
+ break;
}
- eend = 0;
state = CONTENT_PARAGRAPH;
break;
case CONTENT_EXCERPT_END:
- if (end_excerpt != NULL) {
- if (c == '\n' || c == '\r') {
- *end_excerpt = eend;
- state = CONTENT_START_LINE;
- break;
+ if (c == '\n' || c == '\r') {
+ if (ast == NULL) {
+ ast = block_node_new(BLOGC_CONTENT_BLOCK_EXCERPT, NULL, NULL);
+ last = ast;
+ }
+ else {
+ last->next = block_node_new(BLOGC_CONTENT_BLOCK_EXCERPT, NULL, NULL);
+ last = last->next;
}
+ state = CONTENT_START_LINE;
+ break;
}
- eend = 0;
state = CONTENT_PARAGRAPH_END;
break;
@@ -853,23 +860,17 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
if (c == '\n' || c == '\r' || is_last) {
end = is_last && c != '\n' && c != '\r' ? src_len :
(real_end != 0 ? real_end : current);
- tmp = bc_strndup(src + start, end - start);
- if (first_header != NULL && *first_header == NULL)
- *first_header = blogc_htmlentities(tmp);
- parsed = blogc_content_parse_inline(tmp);
- slug = blogc_slugify(tmp);
- if (headers != NULL)
- *headers = blogc_toctree_append(*headers, header_level, slug, parsed);
- if (slug == NULL)
- bc_string_append_printf(rv, "<h%d>%s</h%d>%s",
- header_level, parsed, header_level, line_ending);
- else
- bc_string_append_printf(rv, "<h%d id=\"%s\">%s</h%d>%s",
- header_level, slug, parsed, header_level,
- line_ending);
- free(slug);
- free(parsed);
- parsed = NULL;
+ tmp = sb_strndup(src + start, end - start);
+ sb_trie_t *t = sb_trie_new(free);
+ sb_trie_insert(t, "level", sb_strdup_printf("%d", header_level));
+ if (ast == NULL) {
+ ast = block_node_new(BLOGC_CONTENT_BLOCK_HEADER, blogc_content_parse_inline(tmp), t);
+ last = ast;
+ }
+ else {
+ last->next = block_node_new(BLOGC_CONTENT_BLOCK_HEADER, blogc_content_parse_inline(tmp), t); // TODO: inline-me
+ last = last->next;
+ }
free(tmp);
tmp = NULL;
state = CONTENT_START_LINE;
@@ -888,10 +889,16 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
case CONTENT_HTML_END:
if (c == '\n' || c == '\r' || is_last) {
- tmp = bc_strndup(src + start, end - start);
- bc_string_append_printf(rv, "%s%s", tmp, line_ending);
- free(tmp);
- tmp = NULL;
+ if (ast == NULL) {
+ ast = block_node_new(BLOGC_CONTENT_BLOCK_RAW,
+ sb_strndup(src + start, end - start), NULL);
+ last = ast;
+ }
+ else {
+ last->next = block_node_new(BLOGC_CONTENT_BLOCK_RAW,
+ sb_strndup(src + start, end - start), NULL);
+ last = last->next;
+ }
state = CONTENT_START_LINE;
start = current;
}
@@ -902,7 +909,7 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
case CONTENT_BLOCKQUOTE:
if (c == ' ' || c == '\t')
break;
- prefix = bc_strndup(src + start, current - start);
+ prefix = sb_strndup(src + start, current - start);
state = CONTENT_BLOCKQUOTE_START;
break;
@@ -910,16 +917,16 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
if (c == '\n' || c == '\r' || is_last) {
end = is_last && c != '\n' && c != '\r' ? src_len :
(real_end != 0 ? real_end : current);
- tmp = bc_strndup(src + start2, end - start2);
- if (bc_str_starts_with(tmp, prefix)) {
- lines = bc_slist_append(lines, bc_strdup(tmp + strlen(prefix)));
+ tmp = sb_strndup(src + start2, end - start2);
+ if (sb_str_starts_with(tmp, prefix)) {
+ lines = sb_slist_append(lines, sb_strdup(tmp + strlen(prefix)));
state = CONTENT_BLOCKQUOTE_END;
}
else {
state = CONTENT_PARAGRAPH;
free(prefix);
prefix = NULL;
- bc_slist_free_full(lines, free);
+ sb_slist_free_full(lines, free);
lines = NULL;
if (is_last) {
free(tmp);
@@ -935,21 +942,25 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
case CONTENT_BLOCKQUOTE_END:
if (c == '\n' || c == '\r' || is_last) {
- tmp_str = bc_string_new();
- for (bc_slist_t *l = lines; l != NULL; l = l->next)
- bc_string_append_printf(tmp_str, "%s%s", l->data,
+ tmp_str = sb_string_new();
+ for (sb_slist_t *l = lines; l != NULL; l = l->next)
+ sb_string_append_printf(tmp_str, "%s%s", l->data,
line_ending);
- // do not propagate title and description to blockquote parsing,
- // because we just want paragraphs from first level of
- // content.
- tmp = blogc_content_parse(tmp_str->str, NULL, NULL, NULL, endl, NULL);
- bc_string_append_printf(rv, "<blockquote>%s</blockquote>%s",
- tmp, line_ending);
- free(tmp);
- tmp = NULL;
- bc_string_free(tmp_str, true);
+ if (ast == NULL) {
+ ast = block_node_new(BLOGC_CONTENT_BLOCK_BLOCKQUOTE,
+ NULL, NULL);
+ ast->child = blogc_content_parse_ast(tmp_str->str, nl);
+ last = ast;
+ }
+ else {
+ last->next = block_node_new(BLOGC_CONTENT_BLOCK_BLOCKQUOTE,
+ NULL, NULL);
+ last->next->child = blogc_content_parse_ast(tmp_str->str, nl);
+ last = last->next;
+ }
+ sb_string_free(tmp_str, true);
tmp_str = NULL;
- bc_slist_free_full(lines, free);
+ sb_slist_free_full(lines, free);
lines = NULL;
free(prefix);
prefix = NULL;
@@ -965,7 +976,7 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
case CONTENT_CODE:
if (c == ' ' || c == '\t')
break;
- prefix = bc_strndup(src + start, current - start);
+ prefix = sb_strndup(src + start, current - start);
state = CONTENT_CODE_START;
break;
@@ -973,16 +984,16 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
if (c == '\n' || c == '\r' || is_last) {
end = is_last && c != '\n' && c != '\r' ? src_len :
(real_end != 0 ? real_end : current);
- tmp = bc_strndup(src + start2, end - start2);
- if (bc_str_starts_with(tmp, prefix)) {
- lines = bc_slist_append(lines, bc_strdup(tmp + strlen(prefix)));
+ tmp = sb_strndup(src + start2, end - start2);
+ if (sb_str_starts_with(tmp, prefix)) {
+ lines = sb_slist_append(lines, sb_strdup(tmp + strlen(prefix)));
state = CONTENT_CODE_END;
}
else {
state = CONTENT_PARAGRAPH;
free(prefix);
prefix = NULL;
- bc_slist_free_full(lines, free);
+ sb_slist_free_full(lines, free);
lines = NULL;
free(tmp);
tmp = NULL;
@@ -998,18 +1009,26 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
case CONTENT_CODE_END:
if (c == '\n' || c == '\r' || is_last) {
- bc_string_append(rv, "<pre><code>");
- for (bc_slist_t *l = lines; l != NULL; l = l->next) {
- char *tmp_line = blogc_htmlentities(l->data);
+ tmp_str = sb_string_new();
+ for (sb_slist_t *l = lines; l != NULL; l = l->next) {
if (l->next == NULL)
- bc_string_append_printf(rv, "%s", tmp_line);
+ sb_string_append_printf(tmp_str, "%s", l->data);
else
- bc_string_append_printf(rv, "%s%s", tmp_line,
+ sb_string_append_printf(tmp_str, "%s%s", l->data,
line_ending);
- free(tmp_line);
}
- bc_string_append_printf(rv, "</code></pre>%s", line_ending);
- bc_slist_free_full(lines, free);
+ if (ast == NULL) {
+ ast = block_node_new(BLOGC_CONTENT_BLOCK_CODE,
+ sb_string_free(tmp_str, false), NULL);
+ last = ast;
+ }
+ else {
+ last->next = block_node_new(BLOGC_CONTENT_BLOCK_CODE,
+ sb_string_free(tmp_str, false), NULL);
+ last = last->next;
+ }
+ tmp_str = NULL;
+ sb_slist_free_full(lines, free);
lines = NULL;
free(prefix);
prefix = NULL;
@@ -1022,33 +1041,17 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
}
break;
- case CONTENT_UNORDERED_LIST_OR_HORIZONTAL_RULE_OR_EMPHASIS:
- if (current == start+1) {
- if (c == d) { // horizontal rule or '**' emphasis
- state = CONTENT_HORIZONTAL_RULE_OR_EMPHASIS;
- break;
- }
- else if (c != ' ' && c != '\t' && d == '*') { // is '*' emphasis
- state = CONTENT_PARAGRAPH;
- break;
- }
- }
- if (c == ' ' || c == '\t')
- break;
- prefix = bc_strndup(src + start, current - start);
- state = CONTENT_UNORDERED_LIST_START;
- break;
-
- case CONTENT_HORIZONTAL_RULE_OR_EMPHASIS:
- // 3rd '-' or '*' required for a horizontal rule
+ case CONTENT_UNORDERED_LIST_OR_HORIZONTAL_RULE:
if (c == d) {
state = CONTENT_HORIZONTAL_RULE;
if (is_last)
continue;
break;
}
- // is '**' emphasis
- state = CONTENT_PARAGRAPH;
+ if (c == ' ' || c == '\t')
+ break;
+ prefix = sb_strndup(src + start, current - start);
+ state = CONTENT_UNORDERED_LIST_START;
break;
case CONTENT_HORIZONTAL_RULE:
@@ -1056,7 +1059,16 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
break;
}
if (c == '\n' || c == '\r' || is_last) {
- bc_string_append_printf(rv, "<hr />%s", line_ending);
+ if (ast == NULL) {
+ ast = block_node_new(BLOGC_CONTENT_BLOCK_HORIZONTAL_RULE,
+ NULL, NULL);
+ last = ast;
+ }
+ else {
+ last->next = block_node_new(BLOGC_CONTENT_BLOCK_HORIZONTAL_RULE,
+ NULL, NULL);
+ last = last->next;
+ }
state = CONTENT_START_LINE;
start = current;
d = '\0';
@@ -1069,30 +1081,30 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
if (c == '\n' || c == '\r' || is_last) {
end = is_last && c != '\n' && c != '\r' ? src_len :
(real_end != 0 ? real_end : current);
- tmp = bc_strndup(src + start2, end - start2);
- tmp2 = bc_strdup_printf("%-*s", strlen(prefix), "");
- if (bc_str_starts_with(tmp, prefix)) {
+ tmp = sb_strndup(src + start2, end - start2);
+ tmp2 = sb_strdup_printf("%-*s", strlen(prefix), "");
+ if (sb_str_starts_with(tmp, prefix)) {
if (lines2 != NULL) {
- tmp_str = bc_string_new();
- for (bc_slist_t *l = lines2; l != NULL; l = l->next) {
+ tmp_str = sb_string_new();
+ for (sb_slist_t *l = lines2; l != NULL; l = l->next) {
if (l->next == NULL)
- bc_string_append_printf(tmp_str, "%s", l->data);
+ sb_string_append_printf(tmp_str, "%s", l->data);
else
- bc_string_append_printf(tmp_str, "%s%s", l->data,
+ sb_string_append_printf(tmp_str, "%s%s", l->data,
line_ending);
}
- bc_slist_free_full(lines2, free);
+ sb_slist_free_full(lines2, free);
lines2 = NULL;
parsed = blogc_content_parse_inline(tmp_str->str);
- bc_string_free(tmp_str, true);
- lines = bc_slist_append(lines, bc_strdup(parsed));
+ sb_string_free(tmp_str, true);
+ lines = sb_slist_append(lines, sb_strdup(parsed));
free(parsed);
parsed = NULL;
}
- lines2 = bc_slist_append(lines2, bc_strdup(tmp + strlen(prefix)));
+ lines2 = sb_slist_append(lines2, sb_strdup(tmp + strlen(prefix)));
}
- else if (bc_str_starts_with(tmp, tmp2)) {
- lines2 = bc_slist_append(lines2, bc_strdup(tmp + strlen(prefix)));
+ else if (sb_str_starts_with(tmp, tmp2)) {
+ lines2 = sb_slist_append(lines2, sb_strdup(tmp + strlen(prefix)));
}
else {
state = CONTENT_PARAGRAPH_END;
@@ -1102,8 +1114,8 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
tmp2 = NULL;
free(prefix);
prefix = NULL;
- bc_slist_free_full(lines, free);
- bc_slist_free_full(lines2, free);
+ sb_slist_free_full(lines, free);
+ sb_slist_free_full(lines2, free);
lines = NULL;
if (is_last)
continue;
@@ -1122,28 +1134,46 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
if (c == '\n' || c == '\r' || is_last) {
if (lines2 != NULL) {
// FIXME: avoid repeting the code below
- tmp_str = bc_string_new();
- for (bc_slist_t *l = lines2; l != NULL; l = l->next) {
+ tmp_str = sb_string_new();
+ for (sb_slist_t *l = lines2; l != NULL; l = l->next) {
if (l->next == NULL)
- bc_string_append_printf(tmp_str, "%s", l->data);
+ sb_string_append_printf(tmp_str, "%s", l->data);
else
- bc_string_append_printf(tmp_str, "%s%s", l->data,
+ sb_string_append_printf(tmp_str, "%s%s", l->data,
line_ending);
}
- bc_slist_free_full(lines2, free);
+ sb_slist_free_full(lines2, free);
lines2 = NULL;
parsed = blogc_content_parse_inline(tmp_str->str);
- bc_string_free(tmp_str, true);
- lines = bc_slist_append(lines, bc_strdup(parsed));
+ sb_string_free(tmp_str, true);
+ lines = sb_slist_append(lines, sb_strdup(parsed));
free(parsed);
parsed = NULL;
}
- bc_string_append_printf(rv, "<ul>%s", line_ending);
- for (bc_slist_t *l = lines; l != NULL; l = l->next)
- bc_string_append_printf(rv, "<li>%s</li>%s", l->data,
- line_ending);
- bc_string_append_printf(rv, "</ul>%s", line_ending);
- bc_slist_free_full(lines, free);
+ if (ast == NULL) {
+ ast = block_node_new(BLOGC_CONTENT_BLOCK_UNORDERED_LIST,
+ NULL, NULL);
+ last = ast;
+ }
+ else {
+ last->next = block_node_new(BLOGC_CONTENT_BLOCK_UNORDERED_LIST,
+ NULL, NULL);
+ last = last->next;
+ }
+ blogc_content_node_t *last_list = NULL;
+ for (sb_slist_t *l = lines; l != NULL; l = l->next) {
+ if (last_list == NULL) {
+ last->child = block_node_new(BLOGC_CONTENT_BLOCK_LIST_ITEM,
+ l->data, NULL);
+ last_list = last->child;
+ }
+ else {
+ last_list->next = block_node_new(BLOGC_CONTENT_BLOCK_LIST_ITEM,
+ l->data, NULL);
+ last_list = last_list->next;
+ }
+ }
+ sb_slist_free(lines);
lines = NULL;
free(prefix);
prefix = NULL;
@@ -1180,30 +1210,30 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
if (c == '\n' || c == '\r' || is_last) {
end = is_last && c != '\n' && c != '\r' ? src_len :
(real_end != 0 ? real_end : current);
- tmp = bc_strndup(src + start2, end - start2);
- tmp2 = bc_strdup_printf("%-*s", prefix_len, "");
+ tmp = sb_strndup(src + start2, end - start2);
+ tmp2 = sb_strdup_printf("%-*s", prefix_len, "");
if (blogc_is_ordered_list_item(tmp, prefix_len)) {
if (lines2 != NULL) {
- tmp_str = bc_string_new();
- for (bc_slist_t *l = lines2; l != NULL; l = l->next) {
+ tmp_str = sb_string_new();
+ for (sb_slist_t *l = lines2; l != NULL; l = l->next) {
if (l->next == NULL)
- bc_string_append_printf(tmp_str, "%s", l->data);
+ sb_string_append_printf(tmp_str, "%s", l->data);
else
- bc_string_append_printf(tmp_str, "%s%s", l->data,
+ sb_string_append_printf(tmp_str, "%s%s", l->data,
line_ending);
}
- bc_slist_free_full(lines2, free);
+ sb_slist_free_full(lines2, free);
lines2 = NULL;
parsed = blogc_content_parse_inline(tmp_str->str);
- bc_string_free(tmp_str, true);
- lines = bc_slist_append(lines, bc_strdup(parsed));
+ sb_string_free(tmp_str, true);
+ lines = sb_slist_append(lines, sb_strdup(parsed));
free(parsed);
parsed = NULL;
}
- lines2 = bc_slist_append(lines2, bc_strdup(tmp + prefix_len));
+ lines2 = sb_slist_append(lines2, sb_strdup(tmp + prefix_len));
}
- else if (bc_str_starts_with(tmp, tmp2)) {
- lines2 = bc_slist_append(lines2, bc_strdup(tmp + prefix_len));
+ else if (sb_str_starts_with(tmp, tmp2)) {
+ lines2 = sb_slist_append(lines2, sb_strdup(tmp + prefix_len));
}
else {
state = CONTENT_PARAGRAPH_END;
@@ -1213,8 +1243,8 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
tmp2 = NULL;
free(parsed);
parsed = NULL;
- bc_slist_free_full(lines, free);
- bc_slist_free_full(lines2, free);
+ sb_slist_free_full(lines, free);
+ sb_slist_free_full(lines2, free);
lines = NULL;
if (is_last)
continue;
@@ -1233,28 +1263,46 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
if (c == '\n' || c == '\r' || is_last) {
if (lines2 != NULL) {
// FIXME: avoid repeting the code below
- tmp_str = bc_string_new();
- for (bc_slist_t *l = lines2; l != NULL; l = l->next) {
+ tmp_str = sb_string_new();
+ for (sb_slist_t *l = lines2; l != NULL; l = l->next) {
if (l->next == NULL)
- bc_string_append_printf(tmp_str, "%s", l->data);
+ sb_string_append_printf(tmp_str, "%s", l->data);
else
- bc_string_append_printf(tmp_str, "%s%s", l->data,
+ sb_string_append_printf(tmp_str, "%s%s", l->data,
line_ending);
}
- bc_slist_free_full(lines2, free);
+ sb_slist_free_full(lines2, free);
lines2 = NULL;
parsed = blogc_content_parse_inline(tmp_str->str);
- bc_string_free(tmp_str, true);
- lines = bc_slist_append(lines, bc_strdup(parsed));
+ sb_string_free(tmp_str, true);
+ lines = sb_slist_append(lines, sb_strdup(parsed));
free(parsed);
parsed = NULL;
}
- bc_string_append_printf(rv, "<ol>%s", line_ending);
- for (bc_slist_t *l = lines; l != NULL; l = l->next)
- bc_string_append_printf(rv, "<li>%s</li>%s", l->data,
- line_ending);
- bc_string_append_printf(rv, "</ol>%s", line_ending);
- bc_slist_free_full(lines, free);
+ if (ast == NULL) {
+ ast = block_node_new(BLOGC_CONTENT_BLOCK_ORDERED_LIST,
+ NULL, NULL);
+ last = ast;
+ }
+ else {
+ last->next = block_node_new(BLOGC_CONTENT_BLOCK_ORDERED_LIST,
+ NULL, NULL);
+ last = last->next;
+ }
+ blogc_content_node_t *last_list = NULL;
+ for (sb_slist_t *l = lines; l != NULL; l = l->next) {
+ if (last_list == NULL) {
+ last->child = block_node_new(BLOGC_CONTENT_BLOCK_LIST_ITEM,
+ l->data, NULL);
+ last_list = last->child;
+ }
+ else {
+ last_list->next = block_node_new(BLOGC_CONTENT_BLOCK_LIST_ITEM,
+ l->data, NULL);
+ last_list = last_list->next;
+ }
+ }
+ sb_slist_free(lines);
lines = NULL;
free(prefix);
prefix = NULL;
@@ -1278,16 +1326,19 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
case CONTENT_PARAGRAPH_END:
if (c == '\n' || c == '\r' || is_last) {
- tmp = bc_strndup(src + start, end - start);
- if (description != NULL && *description == NULL)
- *description = blogc_fix_description(tmp);
- parsed = blogc_content_parse_inline(tmp);
- bc_string_append_printf(rv, "<p>%s</p>%s", parsed,
- line_ending);
- free(parsed);
- parsed = NULL;
- free(tmp);
- tmp = NULL;
+ char *tmp2 = sb_strndup(src + start, end - start);
+ sb_trie_t *t = sb_trie_new(free);
+ sb_trie_insert(t, "parsed", blogc_content_parse_inline(tmp2));
+ if (ast == NULL) {
+ ast = block_node_new(BLOGC_CONTENT_BLOCK_PARAGRAPH,
+ tmp2, t);
+ last = ast;
+ }
+ else {
+ last->next = block_node_new(BLOGC_CONTENT_BLOCK_PARAGRAPH,
+ tmp2, t);
+ last = last->next;
+ }
state = CONTENT_START_LINE;
start = current;
}
@@ -1300,9 +1351,159 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header,
current++;
}
- if (endl == NULL) {
- free(line_ending);
+ if (nl != NULL && *nl == NULL)
+ *nl = sb_strdup(line_ending);
+
+ return ast;
+}
+
+
+void
+blogc_content_free_ast(blogc_content_node_t *ast)
+{
+ if (ast == NULL)
+ return;
+ free(ast->content);
+ sb_trie_free(ast->parameters);
+ blogc_content_free_ast(ast->child);
+ blogc_content_free_ast(ast->next);
+ free(ast);
+}
+
+
+char*
+blogc_content_parse(const char *src, char **excerpt, char **description)
+{
+ char *nl = NULL;
+ blogc_content_node_t *c = blogc_content_parse_ast(src, &nl);
+ char *rv = blogc_content_render_html(c, nl, excerpt, description);
+ free(nl);
+ blogc_content_free_ast(c);
+ return rv;
+}
+
+
+char*
+blogc_content_render_html(blogc_content_node_t *ast, char *nl, char **excerpt,
+ char **description)
+{
+ sb_string_t *rv = sb_string_new();
+ char *tmp = NULL;
+ for (blogc_content_node_t *l = ast; l != NULL; l = l->next) {
+ switch (l->node_type) {
+ case BLOGC_CONTENT_BLOCK:
+ switch (l->type.block_type) {
+ case BLOGC_CONTENT_BLOCK_RAW:
+ sb_string_append_printf(rv, "%s%s", l->content, nl);
+ break;
+ case BLOGC_CONTENT_BLOCK_HEADER:
+ tmp = blogc_slugify(l->content);
+ sb_string_append_printf(rv, "<h%s id=\"%s\">%s</h%s>%s",
+ sb_trie_lookup(l->parameters, "level"), tmp, l->content,
+ sb_trie_lookup(l->parameters, "level"), nl);
+ free(tmp);
+ tmp = NULL;
+ break;
+ case BLOGC_CONTENT_BLOCK_BLOCKQUOTE:
+ tmp = blogc_content_render_html(l->child, nl, NULL, NULL);
+ sb_string_append_printf(rv, "<blockquote>%s</blockquote>%s",
+ tmp, nl);
+ free(tmp);
+ tmp = NULL;
+ break;
+ case BLOGC_CONTENT_BLOCK_CODE:
+ tmp = blogc_htmlentities(l->content);
+ sb_string_append_printf(rv, "<pre><code>%s</code></pre>%s",
+ tmp, nl);
+ free(tmp);
+ tmp = NULL;
+ break;
+ case BLOGC_CONTENT_BLOCK_HORIZONTAL_RULE:
+ sb_string_append_printf(rv, "<hr />%s", nl);
+ break;
+ case BLOGC_CONTENT_BLOCK_UNORDERED_LIST:
+ tmp = blogc_content_render_html(l->child, nl, NULL, NULL);
+ sb_string_append_printf(rv, "<ul>%s%s</ul>%s", nl,
+ tmp, nl);
+ free(tmp);
+ tmp = NULL;
+ break;
+ case BLOGC_CONTENT_BLOCK_ORDERED_LIST:
+ tmp = blogc_content_render_html(l->child, nl, NULL, NULL);
+ sb_string_append_printf(rv, "<ol>%s%s</ol>%s", nl,
+ tmp, nl);
+ free(tmp);
+ tmp = NULL;
+ break;
+ case BLOGC_CONTENT_BLOCK_LIST_ITEM:
+ sb_string_append_printf(rv, "<li>%s</li>%s",
+ l->content, nl);
+ break;
+ case BLOGC_CONTENT_BLOCK_PARAGRAPH:
+ if (description != NULL && *description == NULL)
+ *description = blogc_fix_description(l->content);
+ sb_string_append_printf(rv, "<p>%s</p>%s",
+ sb_trie_lookup(l->parameters, "parsed"), nl);
+ break;
+ case BLOGC_CONTENT_BLOCK_EXCERPT:
+ if (excerpt != NULL && *excerpt == NULL)
+ *excerpt = sb_strdup(rv->str);
+ break;
+ }
+ break;
+ case BLOGC_CONTENT_INLINE:
+ break;
+ }
}
+ return sb_string_free(rv, false);
+}
+
- return bc_string_free(rv, false);
+void
+blogc_content_debug(blogc_content_node_t *ast)
+{
+ for (blogc_content_node_t *l = ast; l != NULL; l = l->next) {
+ switch (l->node_type) {
+ case BLOGC_CONTENT_BLOCK:
+ fprintf(stderr, "DEBUG: <CONTENT BLOCK ");
+ switch (l->type.block_type) {
+ case BLOGC_CONTENT_BLOCK_RAW:
+ fprintf(stderr, "RAW: `%s`", l->content);
+ break;
+ case BLOGC_CONTENT_BLOCK_HEADER:
+ fprintf(stderr, "HEADER: \"%s\"", l->content);
+ break;
+ case BLOGC_CONTENT_BLOCK_BLOCKQUOTE:
+ fprintf(stderr, "BLOCKQUOTE");
+ break;
+ case BLOGC_CONTENT_BLOCK_CODE:
+ fprintf(stderr, "CODE: `%s`", l->content);
+ break;
+ case BLOGC_CONTENT_BLOCK_HORIZONTAL_RULE:
+ fprintf(stderr, "HORIZONTAL_RULE");
+ break;
+ case BLOGC_CONTENT_BLOCK_UNORDERED_LIST:
+ fprintf(stderr, "UNORDERED_LIST");
+ break;
+ case BLOGC_CONTENT_BLOCK_ORDERED_LIST:
+ fprintf(stderr, "ORDERED_LIST");
+ break;
+ case BLOGC_CONTENT_BLOCK_LIST_ITEM:
+ fprintf(stderr, "LIST_ITEM: `%s`", l->content);
+ break;
+ case BLOGC_CONTENT_BLOCK_PARAGRAPH:
+ fprintf(stderr, "PARAGRAPH: `%s`", l->content);
+ break;
+ case BLOGC_CONTENT_BLOCK_EXCERPT:
+ fprintf(stderr, "EXCERPT");
+ break;
+ }
+ fprintf(stderr, ">\n");
+ if (l->child != NULL)
+ blogc_content_debug(l->child);
+ break;
+ case BLOGC_CONTENT_INLINE:
+ break;
+ }
+ }
}
diff --git a/src/content-parser.h b/src/content-parser.h
new file mode 100644
index 0000000..3a72317
--- /dev/null
+++ b/src/content-parser.h
@@ -0,0 +1,174 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#ifndef _CONTENT_PARSER_H
+#define _CONTENT_PARSER_H
+
+#include <stddef.h>
+#include <stdbool.h>
+
+#include "utils.h"
+
+/*
+ * Raw node
+ *
+ * +-----+
+ * | RAW | -> ...
+ * +-----+
+ *
+ */
+
+/*
+ * Header node
+ *
+ * +--------+
+ * | HEADER | -> ...
+ * +--------+
+ * |
+ * +-----+ +------+ +-----+
+ * | raw | -> | bold | -> | raw | -> ...
+ * +-----+ +------+ +-----+
+ *
+ */
+
+/*
+ * Blockquote node
+ *
+ * +------------+
+ * | BLOCKQUOTE | -> ...
+ * +------------+
+ * |
+ * +-----------+ +--------+ +-----------+
+ * | PARAGRAPH | -> | HEADER | -> | PARAGRAPH | -> ...
+ * +-----------+ +--------+ +-----------+
+ * |
+ * +-----+
+ * | raw | -> ...
+ * +-----+
+ *
+ */
+
+/*
+ * Code node
+ *
+ * +------+
+ * | CODE | -> ...
+ * +------+
+ *
+ */
+
+/*
+ * Horizontal rule node
+ *
+ * +-----------------+
+ * | HORIZONTAL_RULE | -> ...
+ * +-----------------+
+ *
+ */
+
+/*
+ * Unordered list node
+ *
+ * +----------------+
+ * | UNORDERED_LIST | -> ...
+ * +----------------+
+ * |
+ * +-----------+ +-----------+
+ * | LIST_ITEM | -> | LIST_ITEM | -> ...
+ * +-----------+ +-----------+
+ * |
+ * +-----+ +------+
+ * | raw | -> | bold | -> ...
+ * +-----+ +------+
+ *
+ */
+
+/*
+ * Ordered list node
+ *
+ * +--------------+
+ * | ORDERED_LIST | -> ...
+ * +--------------+
+ * |
+ * +-----------+ +-----------+
+ * | LIST_ITEM | -> | LIST_ITEM | -> ...
+ * +-----------+ +-----------+
+ * |
+ * +-----+ +------+
+ * | raw | -> | bold | -> ...
+ * +-----+ +------+
+ *
+ */
+
+/*
+ * Paragraph node
+ *
+ * +-----------+
+ * | PARAGRAPH | -> ...
+ * +-----------+
+ * |
+ * +-----+ +------+ +-----+
+ * | raw | -> | bold | -> | raw |
+ * +-----+ +------+ +-----+
+ *
+ */
+
+
+typedef enum {
+ BLOGC_CONTENT_BLOCK = 1,
+ BLOGC_CONTENT_INLINE,
+} blogc_content_node_type_t;
+
+typedef enum {
+ BLOGC_CONTENT_BLOCK_RAW = 1,
+ BLOGC_CONTENT_BLOCK_HEADER,
+ BLOGC_CONTENT_BLOCK_BLOCKQUOTE,
+ BLOGC_CONTENT_BLOCK_CODE,
+ BLOGC_CONTENT_BLOCK_HORIZONTAL_RULE,
+ BLOGC_CONTENT_BLOCK_UNORDERED_LIST,
+ BLOGC_CONTENT_BLOCK_ORDERED_LIST,
+ BLOGC_CONTENT_BLOCK_LIST_ITEM,
+ BLOGC_CONTENT_BLOCK_PARAGRAPH,
+ BLOGC_CONTENT_BLOCK_EXCERPT,
+} blogc_content_block_type_t;
+
+typedef enum {
+ BLOGC_CONTENT_INLINE_RAW = 1,
+ BLOGC_CONTENT_INLINE_LINK,
+ BLOGC_CONTENT_INLINE_IMAGE,
+ BLOGC_CONTENT_INLINE_BOLD,
+ BLOGC_CONTENT_INLINE_ITALIC,
+ BLOGC_CONTENT_INLINE_CODE,
+ BLOGC_CONTENT_INLINE_BREAK_LINE,
+} blogc_content_inline_type_t;
+
+typedef struct _blogc_content_node_t {
+ blogc_content_node_type_t node_type;
+ union {
+ blogc_content_block_type_t block_type;
+ blogc_content_inline_type_t inline_type;
+ } type;
+ char *content;
+ struct _blogc_content_node_t *child;
+ struct _blogc_content_node_t *next;
+ sb_trie_t *parameters;
+} blogc_content_node_t;
+
+char* blogc_slugify(const char *str);
+char* blogc_htmlentities(const char *str);
+char* blogc_fix_description(const char *paragraph);
+char* blogc_content_parse_inline(const char *src);
+bool blogc_is_ordered_list_item(const char *str, size_t prefix_len);
+blogc_content_node_t* blogc_content_parse_ast(const char *src, char **nl);
+void blogc_content_free_ast(blogc_content_node_t *ast);
+char* blogc_content_parse(const char *src, char **excerpt, char **description);
+char* blogc_content_render_html(blogc_content_node_t *ast, char *nl, char **excerpt,
+ char **description);
+void blogc_content_debug(blogc_content_node_t *ast);
+
+#endif /* _CONTENT_PARSER_H */
diff --git a/src/blogc/datetime-parser.c b/src/datetime-parser.c
index ddaf6ef..ad65ff7 100644
--- a/src/blogc/datetime-parser.c
+++ b/src/datetime-parser.c
@@ -1,6 +1,6 @@
/*
* blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
*
* This program can be distributed under the terms of the BSD License.
* See the file LICENSE.
@@ -16,9 +16,9 @@
#include <string.h>
+#include "error.h"
#include "datetime-parser.h"
-#include "../common/error.h"
-#include "../common/utils.h"
+#include "utils.h"
typedef enum {
@@ -47,14 +47,14 @@ typedef enum {
char*
blogc_convert_datetime(const char *orig, const char *format,
- bc_error_t **err)
+ blogc_error_t **err)
{
if (err == NULL || *err != NULL)
return NULL;
#ifndef HAVE_TIME_H
- *err = bc_error_new(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new(BLOGC_WARNING_DATETIME_PARSER,
"Your operating system does not supports the datetime functionalities "
"used by blogc. Sorry.");
return NULL;
@@ -69,7 +69,7 @@ blogc_convert_datetime(const char *orig, const char *format,
int tmp = 0;
int diff = '0';
- for (size_t i = 0; orig[i] != '\0'; i++) {
+ for (unsigned int i = 0; orig[i] != '\0'; i++) {
char c = orig[i];
switch (state) {
@@ -80,7 +80,7 @@ blogc_convert_datetime(const char *orig, const char *format,
state = DATETIME_SECOND_YEAR;
break;
}
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid first digit of year. "
"Found '%c', must be integer >= 0 and <= 9.", c);
break;
@@ -91,7 +91,7 @@ blogc_convert_datetime(const char *orig, const char *format,
state = DATETIME_THIRD_YEAR;
break;
}
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid second digit of year. "
"Found '%c', must be integer >= 0 and <= 9.", c);
break;
@@ -102,7 +102,7 @@ blogc_convert_datetime(const char *orig, const char *format,
state = DATETIME_FOURTH_YEAR;
break;
}
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid third digit of year. "
"Found '%c', must be integer >= 0 and <= 9.", c);
break;
@@ -111,7 +111,7 @@ blogc_convert_datetime(const char *orig, const char *format,
if (c >= '0' && c <= '9') {
tmp += c - diff - 1900;
if (tmp < 0) {
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid year. Found %d, must be >= 1900.",
tmp + 1900);
break;
@@ -120,7 +120,7 @@ blogc_convert_datetime(const char *orig, const char *format,
state = DATETIME_FIRST_HYPHEN;
break;
}
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid fourth digit of year. "
"Found '%c', must be integer >= 0 and <= 9.", c);
break;
@@ -131,7 +131,7 @@ blogc_convert_datetime(const char *orig, const char *format,
state = DATETIME_FIRST_MONTH;
break;
}
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid separator between year and month. "
"Found '%c', must be '-'.", c);
break;
@@ -142,7 +142,7 @@ blogc_convert_datetime(const char *orig, const char *format,
state = DATETIME_SECOND_MONTH;
break;
}
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid first digit of month. "
"Found '%c', must be integer >= 0 and <= 1.", c);
break;
@@ -151,7 +151,7 @@ blogc_convert_datetime(const char *orig, const char *format,
if (c >= '0' && c <= '9') {
tmp += c - diff - 1;
if (tmp < 0 || tmp > 11) {
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid month. Found %d, must be >= 1 and <= 12.",
tmp + 1);
break;
@@ -160,7 +160,7 @@ blogc_convert_datetime(const char *orig, const char *format,
state = DATETIME_SECOND_HYPHEN;
break;
}
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid second digit of month. "
"Found '%c', must be integer >= 0 and <= 9.", c);
break;
@@ -171,7 +171,7 @@ blogc_convert_datetime(const char *orig, const char *format,
state = DATETIME_FIRST_DAY;
break;
}
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid separator between month and day. "
"Found '%c', must be '-'.", c);
break;
@@ -182,7 +182,7 @@ blogc_convert_datetime(const char *orig, const char *format,
state = DATETIME_SECOND_DAY;
break;
}
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid first digit of day. "
"Found '%c', must be integer >= 0 and <= 3.", c);
break;
@@ -191,7 +191,7 @@ blogc_convert_datetime(const char *orig, const char *format,
if (c >= '0' && c <= '9') {
tmp += c - diff;
if (tmp < 1 || tmp > 31) {
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid day. Found %d, must be >= 1 and <= 31.",
tmp);
break;
@@ -200,7 +200,7 @@ blogc_convert_datetime(const char *orig, const char *format,
state = DATETIME_SPACE;
break;
}
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid second digit of day. "
"Found '%c', must be integer >= 0 and <= 9.", c);
break;
@@ -211,7 +211,7 @@ blogc_convert_datetime(const char *orig, const char *format,
state = DATETIME_FIRST_HOUR;
break;
}
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid separator between date and time. "
"Found '%c', must be ' ' (empty space).", c);
break;
@@ -222,7 +222,7 @@ blogc_convert_datetime(const char *orig, const char *format,
state = DATETIME_SECOND_HOUR;
break;
}
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid first digit of hours. "
"Found '%c', must be integer >= 0 and <= 2.", c);
break;
@@ -231,7 +231,7 @@ blogc_convert_datetime(const char *orig, const char *format,
if (c >= '0' && c <= '9') {
tmp += c - diff;
if (tmp < 0 || tmp > 23) {
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid hours. Found %d, must be >= 0 and <= 23.",
tmp);
break;
@@ -240,7 +240,7 @@ blogc_convert_datetime(const char *orig, const char *format,
state = DATETIME_FIRST_COLON;
break;
}
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid second digit of hours. "
"Found '%c', must be integer >= 0 and <= 9.", c);
break;
@@ -251,7 +251,7 @@ blogc_convert_datetime(const char *orig, const char *format,
state = DATETIME_FIRST_MINUTE;
break;
}
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid separator between hours and minutes. "
"Found '%c', must be ':'.", c);
break;
@@ -262,7 +262,7 @@ blogc_convert_datetime(const char *orig, const char *format,
state = DATETIME_SECOND_MINUTE;
break;
}
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid first digit of minutes. "
"Found '%c', must be integer >= 0 and <= 5.", c);
break;
@@ -274,7 +274,7 @@ blogc_convert_datetime(const char *orig, const char *format,
// this won't happen because we are restricting the digits
// to 00-59 already, but lets keep the code here for
// reference.
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid minutes. Found %d, must be >= 0 and <= 59.",
tmp);
break;
@@ -283,7 +283,7 @@ blogc_convert_datetime(const char *orig, const char *format,
state = DATETIME_SECOND_COLON;
break;
}
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid second digit of minutes. "
"Found '%c', must be integer >= 0 and <= 9.", c);
break;
@@ -294,7 +294,7 @@ blogc_convert_datetime(const char *orig, const char *format,
state = DATETIME_FIRST_SECOND;
break;
}
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid separator between minutes and seconds. "
"Found '%c', must be ':'.", c);
break;
@@ -305,7 +305,7 @@ blogc_convert_datetime(const char *orig, const char *format,
state = DATETIME_SECOND_SECOND;
break;
}
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid first digit of seconds. "
"Found '%c', must be integer >= 0 and <= 6.", c);
break;
@@ -314,7 +314,7 @@ blogc_convert_datetime(const char *orig, const char *format,
if (c >= '0' && c <= '9') {
tmp += c - diff;
if (tmp < 0 || tmp > 60) {
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid seconds. Found %d, must be >= 0 and <= 60.",
tmp);
break;
@@ -323,7 +323,7 @@ blogc_convert_datetime(const char *orig, const char *format,
state = DATETIME_DONE;
break;
}
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid second digit of seconds. "
"Found '%c', must be integer >= 0 and <= 9.", c);
break;
@@ -355,7 +355,7 @@ blogc_convert_datetime(const char *orig, const char *format,
case DATETIME_SECOND_MINUTE:
case DATETIME_FIRST_SECOND:
case DATETIME_SECOND_SECOND:
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Invalid datetime string. "
"Found '%s', formats allowed are: 'yyyy-mm-dd hh:mm:ss', "
"'yyyy-mm-dd hh:ss', 'yyyy-mm-dd hh' and 'yyyy-mm-dd'.",
@@ -374,13 +374,13 @@ blogc_convert_datetime(const char *orig, const char *format,
char buf[1024];
if (0 == strftime(buf, sizeof(buf), format, &t)) {
- *err = bc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
+ *err = blogc_error_new_printf(BLOGC_WARNING_DATETIME_PARSER,
"Failed to format DATE variable, FORMAT is too long: %s",
format);
return NULL;
}
- return bc_strdup(buf);
+ return sb_strdup(buf);
#endif
}
diff --git a/src/blogc/datetime-parser.h b/src/datetime-parser.h
index 8617ad0..a5087b3 100644
--- a/src/blogc/datetime-parser.h
+++ b/src/datetime-parser.h
@@ -1,6 +1,6 @@
/*
* blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
*
* This program can be distributed under the terms of the BSD License.
* See the file LICENSE.
@@ -9,9 +9,9 @@
#ifndef _DATETIME_H
#define _DATETIME_H
-#include "../common/error.h"
+#include "error.h"
char* blogc_convert_datetime(const char *orig, const char *format,
- bc_error_t **err);
+ blogc_error_t **err);
#endif /* _DATETIME_H */
diff --git a/src/debug.c b/src/debug.c
new file mode 100644
index 0000000..9689028
--- /dev/null
+++ b/src/debug.c
@@ -0,0 +1,80 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#include <stdio.h>
+
+#include "template-parser.h"
+#include "utils.h"
+#include "debug.h"
+
+
+static const char*
+get_operator(blogc_template_stmt_operator_t op)
+{
+ if (op & BLOGC_TEMPLATE_OP_NEQ)
+ return "!=";
+ if (op & BLOGC_TEMPLATE_OP_EQ) {
+ if (op & BLOGC_TEMPLATE_OP_LT)
+ return "<=";
+ else if (op & BLOGC_TEMPLATE_OP_GT)
+ return ">=";
+ return "==";
+ }
+ if (op & BLOGC_TEMPLATE_OP_LT)
+ return "<";
+ else if (op & BLOGC_TEMPLATE_OP_GT)
+ return ">";
+ return "";
+}
+
+
+void
+blogc_debug_template(sb_slist_t *stmts)
+{
+ for (sb_slist_t *tmp = stmts; tmp != NULL; tmp = tmp->next) {
+ blogc_template_stmt_t *data = tmp->data;
+ fprintf(stderr, "DEBUG: <TEMPLATE ");
+ switch (data->type) {
+ case BLOGC_TEMPLATE_IFDEF_STMT:
+ fprintf(stderr, "IFDEF: %s", data->value);
+ break;
+ case BLOGC_TEMPLATE_IFNDEF_STMT:
+ fprintf(stderr, "IFNDEF: %s", data->value);
+ break;
+ case BLOGC_TEMPLATE_IF_STMT:
+ fprintf(stderr, "IF: %s %s %s", data->value,
+ get_operator(data->op), data->value2);
+ break;
+ case BLOGC_TEMPLATE_ELSE_STMT:
+ fprintf(stderr, "ELSE");
+ break;
+ case BLOGC_TEMPLATE_ENDIF_STMT:
+ fprintf(stderr, "ENDIF");
+ break;
+ case BLOGC_TEMPLATE_FOREACH_STMT:
+ fprintf(stderr, "FOREACH: %s", data->value);
+ break;
+ case BLOGC_TEMPLATE_ENDFOREACH_STMT:
+ fprintf(stderr, "ENDFOREACH");
+ break;
+ case BLOGC_TEMPLATE_BLOCK_STMT:
+ fprintf(stderr, "BLOCK: %s", data->value);
+ break;
+ case BLOGC_TEMPLATE_ENDBLOCK_STMT:
+ fprintf(stderr, "ENDBLOCK");
+ break;
+ case BLOGC_TEMPLATE_VARIABLE_STMT:
+ fprintf(stderr, "VARIABLE: %s", data->value);
+ break;
+ case BLOGC_TEMPLATE_CONTENT_STMT:
+ fprintf(stderr, "CONTENT: `%s`", data->value);
+ break;
+ }
+ fprintf(stderr, ">\n");
+ }
+}
diff --git a/src/blogc/debug.h b/src/debug.h
index 6138a91..cd454d4 100644
--- a/src/blogc/debug.h
+++ b/src/debug.h
@@ -1,6 +1,6 @@
/*
* blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
*
* This program can be distributed under the terms of the BSD License.
* See the file LICENSE.
@@ -9,8 +9,8 @@
#ifndef ___DEBUG_H
#define ___DEBUG_H
-#include "../common/utils.h"
+#include "utils.h"
-void blogc_debug_template(bc_slist_t *ast);
+void blogc_debug_template(sb_slist_t *stmts);
#endif /* ___DEBUG_H */
diff --git a/src/common/error.c b/src/error.c
index caf47c3..c238f51 100644
--- a/src/common/error.c
+++ b/src/error.c
@@ -1,6 +1,6 @@
/*
* blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
*
* This program can be distributed under the terms of the BSD License.
* See the file LICENSE.
@@ -13,40 +13,36 @@
#include "utils.h"
-bc_error_t*
-bc_error_new(bc_error_type_t type, const char *msg)
+blogc_error_t*
+blogc_error_new(blogc_error_type_t type, const char *msg)
{
- bc_error_t *err = bc_malloc(sizeof(bc_error_t));
+ blogc_error_t *err = sb_malloc(sizeof(blogc_error_t));
err->type = type;
- err->msg = bc_strdup(msg);
+ err->msg = sb_strdup(msg);
return err;
}
-bc_error_t*
-bc_error_new_printf(bc_error_type_t type, const char *format, ...)
+blogc_error_t*
+blogc_error_new_printf(blogc_error_type_t type, const char *format, ...)
{
- if (format == NULL)
- return bc_error_new(type, "");
va_list ap;
va_start(ap, format);
- char *tmp = bc_strdup_vprintf(format, ap);
+ char *tmp = sb_strdup_vprintf(format, ap);
va_end(ap);
- bc_error_t *rv = bc_error_new(type, tmp);
+ blogc_error_t *rv = blogc_error_new(type, tmp);
free(tmp);
return rv;
}
-bc_error_t*
-bc_error_parser(bc_error_type_t type, const char *src, size_t src_len,
+blogc_error_t*
+blogc_error_parser(blogc_error_type_t type, const char *src, size_t src_len,
size_t current, const char *format, ...)
{
- if (format == NULL)
- return bc_error_new(type, "");
va_list ap;
va_start(ap, format);
- char *msg = bc_strdup_vprintf(format, ap);
+ char *msg = sb_strdup_vprintf(format, ap);
va_end(ap);
size_t lineno = 1;
@@ -87,14 +83,14 @@ bc_error_parser(bc_error_type_t type, const char *src, size_t src_len,
if (lineend <= linestart && src_len >= linestart)
lineend = src_len;
- char *line = bc_strndup(src + linestart, lineend - linestart);
+ char *line = sb_strndup(src + linestart, lineend - linestart);
- bc_error_t *rv = NULL;
+ blogc_error_t *rv = NULL;
if (line[0] == '\0') // "near" message isn't useful if line is empty
- rv = bc_error_new(type, msg);
+ rv = blogc_error_new(type, msg);
else
- rv = bc_error_new_printf(type,
+ rv = blogc_error_new_printf(type,
"%s\nError occurred near line %d, position %d: %s", msg, lineno,
pos, line);
@@ -105,55 +101,36 @@ bc_error_parser(bc_error_type_t type, const char *src, size_t src_len,
}
-// error handling is centralized here for the sake of simplicity :/
void
-bc_error_print(bc_error_t *err, const char *prefix)
+blogc_error_print(blogc_error_t *err)
{
if (err == NULL)
return;
- if (prefix != NULL)
- fprintf(stderr, "%s: ", prefix);
-
switch(err->type) {
- case BC_ERROR_CONFIG_PARSER:
- fprintf(stderr, "error: config-parser: %s\n", err->msg);
- break;
- case BC_ERROR_FILE:
- fprintf(stderr, "error: file: %s\n", err->msg);
- break;
case BLOGC_ERROR_SOURCE_PARSER:
- fprintf(stderr, "error: source: %s\n", err->msg);
+ fprintf(stderr, "blogc: error: source: %s\n", err->msg);
break;
case BLOGC_ERROR_TEMPLATE_PARSER:
- fprintf(stderr, "error: template: %s\n", err->msg);
+ fprintf(stderr, "blogc: error: template: %s\n", err->msg);
break;
case BLOGC_ERROR_LOADER:
- fprintf(stderr, "error: loader: %s\n", err->msg);
- break;
- case BLOGC_WARNING_DATETIME_PARSER:
- fprintf(stderr, "warning: datetime: %s\n", err->msg);
- break;
- case BLOGC_MAKE_ERROR_SETTINGS:
- fprintf(stderr, "error: settings: %s\n", err->msg);
+ fprintf(stderr, "blogc: error: loader: %s\n", err->msg);
break;
- case BLOGC_MAKE_ERROR_EXEC:
- fprintf(stderr, "error: exec: %s\n", err->msg);
+ case BLOGC_ERROR_FILE:
+ fprintf(stderr, "blogc: error: file: %s\n", err->msg);
break;
- case BLOGC_MAKE_ERROR_ATOM:
- fprintf(stderr, "error: atom: %s\n", err->msg);
- break;
- case BLOGC_MAKE_ERROR_UTILS:
- fprintf(stderr, "error: utils: %s\n", err->msg);
+ case BLOGC_WARNING_DATETIME_PARSER:
+ fprintf(stderr, "blogc: warning: datetime: %s\n", err->msg);
break;
default:
- fprintf(stderr, "error: %s\n", err->msg);
+ fprintf(stderr, "blogc: error: %s\n", err->msg);
}
}
void
-bc_error_free(bc_error_t *err)
+blogc_error_free(blogc_error_t *err)
{
if (err == NULL)
return;
diff --git a/src/error.h b/src/error.h
new file mode 100644
index 0000000..31fbaf2
--- /dev/null
+++ b/src/error.h
@@ -0,0 +1,34 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#ifndef _ERROR_H
+#define _ERROR_H
+
+#include <stddef.h>
+
+typedef enum {
+ BLOGC_ERROR_SOURCE_PARSER = 1,
+ BLOGC_ERROR_TEMPLATE_PARSER,
+ BLOGC_ERROR_LOADER,
+ BLOGC_ERROR_FILE,
+ BLOGC_WARNING_DATETIME_PARSER,
+} blogc_error_type_t;
+
+typedef struct {
+ char *msg;
+ blogc_error_type_t type;
+} blogc_error_t;
+
+blogc_error_t* blogc_error_new(blogc_error_type_t type, const char *msg);
+blogc_error_t* blogc_error_new_printf(blogc_error_type_t type, const char *format, ...);
+blogc_error_t* blogc_error_parser(blogc_error_type_t type, const char *src,
+ size_t src_len, size_t current, const char *format, ...);
+void blogc_error_print(blogc_error_t *err);
+void blogc_error_free(blogc_error_t *err);
+
+#endif /* _ERROR_H */
diff --git a/src/file.c b/src/file.c
new file mode 100644
index 0000000..dc43056
--- /dev/null
+++ b/src/file.c
@@ -0,0 +1,81 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include "file.h"
+#include "error.h"
+#include "utf8.h"
+#include "utils.h"
+
+// this would belong to loader.c, but we need it in a separated file to be
+// able to mock it when unit testing the loader functions.
+
+
+char*
+blogc_file_get_contents(const char *path, size_t *len, blogc_error_t **err)
+{
+ if (path == NULL || err == NULL || *err != NULL)
+ return NULL;
+
+ *len = 0;
+ FILE *fp = fopen(path, "r");
+
+ if (fp == NULL) {
+ int tmp_errno = errno;
+ *err = blogc_error_new_printf(BLOGC_ERROR_FILE,
+ "Failed to open file (%s): %s", path, strerror(tmp_errno));
+ return NULL;
+ }
+
+ sb_string_t *str = sb_string_new();
+ char buffer[BLOGC_FILE_CHUNK_SIZE];
+ char *tmp;
+
+ while (!feof(fp)) {
+ size_t read_len = fread(buffer, sizeof(char), BLOGC_FILE_CHUNK_SIZE, fp);
+
+ tmp = buffer;
+
+ if (str->len == 0 && read_len > 0) {
+ // skipping BOM before validation, for performance. should be safe
+ // enough
+ size_t skip = blogc_utf8_skip_bom((uint8_t*) buffer, read_len);
+ read_len -= skip;
+ tmp += skip;
+ }
+
+ *len += read_len;
+ sb_string_append_len(str, tmp, read_len);
+ }
+ fclose(fp);
+
+ if (!blogc_utf8_validate_str(str)) {
+ *err = blogc_error_new_printf(BLOGC_ERROR_FILE,
+ "File content is not valid UTF-8: %s", path);
+ sb_string_free(str, true);
+ return NULL;
+ }
+
+ return sb_string_free(str, false);
+}
+
+
+int
+blogc_fprintf(FILE *stream, const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ int rv = vfprintf(stream, format, ap);
+ va_end(ap);
+ return rv;
+}
diff --git a/src/file.h b/src/file.h
new file mode 100644
index 0000000..d2c4390
--- /dev/null
+++ b/src/file.h
@@ -0,0 +1,21 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#ifndef _FILE_H
+#define _FILE_H
+
+#include <stddef.h>
+#include <stdio.h>
+#include "error.h"
+
+#define BLOGC_FILE_CHUNK_SIZE 1024
+
+char* blogc_file_get_contents(const char *path, size_t *len, blogc_error_t **err);
+int blogc_fprintf(FILE *stream, const char *format, ...);
+
+#endif /* _FILE_H */
diff --git a/src/loader.c b/src/loader.c
new file mode 100644
index 0000000..bd3251e
--- /dev/null
+++ b/src/loader.c
@@ -0,0 +1,212 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#include <math.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "file.h"
+#include "source-parser.h"
+#include "template-parser.h"
+#include "loader.h"
+#include "error.h"
+#include "utils.h"
+
+
+char*
+blogc_get_filename(const char *f)
+{
+ if (f == NULL)
+ return NULL;
+
+ if (strlen(f) == 0)
+ return NULL;
+
+ char *filename = sb_strdup(f);
+
+ // keep a pointer to original string
+ char *tmp = filename;
+
+ bool removed_dot = false;
+ for (int i = strlen(tmp); i >= 0 ; i--) {
+
+ // remove last extension
+ if (!removed_dot && tmp[i] == '.') {
+ tmp[i] = '\0';
+ removed_dot = true;
+ continue;
+ }
+
+ if (tmp[i] == '/' || tmp[i] == '\\') {
+ tmp += i + 1;
+ break;
+ }
+ }
+
+ char *final_filename = sb_strdup(tmp);
+ free(filename);
+
+ return final_filename;
+}
+
+
+sb_slist_t*
+blogc_template_parse_from_file(const char *f, blogc_error_t **err)
+{
+ if (err == NULL || *err != NULL)
+ return NULL;
+ size_t len;
+ char *s = blogc_file_get_contents(f, &len, err);
+ if (s == NULL)
+ return NULL;
+ sb_slist_t *rv = blogc_template_parse(s, len, err);
+ free(s);
+ return rv;
+}
+
+
+sb_trie_t*
+blogc_source_parse_from_file(const char *f, blogc_error_t **err)
+{
+ if (err == NULL || *err != NULL)
+ return NULL;
+ size_t len;
+ char *s = blogc_file_get_contents(f, &len, err);
+ if (s == NULL)
+ return NULL;
+ sb_trie_t *rv = blogc_source_parse(s, len, err);
+
+ // set FILENAME variable
+ if (rv != NULL) {
+ char *filename = blogc_get_filename(f);
+ if (filename != NULL)
+ sb_trie_insert(rv, "FILENAME", filename);
+ }
+
+ free(s);
+ return rv;
+}
+
+
+sb_slist_t*
+blogc_source_parse_from_files(sb_trie_t *conf, sb_slist_t *l, blogc_error_t **err)
+{
+ blogc_error_t *tmp_err = NULL;
+ sb_slist_t *rv = NULL;
+ unsigned int with_date = 0;
+
+ const char *filter_tag = sb_trie_lookup(conf, "FILTER_TAG");
+ const char *filter_page = sb_trie_lookup(conf, "FILTER_PAGE");
+ const char *filter_per_page = sb_trie_lookup(conf, "FILTER_PER_PAGE");
+
+ long page = strtol(filter_page != NULL ? filter_page : "", NULL, 10);
+ if (page <= 0)
+ page = 1;
+ long per_page = strtol(filter_per_page != NULL ? filter_per_page : "10",
+ NULL, 10);
+ if (per_page <= 0)
+ per_page = 10;
+
+ // poor man's pagination
+ unsigned int start = (page - 1) * per_page;
+ unsigned int end = start + per_page;
+ unsigned int counter = 0;
+
+ for (sb_slist_t *tmp = l; tmp != NULL; tmp = tmp->next) {
+ char *f = tmp->data;
+ sb_trie_t *s = blogc_source_parse_from_file(f, &tmp_err);
+ if (s == NULL) {
+ *err = blogc_error_new_printf(BLOGC_ERROR_LOADER,
+ "An error occurred while parsing source file: %s\n\n%s",
+ f, tmp_err->msg);
+ blogc_error_free(tmp_err);
+ tmp_err = NULL;
+ sb_slist_free_full(rv, (sb_free_func_t) sb_trie_free);
+ rv = NULL;
+ break;
+ }
+ if (filter_tag != NULL) {
+ const char *tags_str = sb_trie_lookup(s, "TAGS");
+ // if user wants to filter by tag and no tag is provided, skip it
+ if (tags_str == NULL) {
+ sb_trie_free(s);
+ continue;
+ }
+ char **tags = sb_str_split(tags_str, ' ', 0);
+ bool found = false;
+ for (unsigned int i = 0; tags[i] != NULL; i++) {
+ if (tags[i][0] == '\0')
+ continue;
+ if (0 == strcmp(tags[i], filter_tag))
+ found = true;
+ }
+ sb_strv_free(tags);
+ if (!found) {
+ sb_trie_free(s);
+ continue;
+ }
+ }
+ if (filter_page != NULL) {
+ if (counter < start || counter >= end) {
+ counter++;
+ sb_trie_free(s);
+ continue;
+ }
+ counter++;
+ }
+ if (sb_trie_lookup(s, "DATE") != NULL)
+ with_date++;
+ rv = sb_slist_append(rv, s);
+ }
+
+ if (with_date > 0 && with_date < sb_slist_length(rv))
+ // fatal error, maybe?
+ blogc_fprintf(stderr,
+ "blogc: warning: 'DATE' variable provided for at least one source "
+ "file, but not for all source files. This means that you may get "
+ "wrong values for 'DATE_FIRST' and 'DATE_LAST' variables.\n");
+
+ bool first = true;
+ for (sb_slist_t *tmp = rv; tmp != NULL; tmp = tmp->next) {
+ sb_trie_t *s = tmp->data;
+ if (first) {
+ const char *val = sb_trie_lookup(s, "DATE");
+ if (val != NULL)
+ sb_trie_insert(conf, "DATE_FIRST", sb_strdup(val));
+ val = sb_trie_lookup(s, "FILENAME");
+ if (val != NULL)
+ sb_trie_insert(conf, "FILENAME_FIRST", sb_strdup(val));
+ first = false;
+ }
+ if (tmp->next == NULL) { // last
+ const char *val = sb_trie_lookup(s, "DATE");
+ if (val != NULL)
+ sb_trie_insert(conf, "DATE_LAST", sb_strdup(val));
+ val = sb_trie_lookup(s, "FILENAME");
+ if (val != NULL)
+ sb_trie_insert(conf, "FILENAME_LAST", sb_strdup(val));
+ }
+ }
+
+ if (filter_page != NULL) {
+ unsigned int last_page = ceilf(((float) counter) / per_page);
+ sb_trie_insert(conf, "CURRENT_PAGE", sb_strdup_printf("%ld", page));
+ if (page > 1)
+ sb_trie_insert(conf, "PREVIOUS_PAGE", sb_strdup_printf("%ld", page - 1));
+ if (page < last_page)
+ sb_trie_insert(conf, "NEXT_PAGE", sb_strdup_printf("%ld", page + 1));
+ if (sb_slist_length(rv) > 0)
+ sb_trie_insert(conf, "FIRST_PAGE", sb_strdup("1"));
+ if (last_page > 0)
+ sb_trie_insert(conf, "LAST_PAGE", sb_strdup_printf("%d", last_page));
+ }
+
+ return rv;
+}
diff --git a/src/loader.h b/src/loader.h
new file mode 100644
index 0000000..32b58be
--- /dev/null
+++ b/src/loader.h
@@ -0,0 +1,21 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#ifndef _LOADER_H
+#define _LOADER_H
+
+#include "error.h"
+#include "utils.h"
+
+char* blogc_get_filename(const char *f);
+sb_slist_t* blogc_template_parse_from_file(const char *f, blogc_error_t **err);
+sb_trie_t* blogc_source_parse_from_file(const char *f, blogc_error_t **err);
+sb_slist_t* blogc_source_parse_from_files(sb_trie_t *conf, sb_slist_t *l,
+ blogc_error_t **err);
+
+#endif /* _LOADER_H */
diff --git a/src/blogc/renderer.c b/src/renderer.c
index a91d105..27e92bd 100644
--- a/src/blogc/renderer.c
+++ b/src/renderer.c
@@ -1,112 +1,77 @@
/*
* blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
*
* This program can be distributed under the terms of the BSD License.
* See the file LICENSE.
*/
+#include <errno.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "datetime-parser.h"
-#include "funcvars.h"
+#include "error.h"
#include "template-parser.h"
#include "renderer.h"
-#include "../common/error.h"
-#include "../common/utils.h"
+#include "utils.h"
const char*
-blogc_get_variable(const char *name, bc_trie_t *global, bc_trie_t *local)
+blogc_get_variable(const char *name, sb_trie_t *global, sb_trie_t *local)
{
const char *rv = NULL;
if (local != NULL) {
- rv = bc_trie_lookup(local, name);
+ rv = sb_trie_lookup(local, name);
if (rv != NULL)
return rv;
}
if (global != NULL)
- rv = bc_trie_lookup(global, name);
+ rv = sb_trie_lookup(global, name);
return rv;
}
char*
-blogc_format_date(const char *date, bc_trie_t *global, bc_trie_t *local)
+blogc_format_date(const char *date, sb_trie_t *global, sb_trie_t *local)
{
const char *date_format = blogc_get_variable("DATE_FORMAT", global, local);
if (date == NULL)
return NULL;
if (date_format == NULL)
- return bc_strdup(date);
+ return sb_strdup(date);
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *rv = blogc_convert_datetime(date, date_format, &err);
if (err != NULL) {
- bc_error_print(err, "blogc");
- bc_error_free(err);
- return bc_strdup(date);
+ blogc_error_print(err);
+ blogc_error_free(err);
+ return sb_strdup(date);
}
return rv;
}
-static char*
-foreach_value_variable(const char *name, const char *item)
-{
- if (name == NULL || item == NULL)
- return NULL;
-
- char *rv = bc_strdup_printf("%s__%s", name, item);
- int diff = 'a' - 'A'; // just to avoid magic numbers
- for (size_t i = 0; rv[i] != '\0'; i++) {
- if ((rv[i] >= '0' && rv[i] <= '9') ||
- (rv[i] >= 'A' && rv[i] <= 'Z')) {
- continue;
- }
- if (rv[i] >= 'a' && rv[i] <= 'z') {
- rv[i] -= diff;
- continue;
- }
- rv[i] = '_';
- }
-
- return rv;
-}
-
-
char*
-blogc_format_variable(const char *name, bc_trie_t *global, bc_trie_t *local,
- const char *foreach_name, bc_slist_t *foreach_var)
+blogc_format_variable(const char *name, sb_trie_t *global, sb_trie_t *local,
+ sb_slist_t *foreach_var)
{
// if used asked for a variable that exists, just return it right away
const char *value = blogc_get_variable(name, global, local);
if (value != NULL)
- return bc_strdup(value);
+ return sb_strdup(value);
- // do the same for special foreach variables
+ // do the same for special variable 'FOREACH_ITEM'
if (0 == strcmp(name, "FOREACH_ITEM")) {
if (foreach_var != NULL && foreach_var->data != NULL) {
- return bc_strdup(foreach_var->data);
- }
- return NULL;
- }
- if (0 == strcmp(name, "FOREACH_VALUE")) {
- if (foreach_name != NULL && foreach_var != NULL && foreach_var->data != NULL) {
- char *value_var = foreach_value_variable(foreach_name, foreach_var->data);
- if (value_var != NULL) {
- value = blogc_get_variable(value_var, global, local);
- free(value_var);
- return bc_strdup(value);
- }
+ return sb_strdup(foreach_var->data);
}
return NULL;
}
- char *var = bc_strdup(name);
+ char *var = sb_strdup(name);
size_t i;
size_t last = strlen(var);
@@ -117,11 +82,11 @@ blogc_format_variable(const char *name, bc_trie_t *global, bc_trie_t *local,
for (i = last - 1; i > 0 && var[i] >= '0' && var[i] <= '9'; i--);
if (var[i] == '_' && (i + 1) < last) { // var ends with '_[0-9]+'
- char *endptr;
- len = strtol(var + i + 1, &endptr, 10);
- if (*endptr != '\0') {
- fprintf(stderr, "warning: invalid variable size for '%s', "
- "ignoring.\n", var);
+ // passing NULL to endptr because our string was previously validated
+ len = strtol(var + i + 1, NULL, 10);
+ if (errno != 0) {
+ fprintf(stderr, "warning: invalid variable size for '%s' (%s), "
+ "ignoring.\n", var, strerror(errno));
len = -1;
}
else {
@@ -131,27 +96,16 @@ blogc_format_variable(const char *name, bc_trie_t *global, bc_trie_t *local,
bool must_format = false;
- if (bc_str_ends_with(var, "_FORMATTED")) {
+ if (sb_str_ends_with(var, "_FORMATTED")) {
var[strlen(var) - 10] = '\0';
must_format = true;
}
if ((0 == strcmp(var, "FOREACH_ITEM")) &&
- (foreach_var != NULL && foreach_var->data != NULL)) {
+ (foreach_var != NULL && foreach_var->data != NULL))
value = foreach_var->data;
- }
- else if ((0 == strcmp(var, "FOREACH_VALUE")) &&
- (foreach_name != NULL && foreach_var != NULL && foreach_var->data != NULL)) {
- char *value_var = foreach_value_variable(foreach_name, foreach_var->data);
- if (value_var != NULL) {
- value = blogc_get_variable(value_var, global, local);
- free(value_var);
- }
- }
- else {
- blogc_funcvars_eval(global, var);
+ else
value = blogc_get_variable(var, global, local);
- }
if (value == NULL) {
free(var);
@@ -161,23 +115,23 @@ blogc_format_variable(const char *name, bc_trie_t *global, bc_trie_t *local,
char *rv = NULL;
if (must_format) {
- if (bc_str_starts_with(name, "DATE_")) {
+ if (sb_str_starts_with(name, "DATE_")) {
rv = blogc_format_date(value, global, local);
}
else {
fprintf(stderr, "warning: no formatter found for '%s', "
"ignoring.\n", var);
- rv = bc_strdup(value);
+ rv = sb_strdup(value);
}
}
else {
- rv = bc_strdup(value);
+ rv = sb_strdup(value);
}
free(var);
if (len > 0) {
- char *tmp = bc_strndup(rv, len);
+ char *tmp = sb_strndup(rv, len);
free(rv);
rv = tmp;
}
@@ -186,19 +140,19 @@ blogc_format_variable(const char *name, bc_trie_t *global, bc_trie_t *local,
}
-bc_slist_t*
-blogc_split_list_variable(const char *name, bc_trie_t *global, bc_trie_t *local)
+sb_slist_t*
+blogc_split_list_variable(const char *name, sb_trie_t *global, sb_trie_t *local)
{
const char *value = blogc_get_variable(name, global, local);
if (value == NULL)
return NULL;
- bc_slist_t *rv = NULL;
+ sb_slist_t *rv = NULL;
- char **tmp = bc_str_split(value, ' ', 0);
- for (size_t i = 0; tmp[i] != NULL; i++) {
+ char **tmp = sb_str_split(value, ' ', 0);
+ for (unsigned int i = 0; tmp[i] != NULL; i++) {
if (tmp[i][0] != '\0') // ignore empty strings
- rv = bc_slist_append(rv, tmp[i]);
+ rv = sb_slist_append(rv, tmp[i]);
else
free(tmp[i]);
}
@@ -209,27 +163,25 @@ blogc_split_list_variable(const char *name, bc_trie_t *global, bc_trie_t *local)
char*
-blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_slist_t *listing_entries,
- bc_trie_t *config, bool listing)
+blogc_render(sb_slist_t *tmpl, sb_slist_t *sources, sb_trie_t *config, bool listing)
{
if (tmpl == NULL)
return NULL;
- bc_slist_t *current_source = NULL;
- bc_slist_t *listing_start = NULL;
+ sb_slist_t *current_source = NULL;
+ sb_slist_t *listing_start = NULL;
- bc_string_t *str = bc_string_new();
+ sb_string_t *str = sb_string_new();
- bc_trie_t *tmp_source = NULL;
+ sb_trie_t *tmp_source = NULL;
char *config_value = NULL;
char *defined = NULL;
- size_t if_count = 0;
+ unsigned int if_count = 0;
- char *foreach_name = NULL;
- bc_slist_t *foreach_var = NULL;
- bc_slist_t *foreach_var_start = NULL;
- bc_slist_t *foreach_start = NULL;
+ sb_slist_t *foreach_var = NULL;
+ sb_slist_t *foreach_var_start = NULL;
+ sb_slist_t *foreach_start = NULL;
bool if_not = false;
bool inside_block = false;
@@ -238,87 +190,55 @@ blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_slist_t *listing_entries,
int cmp = 0;
- bc_slist_t *tmp = tmpl;
- bc_slist_t *current_listing_entry = listing_entries;
+ sb_slist_t *tmp = tmpl;
while (tmp != NULL) {
- blogc_template_node_t *node = tmp->data;
+ blogc_template_stmt_t *stmt = tmp->data;
- switch (node->type) {
+ switch (stmt->type) {
- case BLOGC_TEMPLATE_NODE_CONTENT:
- if (node->data[0] != NULL)
- bc_string_append(str, node->data[0]);
+ case BLOGC_TEMPLATE_CONTENT_STMT:
+ if (stmt->value != NULL)
+ sb_string_append(str, stmt->value);
break;
- case BLOGC_TEMPLATE_NODE_BLOCK:
+ case BLOGC_TEMPLATE_BLOCK_STMT:
inside_block = true;
if_count = 0;
- if (0 == strcmp("entry", node->data[0])) {
+ if (0 == strcmp("entry", stmt->value)) {
if (listing) {
// we can just skip anything and walk until the next
// 'endblock'
- while (node->type != BLOGC_TEMPLATE_NODE_ENDBLOCK) {
+ while (stmt->type != BLOGC_TEMPLATE_ENDBLOCK_STMT) {
tmp = tmp->next;
- node = tmp->data;
+ stmt = tmp->data;
}
break;
}
current_source = sources;
- tmp_source = current_source != NULL ? current_source->data : NULL;
- }
- if (0 == strcmp("listing_entry", node->data[0])) {
- bc_trie_t *listing_entry = NULL;
- if (current_listing_entry != NULL) {
- listing_entry = current_listing_entry->data;
- current_listing_entry = current_listing_entry->next;
- }
- if (listing_entry == NULL || !listing) {
- // we can just skip anything and walk until the next
- // 'endblock'
- while (node->type != BLOGC_TEMPLATE_NODE_ENDBLOCK) {
- tmp = tmp->next;
- node = tmp->data;
- }
- break;
- }
- current_source = NULL;
- tmp_source = listing_entry;
+ tmp_source = current_source->data;
}
- else if ((0 == strcmp("listing", node->data[0])) ||
- (0 == strcmp("listing_empty", node->data[0])) ||
- (0 == strcmp("listing_once", node->data[0]))) {
+ else if ((0 == strcmp("listing", stmt->value)) ||
+ (0 == strcmp("listing_once", stmt->value))) {
if (!listing) {
// we can just skip anything and walk until the next
// 'endblock'
- while (node->type != BLOGC_TEMPLATE_NODE_ENDBLOCK) {
+ while (stmt->type != BLOGC_TEMPLATE_ENDBLOCK_STMT) {
tmp = tmp->next;
- node = tmp->data;
+ stmt = tmp->data;
}
break;
}
}
- if (0 == strcmp("listing_empty", node->data[0])) {
- if (sources != NULL) {
-
- // we can just skip anything and walk until the next
- // 'endblock'
- while (node->type != BLOGC_TEMPLATE_NODE_ENDBLOCK) {
- tmp = tmp->next;
- node = tmp->data;
- }
- break;
- }
- }
- if (0 == strcmp("listing", node->data[0])) {
+ if (0 == strcmp("listing", stmt->value)) {
if (sources == NULL) {
// we can just skip anything and walk until the next
// 'endblock'
- while (node->type != BLOGC_TEMPLATE_NODE_ENDBLOCK) {
+ while (stmt->type != BLOGC_TEMPLATE_ENDBLOCK_STMT) {
tmp = tmp->next;
- node = tmp->data;
+ stmt = tmp->data;
}
break;
}
@@ -326,16 +246,16 @@ blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_slist_t *listing_entries,
listing_start = tmp;
current_source = sources;
}
- tmp_source = current_source != NULL ? current_source->data : NULL;
+ tmp_source = current_source->data;
}
break;
- case BLOGC_TEMPLATE_NODE_VARIABLE:
- if (node->data[0] != NULL) {
- config_value = blogc_format_variable(node->data[0],
- config, inside_block ? tmp_source : NULL, foreach_name, foreach_var);
+ case BLOGC_TEMPLATE_VARIABLE_STMT:
+ if (stmt->value != NULL) {
+ config_value = blogc_format_variable(stmt->value,
+ config, inside_block ? tmp_source : NULL, foreach_var);
if (config_value != NULL) {
- bc_string_append(str, config_value);
+ sb_string_append(str, config_value);
free(config_value);
config_value = NULL;
break;
@@ -343,7 +263,7 @@ blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_slist_t *listing_entries,
}
break;
- case BLOGC_TEMPLATE_NODE_ENDBLOCK:
+ case BLOGC_TEMPLATE_ENDBLOCK_STMT:
inside_block = false;
if (listing_start != NULL && current_source != NULL) {
current_source = current_source->next;
@@ -356,46 +276,46 @@ blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_slist_t *listing_entries,
}
break;
- case BLOGC_TEMPLATE_NODE_IFNDEF:
+ case BLOGC_TEMPLATE_IFNDEF_STMT:
if_not = true;
- case BLOGC_TEMPLATE_NODE_IF:
- case BLOGC_TEMPLATE_NODE_IFDEF:
+ case BLOGC_TEMPLATE_IF_STMT:
+ case BLOGC_TEMPLATE_IFDEF_STMT:
if_count = 0;
defined = NULL;
- if (node->data[0] != NULL)
- defined = blogc_format_variable(node->data[0], config,
- inside_block ? tmp_source : NULL, foreach_name, foreach_var);
+ if (stmt->value != NULL)
+ defined = blogc_format_variable(stmt->value, config,
+ inside_block ? tmp_source : NULL, foreach_var);
evaluate = false;
- if (node->op != 0) {
+ if (stmt->op != 0) {
// Strings that start with a '"' are actually strings, the
// others are meant to be looked up as a second variable
// check.
char *defined2 = NULL;
- if (node->data[1] != NULL) {
- if ((strlen(node->data[1]) >= 2) &&
- (node->data[1][0] == '"') &&
- (node->data[1][strlen(node->data[1]) - 1] == '"'))
+ if (stmt->value2 != NULL) {
+ if ((strlen(stmt->value2) >= 2) &&
+ (stmt->value2[0] == '"') &&
+ (stmt->value2[strlen(stmt->value2) - 1] == '"'))
{
- defined2 = bc_strndup(node->data[1] + 1,
- strlen(node->data[1]) - 2);
+ defined2 = sb_strndup(stmt->value2 + 1,
+ strlen(stmt->value2) - 2);
}
else {
- defined2 = blogc_format_variable(node->data[1],
+ defined2 = blogc_format_variable(stmt->value2,
config, inside_block ? tmp_source : NULL,
- foreach_name, foreach_var);
+ foreach_var);
}
}
if (defined != NULL && defined2 != NULL) {
cmp = strcmp(defined, defined2);
- if (cmp != 0 && node->op & BLOGC_TEMPLATE_OP_NEQ)
+ if (cmp != 0 && stmt->op & BLOGC_TEMPLATE_OP_NEQ)
evaluate = true;
- else if (cmp == 0 && node->op & BLOGC_TEMPLATE_OP_EQ)
+ else if (cmp == 0 && stmt->op & BLOGC_TEMPLATE_OP_EQ)
evaluate = true;
- else if (cmp < 0 && node->op & BLOGC_TEMPLATE_OP_LT)
+ else if (cmp < 0 && stmt->op & BLOGC_TEMPLATE_OP_LT)
evaluate = true;
- else if (cmp > 0 && node->op & BLOGC_TEMPLATE_OP_GT)
+ else if (cmp > 0 && stmt->op & BLOGC_TEMPLATE_OP_GT)
evaluate = true;
}
@@ -414,15 +334,15 @@ blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_slist_t *listing_entries,
// skip as well.
while (1) {
tmp = tmp->next;
- node = tmp->data;
- if ((node->type == BLOGC_TEMPLATE_NODE_IF) ||
- (node->type == BLOGC_TEMPLATE_NODE_IFDEF) ||
- (node->type == BLOGC_TEMPLATE_NODE_IFNDEF))
+ stmt = tmp->data;
+ if ((stmt->type == BLOGC_TEMPLATE_IF_STMT) ||
+ (stmt->type == BLOGC_TEMPLATE_IFDEF_STMT) ||
+ (stmt->type == BLOGC_TEMPLATE_IFNDEF_STMT))
{
if_count++;
continue;
}
- if ((node->type == BLOGC_TEMPLATE_NODE_ELSE) &&
+ if ((stmt->type == BLOGC_TEMPLATE_ELSE_STMT) &&
(if_count == 0))
{
// this is somewhat complex. only an else statement
@@ -433,7 +353,7 @@ blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_slist_t *listing_entries,
valid_else = true;
break;
}
- if (node->type == BLOGC_TEMPLATE_NODE_ENDIF) {
+ if (stmt->type == BLOGC_TEMPLATE_ENDIF_STMT) {
if (if_count > 0) {
if_count--;
continue;
@@ -442,15 +362,12 @@ blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_slist_t *listing_entries,
}
}
}
- else {
- valid_else = false;
- }
free(defined);
defined = NULL;
if_not = false;
break;
- case BLOGC_TEMPLATE_NODE_ELSE:
+ case BLOGC_TEMPLATE_ELSE_STMT:
if_count = 0;
if (!valid_else) {
@@ -459,17 +376,17 @@ blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_slist_t *listing_entries,
// skip as well.
while (1) {
tmp = tmp->next;
- node = tmp->data;
- if ((node->type == BLOGC_TEMPLATE_NODE_IF) ||
- (node->type == BLOGC_TEMPLATE_NODE_IFDEF) ||
- (node->type == BLOGC_TEMPLATE_NODE_IFNDEF))
+ stmt = tmp->data;
+ if ((stmt->type == BLOGC_TEMPLATE_IF_STMT) ||
+ (stmt->type == BLOGC_TEMPLATE_IFDEF_STMT) ||
+ (stmt->type == BLOGC_TEMPLATE_IFNDEF_STMT))
{
if_count++;
continue;
}
// no need to handle else statements here, because every
// if should have an endif.
- if (node->type == BLOGC_TEMPLATE_NODE_ENDIF) {
+ if (stmt->type == BLOGC_TEMPLATE_ENDIF_STMT) {
if (if_count > 0) {
if_count--;
continue;
@@ -481,7 +398,7 @@ blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_slist_t *listing_entries,
valid_else = false;
break;
- case BLOGC_TEMPLATE_NODE_ENDIF:
+ case BLOGC_TEMPLATE_ENDIF_STMT:
// any endif statement should invalidate valid_else, to avoid
// propagation to outter conditionals.
valid_else = false;
@@ -489,14 +406,13 @@ blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_slist_t *listing_entries,
if_count--;
break;
- case BLOGC_TEMPLATE_NODE_FOREACH:
+ case BLOGC_TEMPLATE_FOREACH_STMT:
if (foreach_var_start == NULL) {
- if (node->data[0] != NULL)
- foreach_var_start = blogc_split_list_variable(node->data[0],
+ if (stmt->value != NULL)
+ foreach_var_start = blogc_split_list_variable(stmt->value,
config, inside_block ? tmp_source : NULL);
if (foreach_var_start != NULL) {
- foreach_name = bc_strdup(node->data[0]);
foreach_var = foreach_var_start;
foreach_start = tmp;
}
@@ -504,9 +420,9 @@ blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_slist_t *listing_entries,
// we can just skip anything and walk until the next
// 'endforeach'
- while (node->type != BLOGC_TEMPLATE_NODE_ENDFOREACH) {
+ while (stmt->type != BLOGC_TEMPLATE_ENDFOREACH_STMT) {
tmp = tmp->next;
- node = tmp->data;
+ stmt = tmp->data;
}
break;
}
@@ -514,12 +430,11 @@ blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_slist_t *listing_entries,
if (foreach_var == NULL) {
foreach_start = tmp;
- foreach_name = bc_strdup(node->data[0]);
foreach_var = foreach_var_start;
}
break;
- case BLOGC_TEMPLATE_NODE_ENDFOREACH:
+ case BLOGC_TEMPLATE_ENDFOREACH_STMT:
if (foreach_start != NULL && foreach_var != NULL) {
foreach_var = foreach_var->next;
if (foreach_var != NULL) {
@@ -528,10 +443,8 @@ blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_slist_t *listing_entries,
}
}
foreach_start = NULL;
- bc_slist_free_full(foreach_var_start, free);
+ sb_slist_free_full(foreach_var_start, free);
foreach_var_start = NULL;
- free(foreach_name);
- foreach_name = NULL;
break;
}
tmp = tmp->next;
@@ -540,5 +453,5 @@ blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_slist_t *listing_entries,
// no need to free temporary variables here. the template parser makes sure
// that templates are sane and statements are closed.
- return bc_string_free(str, false);
+ return sb_string_free(str, false);
}
diff --git a/src/renderer.h b/src/renderer.h
new file mode 100644
index 0000000..2982ee8
--- /dev/null
+++ b/src/renderer.h
@@ -0,0 +1,24 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#ifndef _RENDERER_H
+#define _RENDERER_H
+
+#include <stdbool.h>
+#include "utils.h"
+
+const char* blogc_get_variable(const char *name, sb_trie_t *global, sb_trie_t *local);
+char* blogc_format_date(const char *date, sb_trie_t *global, sb_trie_t *local);
+char* blogc_format_variable(const char *name, sb_trie_t *global, sb_trie_t *local,
+ sb_slist_t *foreach_var);
+sb_slist_t* blogc_split_list_variable(const char *name, sb_trie_t *global,
+ sb_trie_t *local);
+char* blogc_render(sb_slist_t *tmpl, sb_slist_t *sources, sb_trie_t *config,
+ bool listing);
+
+#endif /* _RENDERER_H */
diff --git a/src/blogc/source-parser.c b/src/source-parser.c
index 13df9e3..349d3f7 100644
--- a/src/blogc/source-parser.c
+++ b/src/source-parser.c
@@ -1,6 +1,6 @@
/*
* blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
*
* This program can be distributed under the terms of the BSD License.
* See the file LICENSE.
@@ -11,9 +11,8 @@
#include "content-parser.h"
#include "source-parser.h"
-#include "toctree.h"
-#include "../common/error.h"
-#include "../common/utils.h"
+#include "error.h"
+#include "utils.h"
typedef enum {
@@ -27,21 +26,19 @@ typedef enum {
} blogc_source_parser_state_t;
-bc_trie_t*
-blogc_source_parse(const char *src, size_t src_len, int toctree_maxdepth,
- bc_error_t **err)
+sb_trie_t*
+blogc_source_parse(const char *src, size_t src_len, blogc_error_t **err)
{
if (err == NULL || *err != NULL)
return NULL;
size_t current = 0;
size_t start = 0;
- size_t end_excerpt = 0;
char *key = NULL;
char *tmp = NULL;
char *content = NULL;
- bc_trie_t *rv = bc_trie_new(free);
+ sb_trie_t *rv = sb_trie_new(free);
blogc_source_parser_state_t state = SOURCE_START;
@@ -62,7 +59,7 @@ blogc_source_parse(const char *src, size_t src_len, int toctree_maxdepth,
state = SOURCE_SEPARATOR;
break;
}
- *err = bc_error_parser(BLOGC_ERROR_SOURCE_PARSER, src, src_len,
+ *err = blogc_error_parser(BLOGC_ERROR_SOURCE_PARSER, src, src_len,
current,
"Can't find a configuration key or the content separator.");
break;
@@ -71,7 +68,7 @@ blogc_source_parse(const char *src, size_t src_len, int toctree_maxdepth,
if ((c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_')
break;
if (c == ':') {
- key = bc_strndup(src + start, current - start);
+ key = sb_strndup(src + start, current - start);
if (((current - start == 8) &&
(0 == strncmp("FILENAME", src + start, 8))) ||
((current - start == 7) &&
@@ -95,7 +92,7 @@ blogc_source_parse(const char *src, size_t src_len, int toctree_maxdepth,
((current - start == 13) &&
(0 == strncmp("BLOGC_VERSION", src + start, 13))))
{
- *err = bc_error_new_printf(BLOGC_ERROR_SOURCE_PARSER,
+ *err = blogc_error_new_printf(BLOGC_ERROR_SOURCE_PARSER,
"'%s' variable is forbidden in source files. It will "
"be set for you by the compiler.", key);
break;
@@ -103,7 +100,7 @@ blogc_source_parse(const char *src, size_t src_len, int toctree_maxdepth,
state = SOURCE_CONFIG_VALUE_START;
break;
}
- *err = bc_error_parser(BLOGC_ERROR_SOURCE_PARSER, src, src_len,
+ *err = blogc_error_parser(BLOGC_ERROR_SOURCE_PARSER, src, src_len,
current, "Invalid configuration key.");
break;
@@ -113,16 +110,15 @@ blogc_source_parse(const char *src, size_t src_len, int toctree_maxdepth,
start = current;
break;
}
- bc_trie_insert(rv, key, bc_strdup(""));
- free(key);
- key = NULL;
- state = SOURCE_START;
+ *err = blogc_error_parser(BLOGC_ERROR_SOURCE_PARSER, src, src_len,
+ current, "Configuration value not provided for '%s'.",
+ key);
break;
case SOURCE_CONFIG_VALUE:
if (c == '\n' || c == '\r') {
- tmp = bc_strndup(src + start, current - start);
- bc_trie_insert(rv, key, bc_strdup(bc_str_strip(tmp)));
+ tmp = sb_strndup(src + start, current - start);
+ sb_trie_insert(rv, key, sb_strdup(sb_str_strip(tmp)));
free(tmp);
free(key);
key = NULL;
@@ -137,7 +133,7 @@ blogc_source_parse(const char *src, size_t src_len, int toctree_maxdepth,
state = SOURCE_CONTENT_START;
break;
}
- *err = bc_error_parser(BLOGC_ERROR_SOURCE_PARSER, src, src_len,
+ *err = blogc_error_parser(BLOGC_ERROR_SOURCE_PARSER, src, src_len,
current,
"Invalid content separator. Must be more than one '-' characters.");
break;
@@ -151,65 +147,25 @@ blogc_source_parse(const char *src, size_t src_len, int toctree_maxdepth,
case SOURCE_CONTENT:
if (current == (src_len - 1)) {
- tmp = bc_strndup(src + start, src_len - start);
- bc_trie_insert(rv, "RAW_CONTENT", tmp);
- char *first_header = NULL;
+ tmp = sb_strndup(src + start, src_len - start);
+ sb_trie_insert(rv, "RAW_CONTENT", tmp);
+ char *excerpt = NULL;
char *description = NULL;
- char *endl = NULL;
- bc_slist_t *headers = NULL;
- bool read_headers = (NULL == bc_trie_lookup(rv, "TOCTREE"));
- content = blogc_content_parse(tmp, &end_excerpt,
- &first_header, &description, &endl, read_headers ? &headers : NULL);
- if (first_header != NULL) {
- // do not override source-provided first_header.
- if (NULL == bc_trie_lookup(rv, "FIRST_HEADER")) {
- // no need to free, because we are transfering memory
- // ownership to the trie.
- bc_trie_insert(rv, "FIRST_HEADER", first_header);
- }
- else {
- free(first_header);
- }
- }
+ content = blogc_content_parse(tmp, &excerpt, &description);
if (description != NULL) {
// do not override source-provided description.
- if (NULL == bc_trie_lookup(rv, "DESCRIPTION")) {
+ if (NULL == sb_trie_lookup(rv, "DESCRIPTION")) {
// no need to free, because we are transfering memory
// ownership to the trie.
- bc_trie_insert(rv, "DESCRIPTION", description);
+ sb_trie_insert(rv, "DESCRIPTION", description);
}
else {
free(description);
}
}
- if (headers != NULL) {
- // we already validated that the user do not defined TOCTREE
- // manually in source file.
- const char *maxdepth = bc_trie_lookup(rv, "TOCTREE_MAXDEPTH");
- if (maxdepth != NULL) {
- char *endptr;
- toctree_maxdepth = strtol(maxdepth, &endptr, 10);
- if (*maxdepth != '\0' && *endptr != '\0') {
- *err = bc_error_parser(BLOGC_ERROR_SOURCE_PARSER, src, src_len,
- current,
- "Invalid value for 'TOCTREE_MAXDEPTH' variable: %s.",
- maxdepth);
- blogc_toctree_free(headers);
- free(endl);
- free(content);
- break;
- }
- }
- char *toctree = blogc_toctree_render(headers, toctree_maxdepth, endl);
- blogc_toctree_free(headers);
- if (toctree != NULL) {
- bc_trie_insert(rv, "TOCTREE", toctree);
- }
- }
- free(endl);
- bc_trie_insert(rv, "CONTENT", content);
- bc_trie_insert(rv, "EXCERPT", end_excerpt == 0 ?
- bc_strdup(content) : bc_strndup(content, end_excerpt));
+ sb_trie_insert(rv, "EXCERPT", excerpt == NULL ?
+ sb_strdup(content) : excerpt);
+ sb_trie_insert(rv, "CONTENT", content);
}
break;
}
@@ -220,28 +176,28 @@ blogc_source_parse(const char *src, size_t src_len, int toctree_maxdepth,
current++;
}
- if (*err == NULL && bc_trie_size(rv) == 0) {
+ if (*err == NULL && sb_trie_size(rv) == 0) {
// ok, nothing found in the config trie, but no error set either.
// let's try to be nice with the users and provide some reasonable
// output. :)
switch (state) {
case SOURCE_START:
- *err = bc_error_parser(BLOGC_ERROR_SOURCE_PARSER, src, src_len,
+ *err = blogc_error_parser(BLOGC_ERROR_SOURCE_PARSER, src, src_len,
current, "Your source file is empty.");
break;
case SOURCE_CONFIG_KEY:
- *err = bc_error_parser(BLOGC_ERROR_SOURCE_PARSER, src, src_len,
+ *err = blogc_error_parser(BLOGC_ERROR_SOURCE_PARSER, src, src_len,
current, "Your last configuration key is missing ':' and "
"the value");
break;
case SOURCE_CONFIG_VALUE_START:
- *err = bc_error_parser(BLOGC_ERROR_SOURCE_PARSER, src, src_len,
+ *err = blogc_error_parser(BLOGC_ERROR_SOURCE_PARSER, src, src_len,
current, "Configuration value not provided for '%s'.",
key);
break;
case SOURCE_CONFIG_VALUE:
- *err = bc_error_parser(BLOGC_ERROR_SOURCE_PARSER, src, src_len,
+ *err = blogc_error_parser(BLOGC_ERROR_SOURCE_PARSER, src, src_len,
current, "No line ending after the configuration value for "
"'%s'.", key);
break;
@@ -254,7 +210,7 @@ blogc_source_parse(const char *src, size_t src_len, int toctree_maxdepth,
if (*err != NULL) {
free(key);
- bc_trie_free(rv);
+ sb_trie_free(rv);
return NULL;
}
diff --git a/src/blogc/source-parser.h b/src/source-parser.h
index 2acd753..0d54742 100644
--- a/src/blogc/source-parser.h
+++ b/src/source-parser.h
@@ -1,6 +1,6 @@
/*
* blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
*
* This program can be distributed under the terms of the BSD License.
* See the file LICENSE.
@@ -10,10 +10,10 @@
#define _SOURCE_PARSER_H
#include <stddef.h>
-#include "../common/error.h"
-#include "../common/utils.h"
+#include "error.h"
+#include "utils.h"
-bc_trie_t* blogc_source_parse(const char *src, size_t src_len, int toctree_maxdepth,
- bc_error_t **err);
+sb_trie_t* blogc_source_parse(const char *src, size_t src_len,
+ blogc_error_t **err);
#endif /* _SOURCE_PARSER_H */
diff --git a/src/blogc/template-parser.c b/src/template-parser.c
index 8e7ca84..6ca6eb7 100644
--- a/src/blogc/template-parser.c
+++ b/src/template-parser.c
@@ -1,6 +1,6 @@
/*
* blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
*
* This program can be distributed under the terms of the BSD License.
* See the file LICENSE.
@@ -11,8 +11,8 @@
#include <string.h>
#include "template-parser.h"
-#include "../common/error.h"
-#include "../common/utils.h"
+#include "error.h"
+#include "utils.h"
typedef enum {
@@ -41,8 +41,8 @@ typedef enum {
} blogc_template_parser_state_t;
-bc_slist_t*
-blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
+sb_slist_t*
+blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)
{
if (err == NULL || *err != NULL)
return NULL;
@@ -55,16 +55,16 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
size_t start2 = 0;
size_t end2 = 0;
- blogc_template_operator_t tmp_op = 0;
+ blogc_template_stmt_operator_t tmp_op = 0;
- size_t if_count = 0;
- size_t block_if_count = 0;
+ unsigned int if_count = 0;
+ unsigned int block_if_count = 0;
bool else_open = false;
bool foreach_open = false;
bool block_foreach_open = false;
- bc_slist_t *ast = NULL;
- blogc_template_node_t *node = NULL;
+ sb_slist_t *stmts = NULL;
+ blogc_template_stmt_t *stmt = NULL;
/*
* this is a reference to the content of previous node in the singly-linked
@@ -75,14 +75,14 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
* - template parser never walk backwards, then the list itself does not
* need to know its previous node.
*/
- blogc_template_node_t *previous = NULL;
+ blogc_template_stmt_t *previous = NULL;
bool lstrip_next = false;
char *tmp = NULL;
char *block_type = NULL;
blogc_template_parser_state_t state = TEMPLATE_START;
- blogc_template_node_type_t type = BLOGC_TEMPLATE_NODE_CONTENT;
+ blogc_template_stmt_type_t type = BLOGC_TEMPLATE_CONTENT_STMT;
bool block_open = false;
@@ -94,23 +94,23 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
case TEMPLATE_START:
if (last) {
- node = bc_malloc(sizeof(blogc_template_node_t));
- node->type = type;
+ stmt = sb_malloc(sizeof(blogc_template_stmt_t));
+ stmt->type = type;
if (lstrip_next) {
- tmp = bc_strndup(src + start, src_len - start);
- node->data[0] = bc_strdup(bc_str_lstrip(tmp));
+ tmp = sb_strndup(src + start, src_len - start);
+ stmt->value = sb_strdup(sb_str_lstrip(tmp));
free(tmp);
tmp = NULL;
lstrip_next = false;
}
else {
- node->data[0] = bc_strndup(src + start, src_len - start);
+ stmt->value = sb_strndup(src + start, src_len - start);
}
- node->op = 0;
- node->data[1] = NULL;
- ast = bc_slist_append(ast, node);
- previous = node;
- node = NULL;
+ stmt->op = 0;
+ stmt->value2 = NULL;
+ stmts = sb_slist_append(stmts, stmt);
+ previous = stmt;
+ stmt = NULL;
}
if (c == '{') {
end = current;
@@ -125,23 +125,23 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
else
state = TEMPLATE_VARIABLE_START;
if (end > start) {
- node = bc_malloc(sizeof(blogc_template_node_t));
- node->type = type;
+ stmt = sb_malloc(sizeof(blogc_template_stmt_t));
+ stmt->type = type;
if (lstrip_next) {
- tmp = bc_strndup(src + start, end - start);
- node->data[0] = bc_strdup(bc_str_lstrip(tmp));
+ tmp = sb_strndup(src + start, end - start);
+ stmt->value = sb_strdup(sb_str_lstrip(tmp));
free(tmp);
tmp = NULL;
lstrip_next = false;
}
else {
- node->data[0] = bc_strndup(src + start, end - start);
+ stmt->value = sb_strndup(src + start, end - start);
}
- node->op = 0;
- node->data[1] = NULL;
- ast = bc_slist_append(ast, node);
- previous = node;
- node = NULL;
+ stmt->op = 0;
+ stmt->value2 = NULL;
+ stmts = sb_slist_append(stmts, stmt);
+ previous = stmt;
+ stmt = NULL;
}
break;
}
@@ -151,9 +151,9 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
case TEMPLATE_BLOCK_START_WHITESPACE_CLEANER:
if (c == '-') {
if ((previous != NULL) &&
- (previous->type == BLOGC_TEMPLATE_NODE_CONTENT))
+ (previous->type == BLOGC_TEMPLATE_CONTENT_STMT))
{
- previous->data[0] = bc_str_rstrip(previous->data[0]); // does not need copy
+ previous->value = sb_str_rstrip(previous->value); // does not need copy
}
state = TEMPLATE_BLOCK_START;
break;
@@ -161,7 +161,7 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
state = TEMPLATE_BLOCK_START;
case TEMPLATE_BLOCK_START:
- if (bc_isspace(c))
+ if (c == ' ')
break;
if (c >= 'a' && c <= 'z') {
state = TEMPLATE_BLOCK_TYPE;
@@ -169,13 +169,13 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
break;
}
if (c == '-') {
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
src_len, current,
"Invalid statement syntax. Duplicated whitespace "
"cleaner before statement.");
break;
}
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
src_len, current,
"Invalid statement syntax. Must begin with lowercase letter.");
break;
@@ -183,19 +183,19 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
case TEMPLATE_BLOCK_TYPE:
if (c >= 'a' && c <= 'z')
break;
- if (bc_isspace(c)) {
+ if (c == ' ') {
if ((current - start == 5) &&
(0 == strncmp("block", src + start, 5)))
{
if (!block_open) {
state = TEMPLATE_BLOCK_BLOCK_TYPE_START;
- type = BLOGC_TEMPLATE_NODE_BLOCK;
+ type = BLOGC_TEMPLATE_BLOCK_STMT;
start = current;
block_if_count = if_count;
block_foreach_open = foreach_open;
break;
}
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER,
src, src_len, current, "Blocks can't be nested.");
break;
}
@@ -204,24 +204,24 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
{
if (block_open) {
if (if_count != block_if_count) {
- *err = bc_error_new_printf(BLOGC_ERROR_TEMPLATE_PARSER,
+ *err = blogc_error_new_printf(BLOGC_ERROR_TEMPLATE_PARSER,
"%d open 'if', 'ifdef' and/or 'ifndef' statements "
"were not closed inside a '%s' block!",
if_count - block_if_count, block_type);
break;
}
if (!block_foreach_open && foreach_open) {
- *err = bc_error_new_printf(BLOGC_ERROR_TEMPLATE_PARSER,
+ *err = blogc_error_new_printf(BLOGC_ERROR_TEMPLATE_PARSER,
"An open 'foreach' statement was not closed "
"inside a '%s' block!", block_type);
break;
}
state = TEMPLATE_BLOCK_END_WHITESPACE_CLEANER;
- type = BLOGC_TEMPLATE_NODE_ENDBLOCK;
+ type = BLOGC_TEMPLATE_ENDBLOCK_STMT;
block_open = false;
break;
}
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER,
src, src_len, current,
"'endblock' statement without an open 'block' statement.");
break;
@@ -230,7 +230,7 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
(0 == strncmp("ifdef", src + start, 5)))
{
state = TEMPLATE_BLOCK_IF_START;
- type = BLOGC_TEMPLATE_NODE_IFDEF;
+ type = BLOGC_TEMPLATE_IFDEF_STMT;
start = current;
if_count++;
else_open = false;
@@ -240,7 +240,7 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
(0 == strncmp("ifndef", src + start, 6)))
{
state = TEMPLATE_BLOCK_IF_START;
- type = BLOGC_TEMPLATE_NODE_IFNDEF;
+ type = BLOGC_TEMPLATE_IFNDEF_STMT;
start = current;
if_count++;
else_open = false;
@@ -250,7 +250,7 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
(0 == strncmp("if", src + start, 2)))
{
state = TEMPLATE_BLOCK_IF_START;
- type = BLOGC_TEMPLATE_NODE_IF;
+ type = BLOGC_TEMPLATE_IF_STMT;
start = current;
if_count++;
else_open = false;
@@ -264,17 +264,17 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
{
if (!else_open) {
state = TEMPLATE_BLOCK_END_WHITESPACE_CLEANER;
- type = BLOGC_TEMPLATE_NODE_ELSE;
+ type = BLOGC_TEMPLATE_ELSE_STMT;
else_open = true;
break;
}
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER,
src, src_len, current,
"More than one 'else' statement for an open 'if', "
"'ifdef' or 'ifndef' statement.");
break;
}
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER,
src, src_len, current,
"'else' statement without an open 'if', 'ifdef' or "
"'ifndef' statement.");
@@ -287,12 +287,12 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
(!block_open && if_count > 0))
{
state = TEMPLATE_BLOCK_END_WHITESPACE_CLEANER;
- type = BLOGC_TEMPLATE_NODE_ENDIF;
+ type = BLOGC_TEMPLATE_ENDIF_STMT;
if_count--;
else_open = false;
break;
}
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER,
src, src_len, current,
"'endif' statement without an open 'if', 'ifdef' or "
"'ifndef' statement.");
@@ -303,12 +303,12 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
{
if (!foreach_open) {
state = TEMPLATE_BLOCK_FOREACH_START;
- type = BLOGC_TEMPLATE_NODE_FOREACH;
+ type = BLOGC_TEMPLATE_FOREACH_STMT;
start = current;
foreach_open = true;
break;
}
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER,
src, src_len, current, "'foreach' statements can't "
"be nested.");
break;
@@ -320,18 +320,18 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
(!block_open && foreach_open))
{
state = TEMPLATE_BLOCK_END_WHITESPACE_CLEANER;
- type = BLOGC_TEMPLATE_NODE_ENDFOREACH;
+ type = BLOGC_TEMPLATE_ENDFOREACH_STMT;
foreach_open = false;
break;
}
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER,
src, src_len, current,
"'endforeach' statement without an open 'foreach' "
"statement.");
break;
}
}
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
src_len, current,
"Invalid statement type: Allowed types are: 'block', "
"'endblock', 'if', 'ifdef', 'ifndef', 'else', 'endif', "
@@ -339,14 +339,14 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
break;
case TEMPLATE_BLOCK_BLOCK_TYPE_START:
- if (bc_isspace(c))
+ if (c == ' ')
break;
if (c >= 'a' && c <= 'z') {
state = TEMPLATE_BLOCK_BLOCK_TYPE;
start = current;
break;
}
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
src_len, current,
"Invalid block syntax. Must begin with lowercase letter.");
break;
@@ -354,7 +354,7 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
case TEMPLATE_BLOCK_BLOCK_TYPE:
if ((c >= 'a' && c <= 'z') || c == '_')
break;
- if (bc_isspace(c)) {
+ if (c == ' ') {
if ((current - start == 5) &&
(0 == strncmp("entry", src + start, 5)))
{
@@ -379,38 +379,22 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
state = TEMPLATE_BLOCK_END_WHITESPACE_CLEANER;
break;
}
- else if ((current - start == 13) &&
- (0 == strncmp("listing_empty", src + start, 13)))
- {
- block_open = true;
- end = current;
- state = TEMPLATE_BLOCK_END_WHITESPACE_CLEANER;
- break;
- }
- else if ((current - start == 13) &&
- (0 == strncmp("listing_entry", src + start, 13)))
- {
- block_open = true;
- end = current;
- state = TEMPLATE_BLOCK_END_WHITESPACE_CLEANER;
- break;
- }
}
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
src_len, current,
- "Invalid block type. Allowed types are: 'entry', 'listing', "
- "'listing_once', 'listing_empty' and 'listing_entry'.");
+ "Invalid block type. Allowed types are: 'entry', 'listing' "
+ "and 'listing_once'.");
break;
case TEMPLATE_BLOCK_IF_START:
- if (bc_isspace(c))
+ if (c == ' ')
break;
if (c >= 'A' && c <= 'Z') {
state = TEMPLATE_BLOCK_IF_VARIABLE;
start = current;
break;
}
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
src_len, current,
"Invalid variable name. Must begin with uppercase letter.");
break;
@@ -418,36 +402,37 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
case TEMPLATE_BLOCK_IF_VARIABLE:
if ((c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_')
break;
- if (bc_isspace(c)) {
+ if (c == ' ') {
end = current;
- if (type == BLOGC_TEMPLATE_NODE_IF)
+ if (type == BLOGC_TEMPLATE_IF_STMT)
state = TEMPLATE_BLOCK_IF_OPERATOR_START;
else
state = TEMPLATE_BLOCK_END_WHITESPACE_CLEANER;
break;
}
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
src_len, current,
"Invalid variable name. Must be uppercase letter, number "
"or '_'.");
break;
case TEMPLATE_BLOCK_IF_OPERATOR_START:
- if (bc_isspace(c))
+ if (c == ' ') {
break;
+ }
state = TEMPLATE_BLOCK_IF_OPERATOR;
op_start = current;
break;
case TEMPLATE_BLOCK_IF_OPERATOR:
- if (!bc_isspace(c))
+ if (c != ' ')
break;
state = TEMPLATE_BLOCK_IF_OPERAND_START;
op_end = current;
break;
case TEMPLATE_BLOCK_IF_OPERAND_START:
- if (bc_isspace(c))
+ if (c == ' ')
break;
if (c >= 'A' && c <= 'Z') {
state = TEMPLATE_BLOCK_IF_VARIABLE_OPERAND;
@@ -461,7 +446,7 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
}
op_start = 0;
op_end = 0;
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
src_len, current,
"Invalid 'if' operand. Must be double-quoted static "
"string or variable.");
@@ -484,14 +469,14 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
break;
case TEMPLATE_BLOCK_FOREACH_START:
- if (bc_isspace(c))
+ if (c == ' ')
break;
if (c >= 'A' && c <= 'Z') {
state = TEMPLATE_BLOCK_FOREACH_VARIABLE;
start = current;
break;
}
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
src_len, current,
"Invalid foreach variable name. Must begin with uppercase "
"letter.");
@@ -500,19 +485,19 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
case TEMPLATE_BLOCK_FOREACH_VARIABLE:
if ((c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_')
break;
- if (bc_isspace(c)) {
+ if (c == ' ') {
end = current;
state = TEMPLATE_BLOCK_END_WHITESPACE_CLEANER;
break;
}
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
src_len, current,
"Invalid foreach variable name. Must be uppercase letter, "
"number or '_'.");
break;
case TEMPLATE_BLOCK_END_WHITESPACE_CLEANER:
- if (bc_isspace(c))
+ if (c == ' ')
break;
if (c == '-') {
lstrip_next = true;
@@ -527,27 +512,27 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
break;
}
if (c == '-') {
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
src_len, current,
"Invalid statement syntax. Duplicated whitespace "
"cleaner after statement.");
break;
}
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
src_len, current,
"Invalid statement syntax. Must end with '%%}'.");
break;
case TEMPLATE_VARIABLE_START:
- if (bc_isspace(c))
+ if (c == ' ')
break;
if (c >= 'A' && c <= 'Z') {
state = TEMPLATE_VARIABLE;
- type = BLOGC_TEMPLATE_NODE_VARIABLE;
+ type = BLOGC_TEMPLATE_VARIABLE_STMT;
start = current;
break;
}
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
src_len, current,
"Invalid variable name. Must begin with uppercase letter.");
break;
@@ -555,7 +540,7 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
case TEMPLATE_VARIABLE:
if ((c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_')
break;
- if (bc_isspace(c)) {
+ if (c == ' ') {
end = current;
state = TEMPLATE_VARIABLE_END;
break;
@@ -565,20 +550,20 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
state = TEMPLATE_CLOSE_BRACKET;
break;
}
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
src_len, current,
"Invalid variable name. Must be uppercase letter, number "
"or '_'.");
break;
case TEMPLATE_VARIABLE_END:
- if (bc_isspace(c))
+ if (c == ' ')
break;
if (c == '}') {
state = TEMPLATE_CLOSE_BRACKET;
break;
}
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
src_len, current,
"Invalid statement syntax. Must end with '}}'.");
break;
@@ -604,7 +589,7 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
tmp_op = BLOGC_TEMPLATE_OP_NEQ;
}
if (tmp_op == 0) {
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER,
src, src_len, op_start,
"Invalid 'if' operator. Must be '<', '>', "
"'<=', '>=', '==' or '!='.");
@@ -615,29 +600,29 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
op_start = 0;
op_end = 0;
}
- node = bc_malloc(sizeof(blogc_template_node_t));
- node->type = type;
- node->op = tmp_op;
- node->data[0] = NULL;
- node->data[1] = NULL;
+ stmt = sb_malloc(sizeof(blogc_template_stmt_t));
+ stmt->type = type;
+ stmt->value = NULL;
+ stmt->op = tmp_op;
+ stmt->value2 = NULL;
if (end > start)
- node->data[0] = bc_strndup(src + start, end - start);
+ stmt->value = sb_strndup(src + start, end - start);
if (end2 > start2) {
- node->data[1] = bc_strndup(src + start2, end2 - start2);
+ stmt->value2 = sb_strndup(src + start2, end2 - start2);
start2 = 0;
end2 = 0;
}
- if (type == BLOGC_TEMPLATE_NODE_BLOCK)
- block_type = node->data[0];
- ast = bc_slist_append(ast, node);
- previous = node;
- node = NULL;
+ if (type == BLOGC_TEMPLATE_BLOCK_STMT)
+ block_type = stmt->value;
+ stmts = sb_slist_append(stmts, stmt);
+ previous = stmt;
+ stmt = NULL;
state = TEMPLATE_START;
- type = BLOGC_TEMPLATE_NODE_CONTENT;
+ type = BLOGC_TEMPLATE_CONTENT_STMT;
start = current + 1;
break;
}
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
src_len, current,
"Invalid statement syntax. Must end with '}'.");
break;
@@ -652,43 +637,43 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
if (*err == NULL) {
if (state == TEMPLATE_BLOCK_IF_STRING_OPERAND)
- *err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src, src_len,
+ *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src, src_len,
start2, "Found an open double-quoted string.");
else if (if_count != 0)
- *err = bc_error_new_printf(BLOGC_ERROR_TEMPLATE_PARSER,
+ *err = blogc_error_new_printf(BLOGC_ERROR_TEMPLATE_PARSER,
"%d open 'if', 'ifdef' and/or 'ifndef' statements were not closed!",
if_count);
else if (block_open)
- *err = bc_error_new(BLOGC_ERROR_TEMPLATE_PARSER,
+ *err = blogc_error_new(BLOGC_ERROR_TEMPLATE_PARSER,
"An open block was not closed!");
else if (foreach_open)
- *err = bc_error_new(BLOGC_ERROR_TEMPLATE_PARSER,
+ *err = blogc_error_new(BLOGC_ERROR_TEMPLATE_PARSER,
"An open 'foreach' statement was not closed!");
}
if (*err != NULL) {
- if (node != NULL) {
- free(node->data[0]);
- free(node);
+ if (stmt != NULL) {
+ free(stmt->value);
+ free(stmt);
}
- blogc_template_free_ast(ast);
+ blogc_template_free_stmts(stmts);
return NULL;
}
- return ast;
+ return stmts;
}
void
-blogc_template_free_ast(bc_slist_t *ast)
+blogc_template_free_stmts(sb_slist_t *stmts)
{
- for (bc_slist_t *tmp = ast; tmp != NULL; tmp = tmp->next) {
- blogc_template_node_t *data = tmp->data;
+ for (sb_slist_t *tmp = stmts; tmp != NULL; tmp = tmp->next) {
+ blogc_template_stmt_t *data = tmp->data;
if (data == NULL)
continue;
- free(data->data[0]);
- free(data->data[1]);
+ free(data->value);
+ free(data->value2);
free(data);
}
- bc_slist_free(ast);
+ sb_slist_free(stmts);
}
diff --git a/src/template-parser.h b/src/template-parser.h
new file mode 100644
index 0000000..19df6af
--- /dev/null
+++ b/src/template-parser.h
@@ -0,0 +1,53 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#ifndef _TEMPLATE_PARSER_H
+#define _TEMPLATE_PARSER_H
+
+#include <stddef.h>
+#include "error.h"
+#include "utils.h"
+
+/*
+ * note: whitespace cleaners are NOT added to ast. we fix strings right during
+ * template parsing. renderer does not need to care about it, for the sake of
+ * simplicity.
+ */
+typedef enum {
+ BLOGC_TEMPLATE_IFDEF_STMT = 1,
+ BLOGC_TEMPLATE_IFNDEF_STMT,
+ BLOGC_TEMPLATE_IF_STMT,
+ BLOGC_TEMPLATE_ELSE_STMT,
+ BLOGC_TEMPLATE_ENDIF_STMT,
+ BLOGC_TEMPLATE_FOREACH_STMT,
+ BLOGC_TEMPLATE_ENDFOREACH_STMT,
+ BLOGC_TEMPLATE_BLOCK_STMT,
+ BLOGC_TEMPLATE_ENDBLOCK_STMT,
+ BLOGC_TEMPLATE_VARIABLE_STMT,
+ BLOGC_TEMPLATE_CONTENT_STMT,
+} blogc_template_stmt_type_t;
+
+typedef enum {
+ BLOGC_TEMPLATE_OP_NEQ = 1 << 0,
+ BLOGC_TEMPLATE_OP_EQ = 1 << 1,
+ BLOGC_TEMPLATE_OP_LT = 1 << 2,
+ BLOGC_TEMPLATE_OP_GT = 1 << 3,
+} blogc_template_stmt_operator_t;
+
+typedef struct {
+ blogc_template_stmt_type_t type;
+ char *value;
+ char *value2;
+ blogc_template_stmt_operator_t op;
+} blogc_template_stmt_t;
+
+sb_slist_t* blogc_template_parse(const char *src, size_t src_len,
+ blogc_error_t **err);
+void blogc_template_free_stmts(sb_slist_t *stmts);
+
+#endif /* _TEMPLATE_PARSER_H */
diff --git a/src/common/utf8.c b/src/utf8.c
index df5e2d2..a2f4fdd 100644
--- a/src/common/utf8.c
+++ b/src/utf8.c
@@ -1,7 +1,7 @@
/*
* blogc: A blog compiler.
* Copyright (c) 2008-2010 Bjoern Hoehrmann <bjoern@hoehrmann.de>
- * Copyright (c) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ * Copyright (c) 2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -56,27 +56,41 @@ static const uint8_t utf8d[] = {
};
+static uint32_t inline
+decode(uint32_t* state, uint32_t* codep, uint32_t byte) {
+ uint32_t type = utf8d[byte];
+
+ *codep = (*state != UTF8_ACCEPT) ?
+ (byte & 0x3fu) | (*codep << 6) :
+ (0xff >> type) & (byte);
+
+ *state = utf8d[256 + *state + type];
+ return *state;
+}
+
+
bool
-bc_utf8_validate(const uint8_t *str, size_t len)
+blogc_utf8_validate(const uint8_t *str, size_t len)
{
+ uint32_t codepoint;
uint32_t state = 0;
for (size_t i = 0; i < len; i++)
- state = utf8d[256 + state + utf8d[str[i]]];
+ decode(&state, &codepoint, str[i]);
return state == UTF8_ACCEPT;
}
bool
-bc_utf8_validate_str(bc_string_t *str)
+blogc_utf8_validate_str(sb_string_t *str)
{
- return bc_utf8_validate((uint8_t*) str->str, str->len);
+ return blogc_utf8_validate((uint8_t*) str->str, str->len);
}
size_t
-bc_utf8_skip_bom(const uint8_t *str, size_t len)
+blogc_utf8_skip_bom(const uint8_t *str, size_t len)
{
if (len < 3)
return 0;
diff --git a/src/common/utf8.h b/src/utf8.h
index bf0f1ae..06fe07e 100644
--- a/src/common/utf8.h
+++ b/src/utf8.h
@@ -1,6 +1,6 @@
/*
* blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
*
* This program can be distributed under the terms of the BSD License.
* See the file LICENSE.
@@ -14,8 +14,8 @@
#include <stdint.h>
#include "utils.h"
-bool bc_utf8_validate(const uint8_t *str, size_t len);
-bool bc_utf8_validate_str(bc_string_t *str);
-size_t bc_utf8_skip_bom(const uint8_t *str, size_t len);
+bool blogc_utf8_validate(const uint8_t *str, size_t len);
+bool blogc_utf8_validate_str(sb_string_t *str);
+size_t blogc_utf8_skip_bom(const uint8_t *str, size_t len);
#endif /* _UTF_8_H */
diff --git a/src/common/utils.c b/src/utils.c
index ddd3911..b42ae4e 100644
--- a/src/common/utils.c
+++ b/src/utils.c
@@ -1,15 +1,14 @@
/*
* blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ * Copyright (C) 2014-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
*
* This program can be distributed under the terms of the BSD License.
* See the file LICENSE.
*/
-#define BC_STRING_CHUNK_SIZE 128
+#define SB_STRING_CHUNK_SIZE 128
#include <string.h>
-#include <strings.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>
@@ -19,7 +18,7 @@
void*
-bc_malloc(size_t size)
+sb_malloc(size_t size)
{
// simple things simple!
void *rv = malloc(size);
@@ -32,7 +31,7 @@ bc_malloc(size_t size)
void*
-bc_realloc(void *ptr, size_t size)
+sb_realloc(void *ptr, size_t size)
{
// simple things even simpler :P
void *rv = realloc(ptr, size);
@@ -45,17 +44,17 @@ bc_realloc(void *ptr, size_t size)
}
-bc_slist_t*
-bc_slist_append(bc_slist_t *l, void *data)
+sb_slist_t*
+sb_slist_append(sb_slist_t *l, void *data)
{
- bc_slist_t *node = bc_malloc(sizeof(bc_slist_t));
+ sb_slist_t *node = sb_malloc(sizeof(sb_slist_t));
node->data = data;
node->next = NULL;
if (l == NULL) {
l = node;
}
else {
- bc_slist_t *tmp;
+ sb_slist_t *tmp;
for (tmp = l; tmp->next != NULL; tmp = tmp->next);
tmp->next = node;
}
@@ -63,10 +62,10 @@ bc_slist_append(bc_slist_t *l, void *data)
}
-bc_slist_t*
-bc_slist_prepend(bc_slist_t *l, void *data)
+sb_slist_t*
+sb_slist_prepend(sb_slist_t *l, void *data)
{
- bc_slist_t *node = bc_malloc(sizeof(bc_slist_t));
+ sb_slist_t *node = sb_malloc(sizeof(sb_slist_t));
node->data = data;
node->next = l;
l = node;
@@ -74,27 +73,11 @@ bc_slist_prepend(bc_slist_t *l, void *data)
}
-bc_slist_t*
-bc_slist_append_list(bc_slist_t *l, bc_slist_t *n)
-{
- if (l == NULL) {
- return n;
- }
- if (n == NULL) {
- return l;
- }
- bc_slist_t *tmp;
- for (tmp = l; tmp->next != NULL; tmp = tmp->next);
- tmp->next = n;
- return l;
-}
-
-
void
-bc_slist_free_full(bc_slist_t *l, bc_free_func_t free_func)
+sb_slist_free_full(sb_slist_t *l, sb_free_func_t free_func)
{
while (l != NULL) {
- bc_slist_t *tmp = l->next;
+ sb_slist_t *tmp = l->next;
if ((free_func != NULL) && (l->data != NULL))
free_func(l->data);
free(l);
@@ -104,26 +87,26 @@ bc_slist_free_full(bc_slist_t *l, bc_free_func_t free_func)
void
-bc_slist_free(bc_slist_t *l)
+sb_slist_free(sb_slist_t *l)
{
- bc_slist_free_full(l, NULL);
+ sb_slist_free_full(l, NULL);
}
size_t
-bc_slist_length(bc_slist_t *l)
+sb_slist_length(sb_slist_t *l)
{
if (l == NULL)
return 0;
size_t i;
- bc_slist_t *tmp;
+ sb_slist_t *tmp;
for (tmp = l, i = 0; tmp != NULL; tmp = tmp->next, i++);
return i;
}
char*
-bc_strdup(const char *s)
+sb_strdup(const char *s)
{
if (s == NULL)
return NULL;
@@ -137,7 +120,7 @@ bc_strdup(const char *s)
char*
-bc_strndup(const char *s, size_t n)
+sb_strndup(const char *s, size_t n)
{
if (s == NULL)
return NULL;
@@ -152,10 +135,8 @@ bc_strndup(const char *s, size_t n)
char*
-bc_strdup_vprintf(const char *format, va_list ap)
+sb_strdup_vprintf(const char *format, va_list ap)
{
- if (format == NULL)
- return NULL;
va_list ap2;
va_copy(ap2, ap);
int l = vsnprintf(NULL, 0, format, ap2);
@@ -175,28 +156,18 @@ bc_strdup_vprintf(const char *format, va_list ap)
char*
-bc_strdup_printf(const char *format, ...)
+sb_strdup_printf(const char *format, ...)
{
- if (format == NULL)
- return NULL;
va_list ap;
va_start(ap, format);
- char *tmp = bc_strdup_vprintf(format, ap);
+ char *tmp = sb_strdup_vprintf(format, ap);
va_end(ap);
return tmp;
}
-// locale-independent implementation of isspace
bool
-bc_isspace(int c)
-{
- return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v';
-}
-
-
-bool
-bc_str_starts_with(const char *str, const char *prefix)
+sb_str_starts_with(const char *str, const char *prefix)
{
int str_l = strlen(str);
int str_lp = strlen(prefix);
@@ -207,7 +178,7 @@ bc_str_starts_with(const char *str, const char *prefix)
bool
-bc_str_ends_with(const char *str, const char *suffix)
+sb_str_ends_with(const char *str, const char *suffix)
{
int str_l = strlen(str);
int str_ls = strlen(suffix);
@@ -218,7 +189,7 @@ bc_str_ends_with(const char *str, const char *suffix)
char*
-bc_str_lstrip(char *str)
+sb_str_lstrip(char *str)
{
if (str == NULL)
return NULL;
@@ -242,7 +213,7 @@ bc_str_lstrip(char *str)
char*
-bc_str_rstrip(char *str)
+sb_str_rstrip(char *str)
{
if (str == NULL)
return NULL;
@@ -266,52 +237,52 @@ bc_str_rstrip(char *str)
char*
-bc_str_strip(char *str)
+sb_str_strip(char *str)
{
- return bc_str_lstrip(bc_str_rstrip(str));
+ return sb_str_lstrip(sb_str_rstrip(str));
}
char**
-bc_str_split(const char *str, char c, size_t max_pieces)
+sb_str_split(const char *str, char c, unsigned int max_pieces)
{
if (str == NULL)
return NULL;
- char **rv = bc_malloc(sizeof(char*));
- size_t i, start = 0, count = 0;
+ char **rv = sb_malloc(sizeof(char*));
+ unsigned int i, start = 0, count = 0;
for (i = 0; i < strlen(str) + 1; i++) {
if (str[0] == '\0')
break;
if ((str[i] == c && (!max_pieces || count + 1 < max_pieces)) || str[i] == '\0') {
- rv = bc_realloc(rv, (count + 1) * sizeof(char*));
- rv[count] = bc_malloc(i - start + 1);
+ rv = sb_realloc(rv, (count + 1) * sizeof(char*));
+ rv[count] = sb_malloc(i - start + 1);
memcpy(rv[count], str + start, i - start);
rv[count++][i - start] = '\0';
start = i + 1;
}
}
- rv = bc_realloc(rv, (count + 1) * sizeof(char*));
+ rv = sb_realloc(rv, (count + 1) * sizeof(char*));
rv[count] = NULL;
return rv;
}
char*
-bc_str_replace(const char *str, const char search, const char *replace)
+sb_str_replace(const char *str, const char search, const char *replace)
{
- char **pieces = bc_str_split(str, search, 0);
+ char **pieces = sb_str_split(str, search, 0);
if (pieces == NULL)
return NULL;
- char* rv = bc_strv_join(pieces, replace);
- bc_strv_free(pieces);
+ char* rv = sb_strv_join(pieces, replace);
+ sb_strv_free(pieces);
if (rv == NULL)
- return bc_strdup(str);
+ return sb_strdup(str);
return rv;
}
char*
-bc_str_find(const char *str, char c)
+sb_str_find(const char *str, char c)
{
// this is somewhat similar to strchr, but respects '\' escaping.
if (str == NULL)
@@ -331,33 +302,8 @@ bc_str_find(const char *str, char c)
}
-bool
-bc_str_to_bool(const char *str)
-{
- if (str == NULL)
- return false;
-
- if (0 == strcmp(str, "1"))
- return true;
-
- if (0 == strcasecmp(str, "y"))
- return true;
-
- if (0 == strcasecmp(str, "yes"))
- return true;
-
- if (0 == strcasecmp(str, "true"))
- return true;
-
- if (0 == strcasecmp(str, "on"))
- return true;
-
- return false;
-}
-
-
void
-bc_strv_free(char **strv)
+sb_strv_free(char **strv)
{
if (strv == NULL)
return;
@@ -368,22 +314,22 @@ bc_strv_free(char **strv)
char*
-bc_strv_join(char **strv, const char *separator)
+sb_strv_join(char **strv, const char *separator)
{
if (strv == NULL || separator == NULL)
return NULL;
- bc_string_t *str = bc_string_new();
+ sb_string_t *str = sb_string_new();
for (size_t i = 0; strv[i] != NULL; i++) {
- str = bc_string_append(str, strv[i]);
+ str = sb_string_append(str, strv[i]);
if (strv[i + 1] != NULL)
- str = bc_string_append(str, separator);
+ str = sb_string_append(str, separator);
}
- return bc_string_free(str, false);
+ return sb_string_free(str, false);
}
size_t
-bc_strv_length(char **strv)
+sb_strv_length(char **strv)
{
if (strv == NULL)
return 0;
@@ -393,23 +339,23 @@ bc_strv_length(char **strv)
}
-bc_string_t*
-bc_string_new(void)
+sb_string_t*
+sb_string_new(void)
{
- bc_string_t* rv = bc_malloc(sizeof(bc_string_t));
+ sb_string_t* rv = sb_malloc(sizeof(sb_string_t));
rv->str = NULL;
rv->len = 0;
rv->allocated_len = 0;
// initialize with empty string
- rv = bc_string_append(rv, "");
+ rv = sb_string_append(rv, "");
return rv;
}
char*
-bc_string_free(bc_string_t *str, bool free_str)
+sb_string_free(sb_string_t *str, bool free_str)
{
if (str == NULL)
return NULL;
@@ -423,18 +369,18 @@ bc_string_free(bc_string_t *str, bool free_str)
}
-bc_string_t*
-bc_string_dup(bc_string_t *str)
+sb_string_t*
+sb_string_dup(sb_string_t *str)
{
if (str == NULL)
return NULL;
- bc_string_t* new = bc_string_new();
- return bc_string_append_len(new, str->str, str->len);
+ sb_string_t* new = sb_string_new();
+ return sb_string_append_len(new, str->str, str->len);
}
-bc_string_t*
-bc_string_append_len(bc_string_t *str, const char *suffix, size_t len)
+sb_string_t*
+sb_string_append_len(sb_string_t *str, const char *suffix, size_t len)
{
if (str == NULL)
return NULL;
@@ -443,8 +389,8 @@ bc_string_append_len(bc_string_t *str, const char *suffix, size_t len)
size_t old_len = str->len;
str->len += len;
if (str->len + 1 > str->allocated_len) {
- str->allocated_len = (((str->len + 1) / BC_STRING_CHUNK_SIZE) + 1) * BC_STRING_CHUNK_SIZE;
- str->str = bc_realloc(str->str, str->allocated_len);
+ str->allocated_len = (((str->len + 1) / SB_STRING_CHUNK_SIZE) + 1) * SB_STRING_CHUNK_SIZE;
+ str->str = sb_realloc(str->str, str->allocated_len);
}
memcpy(str->str + old_len, suffix, len);
str->str[str->len] = '\0';
@@ -452,26 +398,26 @@ bc_string_append_len(bc_string_t *str, const char *suffix, size_t len)
}
-bc_string_t*
-bc_string_append(bc_string_t *str, const char *suffix)
+sb_string_t*
+sb_string_append(sb_string_t *str, const char *suffix)
{
if (str == NULL)
return NULL;
const char *my_suffix = suffix == NULL ? "" : suffix;
- return bc_string_append_len(str, my_suffix, strlen(my_suffix));
+ return sb_string_append_len(str, my_suffix, strlen(my_suffix));
}
-bc_string_t*
-bc_string_append_c(bc_string_t *str, char c)
+sb_string_t*
+sb_string_append_c(sb_string_t *str, char c)
{
if (str == NULL)
return NULL;
size_t old_len = str->len;
str->len += 1;
if (str->len + 1 > str->allocated_len) {
- str->allocated_len = (((str->len + 1) / BC_STRING_CHUNK_SIZE) + 1) * BC_STRING_CHUNK_SIZE;
- str->str = bc_realloc(str->str, str->allocated_len);
+ str->allocated_len = (((str->len + 1) / SB_STRING_CHUNK_SIZE) + 1) * SB_STRING_CHUNK_SIZE;
+ str->str = sb_realloc(str->str, str->allocated_len);
}
str->str[old_len] = c;
str->str[str->len] = '\0';
@@ -479,25 +425,23 @@ bc_string_append_c(bc_string_t *str, char c)
}
-bc_string_t*
-bc_string_append_printf(bc_string_t *str, const char *format, ...)
+sb_string_t*
+sb_string_append_printf(sb_string_t *str, const char *format, ...)
{
if (str == NULL)
return NULL;
- if (format == NULL)
- return str;
va_list ap;
va_start(ap, format);
- char *tmp = bc_strdup_vprintf(format, ap);
+ char *tmp = sb_strdup_vprintf(format, ap);
va_end(ap);
- str = bc_string_append(str, tmp);
+ str = sb_string_append(str, tmp);
free(tmp);
return str;
}
-bc_string_t*
-bc_string_append_escaped(bc_string_t *str, const char *suffix)
+sb_string_t*
+sb_string_append_escaped(sb_string_t *str, const char *suffix)
{
if (str == NULL)
return NULL;
@@ -510,16 +454,16 @@ bc_string_append_escaped(bc_string_t *str, const char *suffix)
continue;
}
escaped = false;
- str = bc_string_append_c(str, suffix[i]);
+ str = sb_string_append_c(str, suffix[i]);
}
return str;
}
-bc_trie_t*
-bc_trie_new(bc_free_func_t free_func)
+sb_trie_t*
+sb_trie_new(sb_free_func_t free_func)
{
- bc_trie_t *trie = bc_malloc(sizeof(bc_trie_t));
+ sb_trie_t *trie = sb_malloc(sizeof(sb_trie_t));
trie->root = NULL;
trie->free_func = free_func;
return trie;
@@ -527,43 +471,43 @@ bc_trie_new(bc_free_func_t free_func)
static void
-bc_trie_free_node(bc_trie_t *trie, bc_trie_node_t *node)
+sb_trie_free_node(sb_trie_t *trie, sb_trie_node_t *node)
{
if (trie == NULL || node == NULL)
return;
if (node->data != NULL && trie->free_func != NULL)
trie->free_func(node->data);
- bc_trie_free_node(trie, node->next);
- bc_trie_free_node(trie, node->child);
+ sb_trie_free_node(trie, node->next);
+ sb_trie_free_node(trie, node->child);
free(node);
}
void
-bc_trie_free(bc_trie_t *trie)
+sb_trie_free(sb_trie_t *trie)
{
if (trie == NULL)
return;
- bc_trie_free_node(trie, trie->root);
+ sb_trie_free_node(trie, trie->root);
free(trie);
}
void
-bc_trie_insert(bc_trie_t *trie, const char *key, void *data)
+sb_trie_insert(sb_trie_t *trie, const char *key, void *data)
{
if (trie == NULL || key == NULL || data == NULL)
return;
- bc_trie_node_t *parent = NULL;
- bc_trie_node_t *previous;
- bc_trie_node_t *current;
- bc_trie_node_t *tmp;
+ sb_trie_node_t *parent = NULL;
+ sb_trie_node_t *previous;
+ sb_trie_node_t *current;
+ sb_trie_node_t *tmp;
while (1) {
if (trie->root == NULL || (parent != NULL && parent->child == NULL)) {
- current = bc_malloc(sizeof(bc_trie_node_t));
+ current = sb_malloc(sizeof(sb_trie_node_t));
current->key = *key;
current->data = NULL;
current->next = NULL;
@@ -589,7 +533,7 @@ bc_trie_insert(bc_trie_t *trie, const char *key, void *data)
if (previous == NULL || parent != NULL)
goto clean;
- current = bc_malloc(sizeof(bc_trie_node_t));
+ current = sb_malloc(sizeof(sb_trie_node_t));
current->key = *key;
current->data = NULL;
current->next = NULL;
@@ -610,13 +554,13 @@ clean:
void*
-bc_trie_lookup(bc_trie_t *trie, const char *key)
+sb_trie_lookup(sb_trie_t *trie, const char *key)
{
if (trie == NULL || trie->root == NULL || key == NULL)
return NULL;
- bc_trie_node_t *parent = trie->root;
- bc_trie_node_t *tmp;
+ sb_trie_node_t *parent = trie->root;
+ sb_trie_node_t *tmp;
while (1) {
for (tmp = parent; tmp != NULL; tmp = tmp->next) {
@@ -639,7 +583,7 @@ bc_trie_lookup(bc_trie_t *trie, const char *key)
static void
-bc_trie_size_node(bc_trie_node_t *node, size_t *count)
+sb_trie_size_node(sb_trie_node_t *node, size_t *count)
{
if (node == NULL || count == NULL)
return;
@@ -647,77 +591,55 @@ bc_trie_size_node(bc_trie_node_t *node, size_t *count)
if (node->key == '\0')
(*count)++;
- bc_trie_size_node(node->next, count);
- bc_trie_size_node(node->child, count);
+ sb_trie_size_node(node->next, count);
+ sb_trie_size_node(node->child, count);
}
size_t
-bc_trie_size(bc_trie_t *trie)
+sb_trie_size(sb_trie_t *trie)
{
if (trie == NULL)
return 0;
size_t count = 0;
- bc_trie_size_node(trie->root, &count);
+ sb_trie_size_node(trie->root, &count);
return count;
}
static void
-bc_trie_foreach_node(bc_trie_node_t *node, bc_string_t *str,
- bc_trie_foreach_func_t func, void *user_data)
+sb_trie_foreach_node(sb_trie_node_t *node, sb_string_t *str,
+ sb_trie_foreach_func_t func, void *user_data)
{
if (node == NULL || str == NULL || func == NULL)
return;
- if (node->key == '\0')
+ if (node->key == '\0') {
func(str->str, node->data, user_data);
+ return;
+ }
if (node->child != NULL) {
- bc_string_t *child = bc_string_dup(str);
- child = bc_string_append_c(child, node->key);
- bc_trie_foreach_node(node->child, child, func, user_data);
- bc_string_free(child, true);
+ sb_string_t *child = sb_string_dup(str);
+ child = sb_string_append_c(child, node->key);
+ sb_trie_foreach_node(node->child, child, func, user_data);
+ sb_string_free(child, true);
}
if (node->next != NULL)
- bc_trie_foreach_node(node->next, str, func, user_data);
+ sb_trie_foreach_node(node->next, str, func, user_data);
}
void
-bc_trie_foreach(bc_trie_t *trie, bc_trie_foreach_func_t func,
+sb_trie_foreach(sb_trie_t *trie, sb_trie_foreach_func_t func,
void *user_data)
{
if (trie == NULL || trie->root == NULL || func == NULL)
return;
- bc_string_t *str = bc_string_new();
- bc_trie_foreach_node(trie->root, str, func, user_data);
- bc_string_free(str, true);
-}
-
-
-char*
-bc_shell_quote(const char *command)
-{
- bc_string_t *rv = bc_string_new();
- bc_string_append_c(rv, '\'');
- if (command != NULL) {
- for (size_t i = 0; i < strlen(command); i++) {
- switch (command[i]) {
- case '!':
- bc_string_append(rv, "'\\!'");
- break;
- case '\'':
- bc_string_append(rv, "'\\''");
- break;
- default:
- bc_string_append_c(rv, command[i]);
- }
- }
- }
- bc_string_append_c(rv, '\'');
- return bc_string_free(rv, false);
+ sb_string_t *str = sb_string_new();
+ sb_trie_foreach_node(trie->root, str, func, user_data);
+ sb_string_free(str, true);
}
diff --git a/src/utils.h b/src/utils.h
new file mode 100644
index 0000000..aca02c0
--- /dev/null
+++ b/src/utils.h
@@ -0,0 +1,102 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2014-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#ifndef _UTILS_H
+#define _UTILS_H
+
+#include <stddef.h>
+#include <stdarg.h>
+#include <stdbool.h>
+
+
+// memory
+
+typedef void (*sb_free_func_t) (void *ptr);
+
+void* sb_malloc(size_t size);
+void* sb_realloc(void *ptr, size_t size);
+
+
+// slist
+
+typedef struct _sb_slist_t {
+ struct _sb_slist_t *next;
+ void *data;
+} sb_slist_t;
+
+sb_slist_t* sb_slist_append(sb_slist_t *l, void *data);
+sb_slist_t* sb_slist_prepend(sb_slist_t *l, void *data);
+void sb_slist_free(sb_slist_t *l);
+void sb_slist_free_full(sb_slist_t *l, sb_free_func_t free_func);
+size_t sb_slist_length(sb_slist_t *l);
+
+
+// strfuncs
+
+char* sb_strdup(const char *s);
+char* sb_strndup(const char *s, size_t n);
+char* sb_strdup_vprintf(const char *format, va_list ap);
+char* sb_strdup_printf(const char *format, ...);
+bool sb_str_starts_with(const char *str, const char *prefix);
+bool sb_str_ends_with(const char *str, const char *suffix);
+char* sb_str_lstrip(char *str);
+char* sb_str_rstrip(char *str);
+char* sb_str_strip(char *str);
+char** sb_str_split(const char *str, char c, unsigned int max_pieces);
+char* sb_str_replace(const char *str, const char search, const char *replace);
+char* sb_str_find(const char *str, char c);
+void sb_strv_free(char **strv);
+char* sb_strv_join(char **strv, const char *separator);
+size_t sb_strv_length(char **strv);
+
+
+// string
+
+typedef struct {
+ char *str;
+ size_t len;
+ size_t allocated_len;
+} sb_string_t;
+
+sb_string_t* sb_string_new(void);
+char* sb_string_free(sb_string_t *str, bool free_str);
+sb_string_t* sb_string_dup(sb_string_t *str);
+sb_string_t* sb_string_append_len(sb_string_t *str, const char *suffix, size_t len);
+sb_string_t* sb_string_append(sb_string_t *str, const char *suffix);
+sb_string_t* sb_string_append_c(sb_string_t *str, char c);
+sb_string_t* sb_string_append_printf(sb_string_t *str, const char *format, ...);
+sb_string_t* sb_string_append_escaped(sb_string_t *str, const char *suffix);
+
+
+// trie
+
+typedef struct _sb_trie_node_t {
+ char key;
+ void *data;
+ struct _sb_trie_node_t *next, *child;
+} sb_trie_node_t;
+
+struct _sb_trie_t {
+ sb_trie_node_t *root;
+ sb_free_func_t free_func;
+};
+
+typedef struct _sb_trie_t sb_trie_t;
+
+typedef void (*sb_trie_foreach_func_t)(const char *key, void *data,
+ void *user_data);
+
+sb_trie_t* sb_trie_new(sb_free_func_t free_func);
+void sb_trie_free(sb_trie_t *trie);
+void sb_trie_insert(sb_trie_t *trie, const char *key, void *data);
+void* sb_trie_lookup(sb_trie_t *trie, const char *key);
+size_t sb_trie_size(sb_trie_t *trie);
+void sb_trie_foreach(sb_trie_t *trie, sb_trie_foreach_func_t func,
+ void *user_data);
+
+#endif /* _UTILS_H */
diff --git a/tests/blogc-git-receiver/check_post_receive.sh.in b/tests/blogc-git-receiver/check_post_receive.sh.in
deleted file mode 100755
index 74d4df2..0000000
--- a/tests/blogc-git-receiver/check_post_receive.sh.in
+++ /dev/null
@@ -1,116 +0,0 @@
-#!@BASH@
-
-set -xe -o pipefail
-
-export LC_ALL=C
-
-TEMP="$(mktemp -d)"
-[[ -n "${TEMP}" ]]
-
-trap_func() {
- [[ -e "${TEMP}/output.txt" ]] && cat "${TEMP}/output.txt"
- [[ -n "${TEMP}" ]] && rm -rf "${TEMP}"
-}
-
-trap trap_func EXIT
-
-mkdir -p "${TEMP}/repos"
-git init --bare "${TEMP}/repos/foo.git" &> /dev/null
-
-ln -s "@abs_top_builddir@/blogc-git-receiver" "${TEMP}/repos/foo.git/hooks/post-receive"
-
-cat > "${TEMP}/tmp.txt" <<EOF
-blob
-mark :1
-data 4
-bar
-
-reset refs/heads/master
-commit refs/heads/master
-mark :2
-author Rafael G. Martins <rafael@rafaelmartins.eng.br> 1476033730 +0200
-committer Rafael G. Martins <rafael@rafaelmartins.eng.br> 1476033888 +0200
-data 11
-testing...
-M 100644 :1 foo
-
-EOF
-
-cd "${TEMP}/repos/foo.git"
-git fast-import < "${TEMP}/tmp.txt" &> /dev/null
-
-git init --bare "${TEMP}/repos/bar.git" &> /dev/null
-
-HOME="${TEMP}" ${TESTS_ENVIRONMENT} ./hooks/post-receive 2>&1 | tee "${TEMP}/output.txt"
-grep "warning: repository mirroring disabled" "${TEMP}/output.txt" &> /dev/null
-
-git config --local remote.mirror.pushurl "${TEMP}/repos/bar.git"
-HOME="${TEMP}" ${TESTS_ENVIRONMENT} ./hooks/post-receive 2>&1 | tee "${TEMP}/output.txt"
-grep "[new branch] *master" "${TEMP}/output.txt" &> /dev/null
-
-git config --local --unset remote.mirror.pushurl
-git init --bare "${TEMP}/repos/bar2.git" &> /dev/null
-git config --local remote.mirror.url "${TEMP}/repos/bar2.git"
-HOME="${TEMP}" ${TESTS_ENVIRONMENT} ./hooks/post-receive 2>&1 | tee "${TEMP}/output.txt"
-grep "[new branch] *master" "${TEMP}/output.txt" &> /dev/null
-
-git config --local --unset remote.mirror.url
-cat > "${TEMP}/blogc-git-receiver.ini" <<EOF
-[repo:boo.git]
-mirror = 123
-
-[repo:foo.git]
-mirror = ${TEMP}/repos/bar3.git
-
-[repo:bar.git]
-mirror = lol
-EOF
-git init --bare "${TEMP}/repos/bar3.git" &> /dev/null
-HOME="${TEMP}" ${TESTS_ENVIRONMENT} ./hooks/post-receive 2>&1 | tee "${TEMP}/output.txt"
-grep "[new branch] *master" "${TEMP}/output.txt" &> /dev/null
-
-cat > "${TEMP}/blogc-git-receiver.ini" <<EOF
-asd[repo:boo.git]
-mirror = 123
-
-[repo:foo.git]
-mirror = ${TEMP}/repos/bar4.git
-
-[repo:bar.git]
-mirror = lol
-EOF
-git init --bare "${TEMP}/repos/bar4.git" &> /dev/null
-HOME="${TEMP}" ${TESTS_ENVIRONMENT} ./hooks/post-receive 2>&1 | tee "${TEMP}/output.txt"
-grep "warning: failed to parse configuration file " "${TEMP}/output.txt" &> /dev/null
-
-cd ..
-cat > "${TEMP}/blogc-git-receiver.ini" <<EOF
-[repo:boo.git]
-mirror = 123
-
-[repo:foo.git]
-mirror = ${TEMP}/repos/bar5.git
-
-[repo:bar.git]
-mirror = lol
-EOF
-git init --bare "${TEMP}/repos/bar5.git" &> /dev/null
-HOME="${TEMP}" ${TESTS_ENVIRONMENT} ./foo.git/hooks/post-receive 2>&1 | tee "${TEMP}/output.txt"
-grep "[new branch] *master" "${TEMP}/output.txt" &> /dev/null
-
-cd ..
-cat > "${TEMP}/blogc-git-receiver.ini" <<EOF
-[repo:boo.git]
-mirror = 123
-
-[repo:foo.git]
-mirror = ${TEMP}/repos/bar6.git
-
-[repo:bar.git]
-mirror = lol
-EOF
-git init --bare "${TEMP}/repos/bar6.git" &> /dev/null
-BLOGC_GIT_RECEIVER_BASE_DIR="${TEMP}" ${TESTS_ENVIRONMENT} ./repos/foo.git/hooks/post-receive 2>&1 | tee "${TEMP}/output.txt"
-grep "[new branch] *master" "${TEMP}/output.txt" &> /dev/null
-
-rm "${TEMP}/output.txt"
diff --git a/tests/blogc-git-receiver/check_pre_receive.sh.in b/tests/blogc-git-receiver/check_pre_receive.sh.in
deleted file mode 100755
index 2cf3c89..0000000
--- a/tests/blogc-git-receiver/check_pre_receive.sh.in
+++ /dev/null
@@ -1,304 +0,0 @@
-#!@BASH@
-
-set -xe -o pipefail
-
-export LC_ALL=C
-
-TEMP="$(mktemp -d)"
-[[ -n "${TEMP}" ]]
-
-trap_func() {
- [[ -e "${TEMP}/output.txt" ]] && cat "${TEMP}/output.txt"
- [[ -n "${TEMP}" ]] && rm -rf "${TEMP}"
-}
-
-trap trap_func EXIT
-
-mkdir -p "${TEMP}/repos"
-git init --bare "${TEMP}/repos/foo.git" &> /dev/null
-
-SELF="@abs_top_builddir@/blogc-git-receiver"
-
-ln -s "${SELF}" "${TEMP}/repos/foo.git/hooks/pre-receive"
-
-cat > "${TEMP}/payload.txt" <<EOF
-0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 refs/heads/foo
-0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 refs/heads/bar
-EOF
-
-cd "${TEMP}/repos/foo.git"
-
-SHELL="${SELF}" HOME="${TEMP}" GIT_DIR=. ${TESTS_ENVIRONMENT} ./hooks/pre-receive < "${TEMP}/payload.txt" 2>&1 | tee "${TEMP}/output.txt"
-grep "warning: no suitable branch found. nothing to deploy." "${TEMP}/output.txt" &> /dev/null
-
-cat > "${TEMP}/tmp.txt" <<EOF
-blob
-mark :1
-data 63
-all:
- mkdir -p \$(OUTPUT_DIR)
- echo lol > \$(OUTPUT_DIR)/foo.txt
-
-reset refs/heads/master
-commit refs/heads/master
-mark :2
-author Rafael G. Martins <rafael@rafaelmartins.eng.br> 1476139736 +0200
-committer Rafael G. Martins <rafael@rafaelmartins.eng.br> 1476139736 +0200
-data 11
-testing...
-M 100644 :1 Makefil
-
-EOF
-
-git fast-import < "${TEMP}/tmp.txt" &> /dev/null
-
-cat > "${TEMP}/payload.txt" <<EOF
-0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 refs/heads/foo
-0000000000000000000000000000000000000000 $(git rev-parse master) refs/heads/master
-0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 refs/heads/main
-EOF
-
-SHELL="${SELF}" HOME="${TEMP}" GIT_DIR=. ${TESTS_ENVIRONMENT} ./hooks/pre-receive < "${TEMP}/payload.txt" 2>&1 | tee "${TEMP}/output.txt"
-grep "warning: no blogcfile or Makefile found. skipping ..." "${TEMP}/output.txt" &> /dev/null
-
-cd "${TEMP}"
-git init --bare "${TEMP}/repos/foo2.git" &> /dev/null
-ln -s "${SELF}" "${TEMP}/repos/foo2.git/hooks/pre-receive"
-
-cat > "${TEMP}/tmp.txt" <<EOF
-blob
-mark :1
-data 63
-all:
- mkdir -p \$(OUTPUT_DIR)
- echo lol > \$(OUTPUT_DIR)/foo.txt
-
-reset refs/heads/main
-commit refs/heads/main
-mark :2
-author Rafael G. Martins <rafael@rafaelmartins.eng.br> 1476139736 +0200
-committer Rafael G. Martins <rafael@rafaelmartins.eng.br> 1476139736 +0200
-data 11
-testing...
-M 100644 :1 Makefile
-
-EOF
-
-cd "${TEMP}/repos/foo2.git"
-git fast-import < "${TEMP}/tmp.txt" &> /dev/null
-
-cat > "${TEMP}/payload.txt" <<EOF
-0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 refs/heads/foo
-0000000000000000000000000000000000000000 $(git rev-parse main) refs/heads/main
-0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 refs/heads/bar
-EOF
-
-cat > "${TEMP}/blogc-git-receiver.ini" <<EOF
-[repo:foo2a.git]
-symlink = ${TEMP}/guda
-EOF
-
-SHELL="${SELF}" HOME="${TEMP}" GIT_DIR=. BLOGC_GIT_RECEIVER_BUILDS_DIR="${TEMP}/foooo" ${TESTS_ENVIRONMENT} ./hooks/pre-receive < "${TEMP}/payload.txt" 2>&1 | tee "${TEMP}/output.txt"
-grep "echo lol" "${TEMP}/output.txt" &> /dev/null
-
-[[ -h htdocs ]]
-[[ "$(cat htdocs/foo.txt)" == "lol" ]]
-
-cat >> "${TEMP}/blogc-git-receiver.ini" <<EOF
-[repo:foo2.git]
-EOF
-
-SHELL="${SELF}" HOME="${TEMP}" GIT_DIR=. BLOGC_GIT_RECEIVER_BUILDS_DIR="${TEMP}/foooo" ${TESTS_ENVIRONMENT} ./hooks/pre-receive < "${TEMP}/payload.txt" 2>&1 | tee "${TEMP}/output.txt"
-grep "echo lol" "${TEMP}/output.txt" &> /dev/null
-
-[[ -h htdocs ]]
-[[ "$(cat htdocs/foo.txt)" == "lol" ]]
-
-cat >> "${TEMP}/blogc-git-receiver.ini" <<EOF
-symlink = ${TEMP}/chunda
-EOF
-
-SHELL="${SELF}" HOME="${TEMP}" GIT_DIR=. BLOGC_GIT_RECEIVER_BUILDS_DIR="${TEMP}/foooo" ${TESTS_ENVIRONMENT} ./hooks/pre-receive < "${TEMP}/payload.txt" 2>&1 | tee "${TEMP}/output.txt"
-grep "echo lol" "${TEMP}/output.txt" &> /dev/null
-
-[[ -h "${TEMP}/chunda" ]]
-[[ "$(cat "${TEMP}/chunda/foo.txt")" == "lol" ]]
-
-DEST="$(readlink "${TEMP}/chunda")"
-[[ -e "${DEST}" ]]
-[[ "${DEST}" == "${TEMP}/foooo/"* ]]
-
-cd "${TEMP}"
-git init --bare "${TEMP}/repos/foo2a.git" &> /dev/null
-ln -s "${SELF}" "${TEMP}/repos/foo2a.git/hooks/pre-receive"
-
-cat > "${TEMP}/tmp.txt" <<EOF
-blob
-mark :1
-data 64
-all:
- mkdir -p \$(OUTPUT_DIR)
- echo lol > \$(OUTPUT_DIR)/foo.txt
-
-
-commit refs/heads/master
-mark :2
-author Rafael G. Martins <rafael@rafaelmartins.eng.br> 1476142917 +0200
-committer Rafael G. Martins <rafael@rafaelmartins.eng.br> 1476142917 +0200
-data 12
-testing2...
-M 100644 :1 Makefile
-
-EOF
-
-cd "${TEMP}/repos/foo2a.git"
-ln -s "${DEST}" "${TEMP}/guda"
-git fast-import < "${TEMP}/tmp.txt" &> /dev/null
-
-cat > "${TEMP}/payload.txt" <<EOF
-0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 refs/heads/foo
-0000000000000000000000000000000000000000 $(git rev-parse master) refs/heads/master
-0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 refs/heads/bar
-EOF
-
-SHELL="${SELF}" HOME="${TEMP}" GIT_DIR=. ${TESTS_ENVIRONMENT} ./hooks/pre-receive < "${TEMP}/payload.txt" 2>&1 | tee "${TEMP}/output.txt"
-grep "echo lol" "${TEMP}/output.txt" &> /dev/null
-
-[[ -h "${TEMP}/guda" ]]
-[[ "$(cat "${TEMP}/guda/foo.txt")" == "lol" ]]
-[[ "${DEST}" != "$(readlink "${TEMP}/guda")" ]]
-[[ ! -e "${DEST}" ]]
-
-DEST="$(readlink "${TEMP}/guda")"
-HOME="${TEMP}" ${TESTS_ENVIRONMENT} ./hooks/pre-receive 2>&1 | tee "${TEMP}/output.txt"
-
-[[ -h "${TEMP}/guda" ]]
-[[ "$(cat "${TEMP}/guda/foo.txt")" == "lol" ]]
-[[ "${DEST}" != "$(readlink "${TEMP}/guda")" ]]
-[[ ! -e "${DEST}" ]]
-
-cd ..
-
-DEST="$(readlink "${TEMP}/guda")"
-HOME="${TEMP}" ${TESTS_ENVIRONMENT} ./foo2a.git/hooks/pre-receive 2>&1 | tee "${TEMP}/output.txt"
-
-[[ -h "${TEMP}/guda" ]]
-[[ "$(cat "${TEMP}/guda/foo.txt")" == "lol" ]]
-[[ "${DEST}" != "$(readlink "${TEMP}/guda")" ]]
-[[ ! -e "${DEST}" ]]
-
-cd ..
-
-DEST="$(readlink "${TEMP}/guda")"
-HOME="${TEMP}" ${TESTS_ENVIRONMENT} ./repos/foo2a.git/hooks/pre-receive 2>&1 | tee "${TEMP}/output.txt"
-
-[[ -h "${TEMP}/guda" ]]
-[[ "$(cat "${TEMP}/guda/foo.txt")" == "lol" ]]
-[[ "${DEST}" != "$(readlink "${TEMP}/guda")" ]]
-[[ ! -e "${DEST}" ]]
-
-DEST="$(readlink "${TEMP}/guda")"
-[[ -e "${DEST}" ]]
-
-cd "${TEMP}"
-git init --bare "${TEMP}/repos/foo3.git" &> /dev/null
-ln -s "${SELF}" "${TEMP}/repos/foo3.git/hooks/pre-receive"
-
-cat > "${TEMP}/tmp.txt" <<EOF
-blob
-mark :1
-data 64
-all:
- mkdir -p \$(OUTPUT_DIR)
- echo lol > \$(OUTPUT_DIR)/foo.txt
-
-
-commit refs/heads/master
-mark :2
-author Rafael G. Martins <rafael@rafaelmartins.eng.br> 1476142917 +0200
-committer Rafael G. Martins <rafael@rafaelmartins.eng.br> 1476142917 +0200
-data 12
-testing2...
-M 100644 :1 Makefile
-
-EOF
-
-cd "${TEMP}/repos/foo3.git"
-ln -s "${DEST}" htdocs
-git fast-import < "${TEMP}/tmp.txt" &> /dev/null
-
-cat > "${TEMP}/payload.txt" <<EOF
-0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 refs/heads/foo
-0000000000000000000000000000000000000000 $(git rev-parse master) refs/heads/master
-0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 refs/heads/bar
-EOF
-
-SHELL="${SELF}" HOME="${TEMP}" GIT_DIR=. ${TESTS_ENVIRONMENT} ./hooks/pre-receive < "${TEMP}/payload.txt" 2>&1 | tee "${TEMP}/output.txt"
-grep "echo lol" "${TEMP}/output.txt" &> /dev/null
-
-[[ -h htdocs ]]
-[[ "$(cat htdocs/foo.txt)" == "lol" ]]
-[[ "${DEST}" != "$(readlink htdocs)" ]]
-[[ ! -e "${DEST}" ]]
-
-DEST="$(readlink htdocs)"
-HOME="${TEMP}" ${TESTS_ENVIRONMENT} ./hooks/pre-receive 2>&1 | tee "${TEMP}/output.txt"
-
-[[ -h htdocs ]]
-[[ "$(cat htdocs/foo.txt)" == "lol" ]]
-[[ "${DEST}" != "$(readlink htdocs)" ]]
-[[ ! -e "${DEST}" ]]
-
-cd ..
-
-DEST="$(readlink foo3.git/htdocs)"
-HOME="${TEMP}" ${TESTS_ENVIRONMENT} ./foo3.git/hooks/pre-receive 2>&1 | tee "${TEMP}/output.txt"
-
-[[ -h foo3.git/htdocs ]]
-[[ "$(cat foo3.git/htdocs/foo.txt)" == "lol" ]]
-[[ "${DEST}" != "$(readlink foo3.git/htdocs)" ]]
-[[ ! -e "${DEST}" ]]
-
-cd ..
-
-DEST="$(readlink repos/foo3.git/htdocs)"
-HOME="${TEMP}" ${TESTS_ENVIRONMENT} ./repos/foo3.git/hooks/pre-receive 2>&1 | tee "${TEMP}/output.txt"
-
-[[ -h repos/foo3.git/htdocs ]]
-[[ "$(cat repos/foo3.git/htdocs/foo.txt)" == "lol" ]]
-[[ "${DEST}" != "$(readlink repos/foo3.git/htdocs)" ]]
-[[ ! -e "${DEST}" ]]
-
-if [[ "x@MAKE_@" == "xenabled" ]]; then
- cd "${TEMP}"
- git init --bare "${TEMP}/repos/foo4.git" &> /dev/null
- ln -s "${SELF}" "${TEMP}/repos/foo4.git/hooks/pre-receive"
-
- cat > "${TEMP}/tmp.txt" <<EOF
-blob
-mark :1
-data 0
-
-reset refs/heads/master
-commit refs/heads/master
-mark :2
-author Rafael G. Martins <rafael@rafaelmartins.eng.br> 1483558736 +0100
-committer Rafael G. Martins <rafael@rafaelmartins.eng.br> 1483558736 +0100
-data 12
-testing3...
-M 100644 :1 blogcfile
-
-EOF
-
- cd "${TEMP}/repos/foo4.git"
- git fast-import < "${TEMP}/tmp.txt" &> /dev/null
-
- cat > "${TEMP}/payload.txt" <<EOF
-0000000000000000000000000000000000000000 $(git rev-parse master) refs/heads/master
-EOF
-
- SHELL="${SELF}" BLOGC_GIT_RECEIVER_BASE_DIR="${TEMP}" PATH="@abs_top_builddir@:${PATH}" GIT_DIR=. ${TESTS_ENVIRONMENT} ./hooks/pre-receive < "${TEMP}/payload.txt" 2>&1 | tee "${TEMP}/output.txt" || true
- grep "blogc-make: error: settings: " "${TEMP}/output.txt" &> /dev/null
-fi
-
-rm "${TEMP}/output.txt"
diff --git a/tests/blogc-git-receiver/check_pre_receive_parser.c b/tests/blogc-git-receiver/check_pre_receive_parser.c
deleted file mode 100644
index cad1421..0000000
--- a/tests/blogc-git-receiver/check_pre_receive_parser.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#include <stdlib.h>
-#include <string.h>
-#include "../../src/blogc-git-receiver/pre-receive-parser.h"
-
-#define _bgr_pre_receive_parse(a) bgr_pre_receive_parse(a, strlen(a))
-
-
-static void
-test_pre_receive_parse(void **state)
-{
- assert_null(_bgr_pre_receive_parse(""));
- assert_null(_bgr_pre_receive_parse(
- "4f1f932f6ef6d6c9770266775c2db072964d7a62"));
- assert_null(_bgr_pre_receive_parse(
- "4f1f932f6ef6d6c9770266775c2db072964d7a62 "));
- assert_null(_bgr_pre_receive_parse(
- "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
- "3fff4bb3172f77b292b0c913749e81bedd3545f3"));
- assert_null(_bgr_pre_receive_parse(
- "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
- "3fff4bb3172f77b292b0c913749e81bedd3545f3 "));
- assert_null(_bgr_pre_receive_parse(
- "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
- "3fff4bb3172f77b292b0c913749e81bedd3545f3 "
- "refs/heads/lol"));
- assert_null(_bgr_pre_receive_parse(
- "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
- "3fff4bb3172f77b292b0c913749e81bedd3545f3 "
- "refs/heads/lol"));
- assert_null(_bgr_pre_receive_parse(
- "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
- "3fff4bb3172f77b292b0c913749e81bedd3545f3 "
- "refs/heads/master"));
- assert_null(_bgr_pre_receive_parse(
- "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
- "3fff4bb3172f77b292b0c913749e81bedd3545f3 "
- "adgfdgdfgfdgdfgdfgdfgdfgdfg\n"));
-
- bc_trie_t *t;
- t = _bgr_pre_receive_parse(
- "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
- "3fff4bb3172f77b292b0c913749e81bedd3545f3 "
- "refs/heads/master asd\n");
- assert_non_null(t);
- assert_int_equal(bc_trie_size(t), 1);
- assert_string_equal(bc_trie_lookup(t, "master asd"),
- "3fff4bb3172f77b292b0c913749e81bedd3545f3");
- bc_trie_free(t);
-
- t = _bgr_pre_receive_parse(
- "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
- "3fff4bb3172f77b292b0c913749e81bedd3545f3 "
- "refs/heads/master\n");
- assert_non_null(t);
- assert_int_equal(bc_trie_size(t), 1);
- assert_string_equal(bc_trie_lookup(t, "master"),
- "3fff4bb3172f77b292b0c913749e81bedd3545f3");
- bc_trie_free(t);
-
- t = _bgr_pre_receive_parse(
- "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
- "3fff4bb3172f77b292b0c913749e81bedd3545fa "
- "refs/heads/master\n"
- "4f1f932f6ef6d6c9770266775c2db072964d7a63 "
- "3fff4bb3172f77b292b0c913749e81bedd3545f4 "
- "refs/heads/bola\n"
- );
- assert_non_null(t);
- assert_int_equal(bc_trie_size(t), 2);
- assert_string_equal(bc_trie_lookup(t, "master"),
- "3fff4bb3172f77b292b0c913749e81bedd3545fa");
- assert_string_equal(bc_trie_lookup(t, "bola"),
- "3fff4bb3172f77b292b0c913749e81bedd3545f4");
- bc_trie_free(t);
-
- t = _bgr_pre_receive_parse(
- "4f1f932f6ef6d6c9770266775c2db072964d7a63 "
- "3fff4bb3172f77b292b0c913749e81bedd3545f4 "
- "refs/heads/bola\n"
- "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
- "3fff4bb3172f77b292b0c913749e81bedd3545fb "
- "refs/heads/master\n"
- );
- assert_non_null(t);
- assert_int_equal(bc_trie_size(t), 2);
- assert_string_equal(bc_trie_lookup(t, "bola"),
- "3fff4bb3172f77b292b0c913749e81bedd3545f4");
- assert_string_equal(bc_trie_lookup(t, "master"),
- "3fff4bb3172f77b292b0c913749e81bedd3545fb");
- bc_trie_free(t);
-
- t = _bgr_pre_receive_parse(
- "4f1f932f6ef6d6c9770266775c2db072964d7a63 "
- "3fff4bb3172f77b292b0c913749e81bedd3545f4 "
- "refs/heads/bola\n"
- "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
- "3fff4bb3172f77b292b0c913749e81bedd3545fc "
- "refs/heads/master\n"
- "4f1f932f6ef6d6c9770266775c2db072964d7a64 "
- "3fff4bb3172f77b292b0c913749e81bedd3545f5 "
- "refs/heads/bolao\n"
- );
- assert_non_null(t);
- assert_int_equal(bc_trie_size(t), 3);
- assert_string_equal(bc_trie_lookup(t, "bola"),
- "3fff4bb3172f77b292b0c913749e81bedd3545f4");
- assert_string_equal(bc_trie_lookup(t, "master"),
- "3fff4bb3172f77b292b0c913749e81bedd3545fc");
- assert_string_equal(bc_trie_lookup(t, "bolao"),
- "3fff4bb3172f77b292b0c913749e81bedd3545f5");
- bc_trie_free(t);
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_pre_receive_parse),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/blogc-git-receiver/check_settings.c b/tests/blogc-git-receiver/check_settings.c
deleted file mode 100644
index 61cd469..0000000
--- a/tests/blogc-git-receiver/check_settings.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#include <string.h>
-#include <stdlib.h>
-#include "../../src/common/config-parser.h"
-#include "../../src/common/utils.h"
-#include "../../src/blogc-git-receiver/settings.h"
-
-
-char*
-__wrap_realpath(const char *path, char *resolved_path)
-{
- const char *real_path = mock_type(const char*);
- if (real_path == NULL)
- return NULL;
- assert_string_equal(path, real_path);
- return bc_strdup(real_path);
-}
-
-
-static void
-test_settings_get_section(void **state)
-{
- bc_error_t *err = NULL;
-
- setenv("HOME", "/home/blogc", 1);
-
- bc_config_t *config = bc_config_parse("", 0, NULL, &err);
- assert_null(err);
- assert_null(bgr_settings_get_section(config, "/home/blogc/repos/foo.git"));
- bc_config_free(config);
-
- will_return(__wrap_realpath, NULL);
- will_return(__wrap_realpath, "/home/blogc/repos/bar.git");
- const char *conf =
- "[repo:foo.git]\n"
- "mirror = foo\n"
- "\n"
- "[repo:bar.git]\n"
- "mirror = bar\n"
- "\n"
- "[repo:baz.git]\n"
- "mirror = baz\n"
- "\n";
- config = bc_config_parse(conf, strlen(conf), NULL, &err);
- assert_null(err);
- char *s = bgr_settings_get_section(config, "/home/blogc/repos/bar.git");
- assert_string_equal(s, "repo:bar.git");
- free(s);
- bc_config_free(config);
-
- setenv("BLOGC_GIT_RECEIVER_BASE_DIR", "/home/bola", 1);
- will_return(__wrap_realpath, NULL);
- will_return(__wrap_realpath, "/home/bola/repos/asd/bar.git");
- conf =
- "[repo:asd/foo.git]\n"
- "mirror = foo\n"
- "\n"
- "[repo:asd/bar.git]\n"
- "mirror = bar\n"
- "\n"
- "[repo:asd/baz.git]\n"
- "mirror = baz\n"
- "\n";
- config = bc_config_parse(conf, strlen(conf), NULL, &err);
- assert_null(err);
- s = bgr_settings_get_section(config, "/home/bola/repos/asd/bar.git");
- assert_string_equal(s, "repo:asd/bar.git");
- free(s);
- bc_config_free(config);
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_settings_get_section),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/blogc-git-receiver/check_shell.sh.in b/tests/blogc-git-receiver/check_shell.sh.in
deleted file mode 100755
index f70fc50..0000000
--- a/tests/blogc-git-receiver/check_shell.sh.in
+++ /dev/null
@@ -1,95 +0,0 @@
-#!@BASH@
-
-set -xe -o pipefail
-
-export LC_ALL=C
-
-TEMP="$(mktemp -d)"
-[[ -n "${TEMP}" ]]
-
-trap_func() {
- [[ -e "${TEMP}/output.txt" ]] && cat "${TEMP}/output.txt"
- [[ -n "${TEMP}" ]] && rm -rf "${TEMP}"
-}
-
-trap trap_func EXIT
-
-SELF="@abs_top_builddir@/blogc-git-receiver"
-
-call_bgr() {
- [[ -n "${VALGRIND}" ]] && export __VALGRIND_ENABLED=1
- SHELL="${SELF}" HOME="${TEMP}" ${TESTS_ENVIRONMENT} "${SELF}" "$@"
-}
-
-call_bgr -c "bola 'lol.git'" 2>&1 | tee "${TEMP}/output.txt" || true
-grep "error: invalid git-shell command: bola 'lol\.git'" "${TEMP}/output.txt" &> /dev/null
-
-echo 0000 | call_bgr -c "git-receive-pack 'lol.git'" 2>&1 > "${TEMP}/output.txt"
-if [[ -n "${VALGRIND}" ]]; then
- grep "git-shell -c \"git-receive-pack '.*repos/lol.git'\"" "${TEMP}/output.txt" &> /dev/null
-else
- grep "agent=" "${TEMP}/output.txt" &> /dev/null
-fi
-[[ -d "${TEMP}/repos/lol.git" ]]
-[[ -h "${TEMP}/repos/lol.git/hooks/pre-receive" ]]
-[[ "$(readlink "${TEMP}/repos/lol.git/hooks/pre-receive")" == "${SELF}" ]]
-[[ -h "${TEMP}/repos/lol.git/hooks/post-receive" ]]
-[[ "$(readlink "${TEMP}/repos/lol.git/hooks/post-receive")" == "${SELF}" ]]
-
-rm "${TEMP}/repos/lol.git/hooks/pre-receive"
-ln -s /lolheheasdxd "${TEMP}/repos/lol.git/hooks/pre-receive"
-
-echo 0000 | call_bgr -c "git-receive-pack 'lol.git'" 2>&1 > "${TEMP}/output.txt"
-if [[ -n "${VALGRIND}" ]]; then
- grep "git-shell -c \"git-receive-pack '.*repos/lol.git'\"" "${TEMP}/output.txt" &> /dev/null
-else
- grep "agent=" "${TEMP}/output.txt" &> /dev/null
-fi
-[[ -d "${TEMP}/repos/lol.git" ]]
-[[ -h "${TEMP}/repos/lol.git/hooks/pre-receive" ]]
-[[ "$(readlink "${TEMP}/repos/lol.git/hooks/pre-receive")" == "${SELF}" ]]
-[[ -h "${TEMP}/repos/lol.git/hooks/post-receive" ]]
-[[ "$(readlink "${TEMP}/repos/lol.git/hooks/post-receive")" == "${SELF}" ]]
-
-cat > "${TEMP}/tmp.txt" <<EOF
-blob
-mark :1
-data 4
-bar
-
-reset refs/heads/master
-commit refs/heads/master
-mark :2
-author Rafael G. Martins <rafael@rafaelmartins.eng.br> 1476033730 +0200
-committer Rafael G. Martins <rafael@rafaelmartins.eng.br> 1476033888 +0200
-data 11
-testing...
-M 100644 :1 foo
-
-EOF
-cd "${TEMP}/repos/lol.git"
-git fast-import < "${TEMP}/tmp.txt" &> /dev/null
-cd - > /dev/null
-
-echo 0000 | call_bgr -c "git-upload-pack 'lol.git'" 2>&1 > "${TEMP}/output.txt"
-if [[ -n "${VALGRIND}" ]]; then
- grep "git-shell -c \"git-upload-pack '.*repos/lol.git'\"" "${TEMP}/output.txt" &> /dev/null
-else
- grep "agent=" "${TEMP}/output.txt" &> /dev/null
-fi
-
-echo 0000 | SSH_ORIGINAL_COMMAND="git-upload-pack 'lol.git'" call_bgr 2>&1 > "${TEMP}/output.txt"
-if [[ -n "${VALGRIND}" ]]; then
- grep "git-shell -c \"git-upload-pack '.*repos/lol.git'\"" "${TEMP}/output.txt" &> /dev/null
-else
- grep "agent=" "${TEMP}/output.txt" &> /dev/null
-fi
-
-echo 0000 | call_bgr -c "git-upload-archive 'lol.git'" 2>&1 > "${TEMP}/output.txt" || true
-if [[ -n "${VALGRIND}" ]]; then
- grep "git-shell -c \"git-upload-archive '.*repos/lol.git'\"" "${TEMP}/output.txt" &> /dev/null
-else
- grep "ACK" "${TEMP}/output.txt" &> /dev/null
-fi
-
-rm "${TEMP}/output.txt"
diff --git a/tests/blogc-git-receiver/check_shell_command_parser.c b/tests/blogc-git-receiver/check_shell_command_parser.c
deleted file mode 100644
index eafeabb..0000000
--- a/tests/blogc-git-receiver/check_shell_command_parser.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#include <stdlib.h>
-#include "../../src/blogc-git-receiver/shell-command-parser.h"
-
-
-static void
-test_shell_command_parse(void **state)
-{
- char *t;
- assert_null(bgr_shell_command_parse(""));
- assert_null(bgr_shell_command_parse("bola"));
- assert_null(bgr_shell_command_parse("bola guda"));
- assert_null(bgr_shell_command_parse("bola 'guda'"));
- t = bgr_shell_command_parse("git-receive-pack 'bola.git'");
- assert_string_equal(t, "bola.git");
- free(t);
- t = bgr_shell_command_parse("git-upload-pack 'bolaa.git'");
- assert_string_equal(t, "bolaa.git");
- free(t);
- t = bgr_shell_command_parse("git-upload-archive 'bolab.git'");
- assert_string_equal(t, "bolab.git");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack '/bola1.git'");
- assert_string_equal(t, "bola1.git");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack '/bola2.git/'");
- assert_string_equal(t, "bola2.git/");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack 'bola3.git/'");
- assert_string_equal(t, "bola3.git/");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack 'foo/bola.git'");
- assert_string_equal(t, "foo/bola.git");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack '/foo/bola1.git'");
- assert_string_equal(t, "foo/bola1.git");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack '/foo/bola2.git/'");
- assert_string_equal(t, "foo/bola2.git/");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack 'foo/bola3.git/'");
- assert_string_equal(t, "foo/bola3.git/");
- free(t);
-
- t = bgr_shell_command_parse("git-receive-pack ''\\''bola.git'");
- assert_string_equal(t, "'bola.git");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack ''\\''/bola1.git'");
- assert_string_equal(t, "'/bola1.git");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack ''\\''/bola2.git/'");
- assert_string_equal(t, "'/bola2.git/");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack ''\\''bola3.git/'");
- assert_string_equal(t, "'bola3.git/");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack ''\\''foo/bola.git'");
- assert_string_equal(t, "'foo/bola.git");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack ''\\''/foo/bola1.git'");
- assert_string_equal(t, "'/foo/bola1.git");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack ''\\''/foo/bola2.git/'");
- assert_string_equal(t, "'/foo/bola2.git/");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack ''\\''foo/bola3.git/'");
- assert_string_equal(t, "'foo/bola3.git/");
- free(t);
-
- t = bgr_shell_command_parse("git-receive-pack 'bola.git'\\'''");
- assert_string_equal(t, "bola.git'");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack '/bola1.git'\\'''");
- assert_string_equal(t, "bola1.git'");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack '/bola2.git/'\\'''");
- assert_string_equal(t, "bola2.git/'");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack 'bola3.git/'\\'''");
- assert_string_equal(t, "bola3.git/'");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack 'foo/bola.git'\\'''");
- assert_string_equal(t, "foo/bola.git'");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack '/foo/bola1.git'\\'''");
- assert_string_equal(t, "foo/bola1.git'");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack '/foo/bola2.git/'\\'''");
- assert_string_equal(t, "foo/bola2.git/'");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack 'foo/bola3.git/'\\'''");
- assert_string_equal(t, "foo/bola3.git/'");
- free(t);
-
- t = bgr_shell_command_parse("git-receive-pack 'bo'\\''la.git'");
- assert_string_equal(t, "bo'la.git");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack '/bo'\\''la1.git'");
- assert_string_equal(t, "bo'la1.git");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack '/bo'\\''la2.git/'");
- assert_string_equal(t, "bo'la2.git/");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack 'bo'\\''la3.git/'");
- assert_string_equal(t, "bo'la3.git/");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack 'foo/bo'\\''la.git'");
- assert_string_equal(t, "foo/bo'la.git");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack '/foo/bo'\\''la1.git'");
- assert_string_equal(t, "foo/bo'la1.git");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack '/foo/bo'\\''la2.git/'");
- assert_string_equal(t, "foo/bo'la2.git/");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack 'foo/bo'\\''la3.git/'");
- assert_string_equal(t, "foo/bo'la3.git/");
- free(t);
-
- t = bgr_shell_command_parse("git-receive-pack ''\\!'bola.git'");
- assert_string_equal(t, "!bola.git");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack ''\\!'/bola1.git'");
- assert_string_equal(t, "!/bola1.git");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack ''\\!'/bola2.git/'");
- assert_string_equal(t, "!/bola2.git/");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack ''\\!'bola3.git/'");
- assert_string_equal(t, "!bola3.git/");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack ''\\!'foo/bola.git'");
- assert_string_equal(t, "!foo/bola.git");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack ''\\!'/foo/bola1.git'");
- assert_string_equal(t, "!/foo/bola1.git");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack ''\\!'/foo/bola2.git/'");
- assert_string_equal(t, "!/foo/bola2.git/");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack ''\\!'foo/bola3.git/'");
- assert_string_equal(t, "!foo/bola3.git/");
- free(t);
-
- t = bgr_shell_command_parse("git-receive-pack 'bola.git'\\!''");
- assert_string_equal(t, "bola.git!");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack '/bola1.git'\\!''");
- assert_string_equal(t, "bola1.git!");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack '/bola2.git/'\\!''");
- assert_string_equal(t, "bola2.git/!");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack 'bola3.git/'\\!''");
- assert_string_equal(t, "bola3.git/!");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack 'foo/bola.git'\\!''");
- assert_string_equal(t, "foo/bola.git!");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack '/foo/bola1.git'\\!''");
- assert_string_equal(t, "foo/bola1.git!");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack '/foo/bola2.git/'\\!''");
- assert_string_equal(t, "foo/bola2.git/!");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack 'foo/bola3.git/'\\!''");
- assert_string_equal(t, "foo/bola3.git/!");
- free(t);
-
- t = bgr_shell_command_parse("git-receive-pack 'bo'\\!'la.git'");
- assert_string_equal(t, "bo!la.git");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack '/bo'\\!'la1.git'");
- assert_string_equal(t, "bo!la1.git");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack '/bo'\\!'la2.git/'");
- assert_string_equal(t, "bo!la2.git/");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack 'bo'\\!'la3.git/'");
- assert_string_equal(t, "bo!la3.git/");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack 'foo/bo'\\!'la.git'");
- assert_string_equal(t, "foo/bo!la.git");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack '/foo/bo'\\!'la1.git'");
- assert_string_equal(t, "foo/bo!la1.git");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack '/foo/bo'\\!'la2.git/'");
- assert_string_equal(t, "foo/bo!la2.git/");
- free(t);
- t = bgr_shell_command_parse("git-receive-pack 'foo/bo'\\!'la3.git/'");
- assert_string_equal(t, "foo/bo!la3.git/");
- free(t);
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_shell_command_parse),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/blogc-make/check_atom.c b/tests/blogc-make/check_atom.c
deleted file mode 100644
index e93bc76..0000000
--- a/tests/blogc-make/check_atom.c
+++ /dev/null
@@ -1,552 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "../../src/blogc-make/atom.h"
-#include "../../src/blogc-make/settings.h"
-#include "../../src/common/file.h"
-#include "../../src/common/error.h"
-#include "../../src/common/utils.h"
-
-
-static void
-test_atom_generate_empty_file(void **state)
-{
- bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
- settings->settings = bc_trie_new(free);
- bc_trie_insert(settings->settings, "atom_prefix", bc_strdup(""));
- bc_trie_insert(settings->settings, "atom_ext", bc_strdup(".xml"));
- bc_trie_insert(settings->settings, "post_prefix", bc_strdup(""));
- bc_trie_insert(settings->settings, "html_ext", bc_strdup(".html"));
-
- char *cmp = bm_atom_generate(settings);
-
- assert_non_null(cmp);
-
- assert_string_equal(cmp,
- "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
- "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n"
- " <title type=\"text\">{{ SITE_TITLE }}{% ifdef FILTER_TAG %} - "
- "{{ FILTER_TAG }}{% endif %}</title>\n"
- " <id>{{ BASE_DOMAIN }}{{ BASE_URL }}{% ifdef FILTER_TAG %}/{{ FILTER_TAG }}"
- "{% else %}/index{% endif %}.xml</id>\n"
- " <updated>{{ DATE_FIRST_FORMATTED }}</updated>\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/\" />\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}{% ifdef FILTER_TAG %}"
- "/{{ FILTER_TAG }}{% else %}/index{% endif %}.xml\" rel=\"self\" />\n"
- " <author>\n"
- " <name>{{ AUTHOR_NAME }}</name>\n"
- " <email>{{ AUTHOR_EMAIL }}</email>\n"
- " </author>\n"
- " <subtitle type=\"text\">{{ SITE_TAGLINE }}</subtitle>\n"
- " {%- block listing %}\n"
- " <entry>\n"
- " <title type=\"text\">{{ TITLE }}</title>\n"
- " <id>{{ BASE_DOMAIN }}{{ BASE_URL }}/{{ FILENAME }}.html</id>\n"
- " <updated>{{ DATE_FORMATTED }}</updated>\n"
- " <published>{{ DATE_FORMATTED }}</published>\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/{{ FILENAME }}.html\" />\n"
- " <author>\n"
- " <name>{{ AUTHOR_NAME }}</name>\n"
- " <email>{{ AUTHOR_EMAIL }}</email>\n"
- " </author>\n"
- " <content type=\"html\"><![CDATA[{{ CONTENT }}]]></content>\n"
- " </entry>\n"
- " {%- endblock %}\n"
- "</feed>\n");
-
- free(cmp);
- bc_trie_free(settings->settings);
- free(settings);
-}
-
-
-static void
-test_atom_generate_empty_dir(void **state)
-{
- bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
- settings->settings = bc_trie_new(free);
- bc_trie_insert(settings->settings, "atom_prefix", bc_strdup(""));
- bc_trie_insert(settings->settings, "atom_ext", bc_strdup("/index.xml"));
- bc_trie_insert(settings->settings, "post_prefix", bc_strdup(""));
- bc_trie_insert(settings->settings, "html_ext", bc_strdup("/index.html"));
-
- char *cmp = bm_atom_generate(settings);
-
- assert_non_null(cmp);
-
- assert_string_equal(cmp,
- "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
- "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n"
- " <title type=\"text\">{{ SITE_TITLE }}{% ifdef FILTER_TAG %} - "
- "{{ FILTER_TAG }}{% endif %}</title>\n"
- " <id>{{ BASE_DOMAIN }}{{ BASE_URL }}{% ifdef FILTER_TAG %}/{{ FILTER_TAG }}"
- "{% endif %}/index.xml</id>\n"
- " <updated>{{ DATE_FIRST_FORMATTED }}</updated>\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/\" />\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}{% ifdef FILTER_TAG %}"
- "/{{ FILTER_TAG }}{% endif %}/index.xml\" rel=\"self\" />\n"
- " <author>\n"
- " <name>{{ AUTHOR_NAME }}</name>\n"
- " <email>{{ AUTHOR_EMAIL }}</email>\n"
- " </author>\n"
- " <subtitle type=\"text\">{{ SITE_TAGLINE }}</subtitle>\n"
- " {%- block listing %}\n"
- " <entry>\n"
- " <title type=\"text\">{{ TITLE }}</title>\n"
- " <id>{{ BASE_DOMAIN }}{{ BASE_URL }}/{{ FILENAME }}/index.html</id>\n"
- " <updated>{{ DATE_FORMATTED }}</updated>\n"
- " <published>{{ DATE_FORMATTED }}</published>\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/{{ FILENAME }}/index.html\" />\n"
- " <author>\n"
- " <name>{{ AUTHOR_NAME }}</name>\n"
- " <email>{{ AUTHOR_EMAIL }}</email>\n"
- " </author>\n"
- " <content type=\"html\"><![CDATA[{{ CONTENT }}]]></content>\n"
- " </entry>\n"
- " {%- endblock %}\n"
- "</feed>\n");
-
- free(cmp);
- bc_trie_free(settings->settings);
- free(settings);
-}
-
-
-static void
-test_atom_generate_file(void **state)
-{
- bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
- settings->settings = bc_trie_new(free);
- bc_trie_insert(settings->settings, "atom_prefix", bc_strdup("atom"));
- bc_trie_insert(settings->settings, "atom_ext", bc_strdup(".xml"));
- bc_trie_insert(settings->settings, "post_prefix", bc_strdup("post"));
- bc_trie_insert(settings->settings, "html_ext", bc_strdup(".html"));
-
- char *cmp = bm_atom_generate(settings);
-
- assert_non_null(cmp);
-
- assert_string_equal(cmp,
- "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
- "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n"
- " <title type=\"text\">{{ SITE_TITLE }}{% ifdef FILTER_TAG %} - "
- "{{ FILTER_TAG }}{% endif %}</title>\n"
- " <id>{{ BASE_DOMAIN }}{{ BASE_URL }}/atom{% ifdef FILTER_TAG %}/{{ FILTER_TAG }}"
- "{% endif %}.xml</id>\n"
- " <updated>{{ DATE_FIRST_FORMATTED }}</updated>\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/\" />\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/atom{% ifdef FILTER_TAG %}"
- "/{{ FILTER_TAG }}{% endif %}.xml\" rel=\"self\" />\n"
- " <author>\n"
- " <name>{{ AUTHOR_NAME }}</name>\n"
- " <email>{{ AUTHOR_EMAIL }}</email>\n"
- " </author>\n"
- " <subtitle type=\"text\">{{ SITE_TAGLINE }}</subtitle>\n"
- " {%- block listing %}\n"
- " <entry>\n"
- " <title type=\"text\">{{ TITLE }}</title>\n"
- " <id>{{ BASE_DOMAIN }}{{ BASE_URL }}/post/{{ FILENAME }}.html</id>\n"
- " <updated>{{ DATE_FORMATTED }}</updated>\n"
- " <published>{{ DATE_FORMATTED }}</published>\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/post/{{ FILENAME }}.html\" />\n"
- " <author>\n"
- " <name>{{ AUTHOR_NAME }}</name>\n"
- " <email>{{ AUTHOR_EMAIL }}</email>\n"
- " </author>\n"
- " <content type=\"html\"><![CDATA[{{ CONTENT }}]]></content>\n"
- " </entry>\n"
- " {%- endblock %}\n"
- "</feed>\n");
-
- free(cmp);
- bc_trie_free(settings->settings);
- free(settings);
-}
-
-
-static void
-test_atom_generate_dir(void **state)
-{
- bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
- settings->settings = bc_trie_new(free);
- bc_trie_insert(settings->settings, "atom_prefix", bc_strdup("atom"));
- bc_trie_insert(settings->settings, "atom_ext", bc_strdup("/index.xml"));
- bc_trie_insert(settings->settings, "post_prefix", bc_strdup("post"));
- bc_trie_insert(settings->settings, "html_ext", bc_strdup("/index.html"));
-
- char *cmp = bm_atom_generate(settings);
-
- assert_non_null(cmp);
-
- assert_string_equal(cmp,
- "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
- "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n"
- " <title type=\"text\">{{ SITE_TITLE }}{% ifdef FILTER_TAG %} - "
- "{{ FILTER_TAG }}{% endif %}</title>\n"
- " <id>{{ BASE_DOMAIN }}{{ BASE_URL }}/atom{% ifdef FILTER_TAG %}/{{ FILTER_TAG }}"
- "{% endif %}/index.xml</id>\n"
- " <updated>{{ DATE_FIRST_FORMATTED }}</updated>\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/\" />\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/atom{% ifdef FILTER_TAG %}"
- "/{{ FILTER_TAG }}{% endif %}/index.xml\" rel=\"self\" />\n"
- " <author>\n"
- " <name>{{ AUTHOR_NAME }}</name>\n"
- " <email>{{ AUTHOR_EMAIL }}</email>\n"
- " </author>\n"
- " <subtitle type=\"text\">{{ SITE_TAGLINE }}</subtitle>\n"
- " {%- block listing %}\n"
- " <entry>\n"
- " <title type=\"text\">{{ TITLE }}</title>\n"
- " <id>{{ BASE_DOMAIN }}{{ BASE_URL }}/post/{{ FILENAME }}/index.html</id>\n"
- " <updated>{{ DATE_FORMATTED }}</updated>\n"
- " <published>{{ DATE_FORMATTED }}</published>\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/post/{{ FILENAME }}/index.html\" />\n"
- " <author>\n"
- " <name>{{ AUTHOR_NAME }}</name>\n"
- " <email>{{ AUTHOR_EMAIL }}</email>\n"
- " </author>\n"
- " <content type=\"html\"><![CDATA[{{ CONTENT }}]]></content>\n"
- " </entry>\n"
- " {%- endblock %}\n"
- "</feed>\n");
-
- free(cmp);
- bc_trie_free(settings->settings);
- free(settings);
-}
-
-
-static void
-test_atom_empty_file(void **state)
-{
- bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
- settings->settings = bc_trie_new(free);
- bc_trie_insert(settings->settings, "atom_prefix", bc_strdup(""));
- bc_trie_insert(settings->settings, "atom_ext", bc_strdup(".xml"));
- bc_trie_insert(settings->settings, "post_prefix", bc_strdup(""));
- bc_trie_insert(settings->settings, "html_ext", bc_strdup(".html"));
-
- bc_error_t *err = NULL;
- char *rv = bm_atom_deploy(settings, &err);
-
- assert_non_null(rv);
- assert_null(err);
-
- size_t cmp_len;
- char *cmp = bc_file_get_contents(rv, true, &cmp_len, &err);
-
- assert_non_null(cmp);
- assert_null(err);
-
- assert_string_equal(cmp,
- "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
- "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n"
- " <title type=\"text\">{{ SITE_TITLE }}{% ifdef FILTER_TAG %} - "
- "{{ FILTER_TAG }}{% endif %}</title>\n"
- " <id>{{ BASE_DOMAIN }}{{ BASE_URL }}{% ifdef FILTER_TAG %}/{{ FILTER_TAG }}"
- "{% else %}/index{% endif %}.xml</id>\n"
- " <updated>{{ DATE_FIRST_FORMATTED }}</updated>\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/\" />\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}{% ifdef FILTER_TAG %}"
- "/{{ FILTER_TAG }}{% else %}/index{% endif %}.xml\" rel=\"self\" />\n"
- " <author>\n"
- " <name>{{ AUTHOR_NAME }}</name>\n"
- " <email>{{ AUTHOR_EMAIL }}</email>\n"
- " </author>\n"
- " <subtitle type=\"text\">{{ SITE_TAGLINE }}</subtitle>\n"
- " {%- block listing %}\n"
- " <entry>\n"
- " <title type=\"text\">{{ TITLE }}</title>\n"
- " <id>{{ BASE_DOMAIN }}{{ BASE_URL }}/{{ FILENAME }}.html</id>\n"
- " <updated>{{ DATE_FORMATTED }}</updated>\n"
- " <published>{{ DATE_FORMATTED }}</published>\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/{{ FILENAME }}.html\" />\n"
- " <author>\n"
- " <name>{{ AUTHOR_NAME }}</name>\n"
- " <email>{{ AUTHOR_EMAIL }}</email>\n"
- " </author>\n"
- " <content type=\"html\"><![CDATA[{{ CONTENT }}]]></content>\n"
- " </entry>\n"
- " {%- endblock %}\n"
- "</feed>\n");
-
- free(cmp);
- bm_atom_destroy(rv);
- free(rv);
- bc_trie_free(settings->settings);
- free(settings);
-}
-
-
-static void
-test_atom_empty_dir(void **state)
-{
- bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
- settings->settings = bc_trie_new(free);
- bc_trie_insert(settings->settings, "atom_prefix", bc_strdup(""));
- bc_trie_insert(settings->settings, "atom_ext", bc_strdup("/index.xml"));
- bc_trie_insert(settings->settings, "post_prefix", bc_strdup(""));
- bc_trie_insert(settings->settings, "html_ext", bc_strdup("/index.html"));
-
- bc_error_t *err = NULL;
- char *rv = bm_atom_deploy(settings, &err);
-
- assert_non_null(rv);
- assert_null(err);
-
- size_t cmp_len;
- char *cmp = bc_file_get_contents(rv, true, &cmp_len, &err);
-
- assert_non_null(cmp);
- assert_null(err);
-
- assert_string_equal(cmp,
- "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
- "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n"
- " <title type=\"text\">{{ SITE_TITLE }}{% ifdef FILTER_TAG %} - "
- "{{ FILTER_TAG }}{% endif %}</title>\n"
- " <id>{{ BASE_DOMAIN }}{{ BASE_URL }}{% ifdef FILTER_TAG %}/{{ FILTER_TAG }}"
- "{% endif %}/index.xml</id>\n"
- " <updated>{{ DATE_FIRST_FORMATTED }}</updated>\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/\" />\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}{% ifdef FILTER_TAG %}"
- "/{{ FILTER_TAG }}{% endif %}/index.xml\" rel=\"self\" />\n"
- " <author>\n"
- " <name>{{ AUTHOR_NAME }}</name>\n"
- " <email>{{ AUTHOR_EMAIL }}</email>\n"
- " </author>\n"
- " <subtitle type=\"text\">{{ SITE_TAGLINE }}</subtitle>\n"
- " {%- block listing %}\n"
- " <entry>\n"
- " <title type=\"text\">{{ TITLE }}</title>\n"
- " <id>{{ BASE_DOMAIN }}{{ BASE_URL }}/{{ FILENAME }}/index.html</id>\n"
- " <updated>{{ DATE_FORMATTED }}</updated>\n"
- " <published>{{ DATE_FORMATTED }}</published>\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/{{ FILENAME }}/index.html\" />\n"
- " <author>\n"
- " <name>{{ AUTHOR_NAME }}</name>\n"
- " <email>{{ AUTHOR_EMAIL }}</email>\n"
- " </author>\n"
- " <content type=\"html\"><![CDATA[{{ CONTENT }}]]></content>\n"
- " </entry>\n"
- " {%- endblock %}\n"
- "</feed>\n");
-
- free(cmp);
- bm_atom_destroy(rv);
- free(rv);
- bc_trie_free(settings->settings);
- free(settings);
-}
-
-
-static void
-test_atom_file(void **state)
-{
- bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
- settings->settings = bc_trie_new(free);
- bc_trie_insert(settings->settings, "atom_prefix", bc_strdup("atom"));
- bc_trie_insert(settings->settings, "atom_ext", bc_strdup(".xml"));
- bc_trie_insert(settings->settings, "post_prefix", bc_strdup("post"));
- bc_trie_insert(settings->settings, "html_ext", bc_strdup(".html"));
-
- bc_error_t *err = NULL;
- char *rv = bm_atom_deploy(settings, &err);
-
- assert_non_null(rv);
- assert_null(err);
-
- size_t cmp_len;
- char *cmp = bc_file_get_contents(rv, true, &cmp_len, &err);
-
- assert_non_null(cmp);
- assert_null(err);
-
- assert_string_equal(cmp,
- "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
- "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n"
- " <title type=\"text\">{{ SITE_TITLE }}{% ifdef FILTER_TAG %} - "
- "{{ FILTER_TAG }}{% endif %}</title>\n"
- " <id>{{ BASE_DOMAIN }}{{ BASE_URL }}/atom{% ifdef FILTER_TAG %}/{{ FILTER_TAG }}"
- "{% endif %}.xml</id>\n"
- " <updated>{{ DATE_FIRST_FORMATTED }}</updated>\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/\" />\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/atom{% ifdef FILTER_TAG %}"
- "/{{ FILTER_TAG }}{% endif %}.xml\" rel=\"self\" />\n"
- " <author>\n"
- " <name>{{ AUTHOR_NAME }}</name>\n"
- " <email>{{ AUTHOR_EMAIL }}</email>\n"
- " </author>\n"
- " <subtitle type=\"text\">{{ SITE_TAGLINE }}</subtitle>\n"
- " {%- block listing %}\n"
- " <entry>\n"
- " <title type=\"text\">{{ TITLE }}</title>\n"
- " <id>{{ BASE_DOMAIN }}{{ BASE_URL }}/post/{{ FILENAME }}.html</id>\n"
- " <updated>{{ DATE_FORMATTED }}</updated>\n"
- " <published>{{ DATE_FORMATTED }}</published>\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/post/{{ FILENAME }}.html\" />\n"
- " <author>\n"
- " <name>{{ AUTHOR_NAME }}</name>\n"
- " <email>{{ AUTHOR_EMAIL }}</email>\n"
- " </author>\n"
- " <content type=\"html\"><![CDATA[{{ CONTENT }}]]></content>\n"
- " </entry>\n"
- " {%- endblock %}\n"
- "</feed>\n");
-
- free(cmp);
- bm_atom_destroy(rv);
- free(rv);
- bc_trie_free(settings->settings);
- free(settings);
-}
-
-
-static void
-test_atom_dir(void **state)
-{
- bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
- settings->settings = bc_trie_new(free);
- bc_trie_insert(settings->settings, "atom_prefix", bc_strdup("atom"));
- bc_trie_insert(settings->settings, "atom_ext", bc_strdup("/index.xml"));
- bc_trie_insert(settings->settings, "post_prefix", bc_strdup("post"));
- bc_trie_insert(settings->settings, "html_ext", bc_strdup("/index.html"));
-
- bc_error_t *err = NULL;
- char *rv = bm_atom_deploy(settings, &err);
-
- assert_non_null(rv);
- assert_null(err);
-
- size_t cmp_len;
- char *cmp = bc_file_get_contents(rv, true, &cmp_len, &err);
-
- assert_non_null(cmp);
- assert_null(err);
-
- assert_string_equal(cmp,
- "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
- "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n"
- " <title type=\"text\">{{ SITE_TITLE }}{% ifdef FILTER_TAG %} - "
- "{{ FILTER_TAG }}{% endif %}</title>\n"
- " <id>{{ BASE_DOMAIN }}{{ BASE_URL }}/atom{% ifdef FILTER_TAG %}/{{ FILTER_TAG }}"
- "{% endif %}/index.xml</id>\n"
- " <updated>{{ DATE_FIRST_FORMATTED }}</updated>\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/\" />\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/atom{% ifdef FILTER_TAG %}"
- "/{{ FILTER_TAG }}{% endif %}/index.xml\" rel=\"self\" />\n"
- " <author>\n"
- " <name>{{ AUTHOR_NAME }}</name>\n"
- " <email>{{ AUTHOR_EMAIL }}</email>\n"
- " </author>\n"
- " <subtitle type=\"text\">{{ SITE_TAGLINE }}</subtitle>\n"
- " {%- block listing %}\n"
- " <entry>\n"
- " <title type=\"text\">{{ TITLE }}</title>\n"
- " <id>{{ BASE_DOMAIN }}{{ BASE_URL }}/post/{{ FILENAME }}/index.html</id>\n"
- " <updated>{{ DATE_FORMATTED }}</updated>\n"
- " <published>{{ DATE_FORMATTED }}</published>\n"
- " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/post/{{ FILENAME }}/index.html\" />\n"
- " <author>\n"
- " <name>{{ AUTHOR_NAME }}</name>\n"
- " <email>{{ AUTHOR_EMAIL }}</email>\n"
- " </author>\n"
- " <content type=\"html\"><![CDATA[{{ CONTENT }}]]></content>\n"
- " </entry>\n"
- " {%- endblock %}\n"
- "</feed>\n");
-
- free(cmp);
- bm_atom_destroy(rv);
- free(rv);
- bc_trie_free(settings->settings);
- free(settings);
-}
-
-
-static void
-test_atom_legacy_entry_id_empty(void **state)
-{
- bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
- settings->settings = bc_trie_new(free);
- bc_trie_insert(settings->settings, "atom_prefix", bc_strdup(""));
- bc_trie_insert(settings->settings, "atom_ext", bc_strdup(".xml"));
- bc_trie_insert(settings->settings, "post_prefix", bc_strdup(""));
- bc_trie_insert(settings->settings, "html_ext", bc_strdup(".html"));
- bc_trie_insert(settings->settings, "atom_legacy_entry_id", bc_strdup("1"));
-
- bc_error_t *err = NULL;
- char *rv = bm_atom_deploy(settings, &err);
-
- assert_null(rv);
- assert_non_null(err);
-
- assert_int_equal(err->type, BLOGC_MAKE_ERROR_ATOM);
- assert_string_equal(err->msg,
- "'atom_legacy_entry_id' setting is not supported anymore. see "
- "https://blogc.rgm.io/news/blogc-0.16.1/ for details");
-
- bc_error_free(err);
- bc_trie_free(settings->settings);
- free(settings);
-}
-
-
-static void
-test_atom_legacy_entry_id(void **state)
-{
- bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
- settings->settings = bc_trie_new(free);
- bc_trie_insert(settings->settings, "atom_prefix", bc_strdup("atom"));
- bc_trie_insert(settings->settings, "atom_ext", bc_strdup(".xml"));
- bc_trie_insert(settings->settings, "post_prefix", bc_strdup("post"));
- bc_trie_insert(settings->settings, "html_ext", bc_strdup(".html"));
- bc_trie_insert(settings->settings, "atom_legacy_entry_id", bc_strdup("1"));
-
- bc_error_t *err = NULL;
- char *rv = bm_atom_deploy(settings, &err);
-
- assert_null(rv);
- assert_non_null(err);
-
- assert_int_equal(err->type, BLOGC_MAKE_ERROR_ATOM);
- assert_string_equal(err->msg,
- "'atom_legacy_entry_id' setting is not supported anymore. see "
- "https://blogc.rgm.io/news/blogc-0.16.1/ for details");
-
- bc_error_free(err);
- bc_trie_free(settings->settings);
- free(settings);
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_atom_generate_empty_file),
- cmocka_unit_test(test_atom_generate_empty_dir),
- cmocka_unit_test(test_atom_generate_file),
- cmocka_unit_test(test_atom_generate_dir),
- cmocka_unit_test(test_atom_empty_file),
- cmocka_unit_test(test_atom_empty_dir),
- cmocka_unit_test(test_atom_file),
- cmocka_unit_test(test_atom_dir),
- cmocka_unit_test(test_atom_legacy_entry_id_empty),
- cmocka_unit_test(test_atom_legacy_entry_id),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/blogc-make/check_blogc_make.sh.in b/tests/blogc-make/check_blogc_make.sh.in
deleted file mode 100755
index 73393d4..0000000
--- a/tests/blogc-make/check_blogc_make.sh.in
+++ /dev/null
@@ -1,2463 +0,0 @@
-#!@BASH@
-
-set -xe -o pipefail
-
-export LC_ALL=C
-
-export BLOGC=@abs_top_builddir@/blogc
-
-TEMP="$(mktemp -d)"
-[[ -n "${TEMP}" ]]
-
-trap_func() {
- [[ -e "${TEMP}/output.txt" ]] && cat "${TEMP}/output.txt"
- [[ -n "${TEMP}" ]] && rm -rf "${TEMP}"
-}
-
-trap trap_func EXIT
-
-mkdir -p "${TEMP}"/proj{,/templates,/content/post}
-
-
-### minimal settings, will produce no file
-
-cat > "${TEMP}/proj/blogcfile" <<EOF
-[global]
-AUTHOR_NAME = Lol
-AUTHOR_EMAIL = author@example.com
-SITE_TITLE = Lol's Website
-SITE_TAGLINE = WAT?!
-BASE_DOMAIN = http://example.org
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1
-
-
-### default settings with some posts
-
-cat > "${TEMP}/proj/content/post/foo.txt" <<EOF
-TITLE: Foo
-DATE: 2016-10-01
-TAGS: qwe
-----------------
-This is foo.
-EOF
-
-cat > "${TEMP}/proj/content/post/bar.txt" <<EOF
-TITLE: Bar
-DATE: 2016-09-01
-TAGS: qwe
-----------------
-This is bar.
-EOF
-
-for i in $(seq -f "%02g" 1 11); do
- cat > "${TEMP}/proj/content/post/post${i}.txt" <<EOF
-TITLE: Post ${i}
-DATE: 2016-09-${i}
-TAGS: asd
-----------------
-This is Post ${i}.
-EOF
-done
-
-cat > "${TEMP}/proj/templates/main.tmpl" <<EOF
-{% block listing_entry %}{{ CONTENT }}{% endblock %}{% block listing %}
-Listing: {% ifdef FILTER_TAG %}{{ FILTER_TAG }} - {% endif %}{{ TITLE }} - {{ DATE_FORMATTED }}
-{% endblock %}
-{% block entry %}
-{{ TITLE }}{% if MAKE_TYPE == "post" %} - {{ DATE_FORMATTED }}{% endif %}
-
-{{ CONTENT }}
-{% endblock %}
-EOF
-
-cat >> "${TEMP}/proj/blogcfile" <<EOF
-[posts]
-foo
-bar
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1 | tee "${TEMP}/output.txt"
-grep "_build/index\\.html" "${TEMP}/output.txt"
-grep "_build/atom\\.xml" "${TEMP}/output.txt"
-grep "_build/page/1/index\\.html" "${TEMP}/output.txt"
-grep -v "_build/page/2/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/foo/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/bar/index\\.html" "${TEMP}/output.txt"
-
-rm "${TEMP}/output.txt"
-
-cat > "${TEMP}/expected-index.html" <<EOF
-
-Listing: Bar - Sep 01, 2016, 12:00 AM GMT
-
-Listing: Foo - Oct 01, 2016, 12:00 AM GMT
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/index.html" "${TEMP}/expected-index.html"
-diff -uN "${TEMP}/proj/_build/page/1/index.html" "${TEMP}/expected-index.html"
-
-cat > "${TEMP}/expected-atom.xml" <<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Lol's Website</title>
- <id>http://example.org/atom.xml</id>
- <updated>2016-09-01T00:00:00Z</updated>
- <link href="http://example.org/" />
- <link href="http://example.org/atom.xml" rel="self" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <subtitle type="text">WAT?!</subtitle>
- <entry>
- <title type="text">Bar</title>
- <id>http://example.org/post/bar/index.html</id>
- <updated>2016-09-01T00:00:00Z</updated>
- <published>2016-09-01T00:00:00Z</published>
- <link href="http://example.org/post/bar/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is bar.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Foo</title>
- <id>http://example.org/post/foo/index.html</id>
- <updated>2016-10-01T00:00:00Z</updated>
- <published>2016-10-01T00:00:00Z</published>
- <link href="http://example.org/post/foo/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is foo.</p>
-]]></content>
- </entry>
-</feed>
-EOF
-diff -uN "${TEMP}/proj/_build/atom.xml" "${TEMP}/expected-atom.xml"
-
-cat > "${TEMP}/expected-post-foo.html" <<EOF
-
-
-Foo - Oct 01, 2016, 12:00 AM GMT
-
-<p>This is foo.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/post/foo/index.html" "${TEMP}/expected-post-foo.html"
-
-cat > "${TEMP}/expected-post-bar.html" <<EOF
-
-
-Bar - Sep 01, 2016, 12:00 AM GMT
-
-<p>This is bar.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/post/bar/index.html" "${TEMP}/expected-post-bar.html"
-
-rm -rf "${TEMP}/proj/_build"
-
-
-### default settings with some posts, posts per page -1
-
-cat > "${TEMP}/proj/blogcfile" <<EOF
-[global]
-AUTHOR_NAME = Lol
-AUTHOR_EMAIL = author@example.com
-SITE_TITLE = Lol's Website
-SITE_TAGLINE = WAT?!
-BASE_DOMAIN = http://example.org
-
-[settings]
-posts_per_page = -1
-atom_posts_per_page = -1
-
-[posts]
-post01
-post02
-post03
-post04
-post05
-post06
-post07
-post08
-post09
-post10
-post11
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1 | tee "${TEMP}/output.txt"
-grep "_build/index\\.html" "${TEMP}/output.txt"
-grep "_build/atom\\.xml" "${TEMP}/output.txt"
-grep "_build/post/post01/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post02/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post03/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post04/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post05/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post06/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post07/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post08/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post09/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post10/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post11/index\\.html" "${TEMP}/output.txt"
-
-rm "${TEMP}/output.txt"
-
-cat > "${TEMP}/expected-index.html" <<EOF
-
-Listing: Post 11 - Sep 11, 2016, 12:00 AM GMT
-
-Listing: Post 10 - Sep 10, 2016, 12:00 AM GMT
-
-Listing: Post 09 - Sep 09, 2016, 12:00 AM GMT
-
-Listing: Post 08 - Sep 08, 2016, 12:00 AM GMT
-
-Listing: Post 07 - Sep 07, 2016, 12:00 AM GMT
-
-Listing: Post 06 - Sep 06, 2016, 12:00 AM GMT
-
-Listing: Post 05 - Sep 05, 2016, 12:00 AM GMT
-
-Listing: Post 04 - Sep 04, 2016, 12:00 AM GMT
-
-Listing: Post 03 - Sep 03, 2016, 12:00 AM GMT
-
-Listing: Post 02 - Sep 02, 2016, 12:00 AM GMT
-
-Listing: Post 01 - Sep 01, 2016, 12:00 AM GMT
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/index.html" "${TEMP}/expected-index.html"
-
-cat > "${TEMP}/expected-atom.xml" <<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Lol's Website</title>
- <id>http://example.org/atom.xml</id>
- <updated>2016-09-11T00:00:00Z</updated>
- <link href="http://example.org/" />
- <link href="http://example.org/atom.xml" rel="self" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <subtitle type="text">WAT?!</subtitle>
- <entry>
- <title type="text">Post 11</title>
- <id>http://example.org/post/post11/index.html</id>
- <updated>2016-09-11T00:00:00Z</updated>
- <published>2016-09-11T00:00:00Z</published>
- <link href="http://example.org/post/post11/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 11.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Post 10</title>
- <id>http://example.org/post/post10/index.html</id>
- <updated>2016-09-10T00:00:00Z</updated>
- <published>2016-09-10T00:00:00Z</published>
- <link href="http://example.org/post/post10/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 10.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Post 09</title>
- <id>http://example.org/post/post09/index.html</id>
- <updated>2016-09-09T00:00:00Z</updated>
- <published>2016-09-09T00:00:00Z</published>
- <link href="http://example.org/post/post09/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 09.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Post 08</title>
- <id>http://example.org/post/post08/index.html</id>
- <updated>2016-09-08T00:00:00Z</updated>
- <published>2016-09-08T00:00:00Z</published>
- <link href="http://example.org/post/post08/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 08.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Post 07</title>
- <id>http://example.org/post/post07/index.html</id>
- <updated>2016-09-07T00:00:00Z</updated>
- <published>2016-09-07T00:00:00Z</published>
- <link href="http://example.org/post/post07/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 07.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Post 06</title>
- <id>http://example.org/post/post06/index.html</id>
- <updated>2016-09-06T00:00:00Z</updated>
- <published>2016-09-06T00:00:00Z</published>
- <link href="http://example.org/post/post06/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 06.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Post 05</title>
- <id>http://example.org/post/post05/index.html</id>
- <updated>2016-09-05T00:00:00Z</updated>
- <published>2016-09-05T00:00:00Z</published>
- <link href="http://example.org/post/post05/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 05.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Post 04</title>
- <id>http://example.org/post/post04/index.html</id>
- <updated>2016-09-04T00:00:00Z</updated>
- <published>2016-09-04T00:00:00Z</published>
- <link href="http://example.org/post/post04/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 04.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Post 03</title>
- <id>http://example.org/post/post03/index.html</id>
- <updated>2016-09-03T00:00:00Z</updated>
- <published>2016-09-03T00:00:00Z</published>
- <link href="http://example.org/post/post03/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 03.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Post 02</title>
- <id>http://example.org/post/post02/index.html</id>
- <updated>2016-09-02T00:00:00Z</updated>
- <published>2016-09-02T00:00:00Z</published>
- <link href="http://example.org/post/post02/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 02.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Post 01</title>
- <id>http://example.org/post/post01/index.html</id>
- <updated>2016-09-01T00:00:00Z</updated>
- <published>2016-09-01T00:00:00Z</published>
- <link href="http://example.org/post/post01/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 01.</p>
-]]></content>
- </entry>
-</feed>
-EOF
-diff -uN "${TEMP}/proj/_build/atom.xml" "${TEMP}/expected-atom.xml"
-
-cat > "${TEMP}/expected-post-post01.html" <<EOF
-
-
-Post 01 - Sep 01, 2016, 12:00 AM GMT
-
-<p>This is Post 01.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/post/post01/index.html" "${TEMP}/expected-post-post01.html"
-
-cat > "${TEMP}/expected-post-post11.html" <<EOF
-
-
-Post 11 - Sep 11, 2016, 12:00 AM GMT
-
-<p>This is Post 11.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/post/post11/index.html" "${TEMP}/expected-post-post11.html"
-
-rm -rf "${TEMP}/proj/_build"
-
-
-### default settings with some posts, custom atom template
-
-cat > "${TEMP}/proj/blogcfile" <<EOF
-[global]
-AUTHOR_NAME = Lol
-AUTHOR_EMAIL = author@example.com
-SITE_TITLE = Lol's Website
-SITE_TAGLINE = WAT?!
-BASE_DOMAIN = http://example.org
-
-[settings]
-posts_per_page = -1
-atom_posts_per_page = -1
-atom_template = atom.tmpl
-
-[posts]
-post01
-post02
-post03
-post04
-post05
-post06
-post07
-post08
-post09
-post10
-post11
-EOF
-
-cat > "${TEMP}/proj/templates/atom.tmpl" <<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">{{ SITE_TITLE }}{% ifdef FILTER_TAG %} - {{ FILTER_TAG }}{% endif %}</title>
- <id>{{ BASE_DOMAIN }}{{ BASE_URL }}/atom/{% ifdef FILTER_TAG %}{{ FILTER_TAG }}/{% endif %}</id>
- <updated>{{ DATE_FIRST_FORMATTED }}</updated>
- <link href="{{ BASE_DOMAIN }}{{ BASE_URL }}/" />
- <link href="{{ BASE_DOMAIN }}{{ BASE_URL }}/atom/{% ifdef FILTER_TAG %}{{ FILTER_TAG }}/{% endif %}" rel="self" />
- <author>
- <name>{{ AUTHOR_NAME }}</name>
- <email>{{ AUTHOR_EMAIL }}</email>
- </author>
- <subtitle type="text">{{ SITE_TAGLINE }}</subtitle>
- {%- block listing %}
- <entry>
- <title type="text">{{ TITLE }}</title>
- <id>{{ BASE_DOMAIN }}{{ BASE_URL }}/post/{{ FILENAME }}/</id>
- <updated>{{ DATE_FORMATTED }}</updated>
- <published>{{ DATE_FORMATTED }}</published>
- <link href="{{ BASE_DOMAIN }}{{ BASE_URL }}/post/{{ FILENAME }}/" />
- <author>
- <name>{{ AUTHOR_NAME }}</name>
- <email>{{ AUTHOR_EMAIL }}</email>
- </author>
- <content type="html"><![CDATA[{{ CONTENT }}]]></content>
- </entry>
- {%- endblock %}
-</feed>
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1 | tee "${TEMP}/output.txt"
-grep "_build/index\\.html" "${TEMP}/output.txt"
-grep "_build/atom\\.xml" "${TEMP}/output.txt"
-grep "_build/post/post01/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post02/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post03/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post04/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post05/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post06/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post07/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post08/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post09/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post10/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post11/index\\.html" "${TEMP}/output.txt"
-
-rm "${TEMP}/output.txt"
-
-cat > "${TEMP}/expected-atom.xml" <<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Lol's Website</title>
- <id>http://example.org/atom/</id>
- <updated>2016-09-11T00:00:00Z</updated>
- <link href="http://example.org/" />
- <link href="http://example.org/atom/" rel="self" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <subtitle type="text">WAT?!</subtitle>
- <entry>
- <title type="text">Post 11</title>
- <id>http://example.org/post/post11/</id>
- <updated>2016-09-11T00:00:00Z</updated>
- <published>2016-09-11T00:00:00Z</published>
- <link href="http://example.org/post/post11/" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 11.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Post 10</title>
- <id>http://example.org/post/post10/</id>
- <updated>2016-09-10T00:00:00Z</updated>
- <published>2016-09-10T00:00:00Z</published>
- <link href="http://example.org/post/post10/" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 10.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Post 09</title>
- <id>http://example.org/post/post09/</id>
- <updated>2016-09-09T00:00:00Z</updated>
- <published>2016-09-09T00:00:00Z</published>
- <link href="http://example.org/post/post09/" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 09.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Post 08</title>
- <id>http://example.org/post/post08/</id>
- <updated>2016-09-08T00:00:00Z</updated>
- <published>2016-09-08T00:00:00Z</published>
- <link href="http://example.org/post/post08/" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 08.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Post 07</title>
- <id>http://example.org/post/post07/</id>
- <updated>2016-09-07T00:00:00Z</updated>
- <published>2016-09-07T00:00:00Z</published>
- <link href="http://example.org/post/post07/" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 07.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Post 06</title>
- <id>http://example.org/post/post06/</id>
- <updated>2016-09-06T00:00:00Z</updated>
- <published>2016-09-06T00:00:00Z</published>
- <link href="http://example.org/post/post06/" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 06.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Post 05</title>
- <id>http://example.org/post/post05/</id>
- <updated>2016-09-05T00:00:00Z</updated>
- <published>2016-09-05T00:00:00Z</published>
- <link href="http://example.org/post/post05/" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 05.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Post 04</title>
- <id>http://example.org/post/post04/</id>
- <updated>2016-09-04T00:00:00Z</updated>
- <published>2016-09-04T00:00:00Z</published>
- <link href="http://example.org/post/post04/" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 04.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Post 03</title>
- <id>http://example.org/post/post03/</id>
- <updated>2016-09-03T00:00:00Z</updated>
- <published>2016-09-03T00:00:00Z</published>
- <link href="http://example.org/post/post03/" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 03.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Post 02</title>
- <id>http://example.org/post/post02/</id>
- <updated>2016-09-02T00:00:00Z</updated>
- <published>2016-09-02T00:00:00Z</published>
- <link href="http://example.org/post/post02/" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 02.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Post 01</title>
- <id>http://example.org/post/post01/</id>
- <updated>2016-09-01T00:00:00Z</updated>
- <published>2016-09-01T00:00:00Z</published>
- <link href="http://example.org/post/post01/" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is Post 01.</p>
-]]></content>
- </entry>
-</feed>
-EOF
-diff -uN "${TEMP}/proj/_build/atom.xml" "${TEMP}/expected-atom.xml"
-
-rm -rf "${TEMP}/proj/_build"
-
-
-### default settings with some posts, atom posts per page 0
-
-cat > "${TEMP}/proj/blogcfile" <<EOF
-[global]
-AUTHOR_NAME = Lol
-AUTHOR_EMAIL = author@example.com
-SITE_TITLE = Lol's Website
-SITE_TAGLINE = WAT?!
-BASE_DOMAIN = http://example.org
-
-[settings]
-atom_posts_per_page = 0
-posts_per_page = 0
-
-[posts]
-post01
-post02
-post03
-post04
-post05
-post06
-post07
-post08
-post09
-post10
-post11
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1 | tee "${TEMP}/output.txt"
-grep "_build/post/post01/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post02/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post03/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post04/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post05/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post06/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post07/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post08/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post09/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post10/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post11/index\\.html" "${TEMP}/output.txt"
-
-rm "${TEMP}/output.txt"
-
-cat > "${TEMP}/expected-post-post01.html" <<EOF
-
-
-Post 01 - Sep 01, 2016, 12:00 AM GMT
-
-<p>This is Post 01.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/post/post01/index.html" "${TEMP}/expected-post-post01.html"
-
-cat > "${TEMP}/expected-post-post11.html" <<EOF
-
-
-Post 11 - Sep 11, 2016, 12:00 AM GMT
-
-<p>This is Post 11.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/post/post11/index.html" "${TEMP}/expected-post-post11.html"
-
-rm -rf "${TEMP}/proj/_build"
-
-
-### default settings with some posts and tags pagination
-
-cat > "${TEMP}/proj/blogcfile" <<EOF
-[global]
-AUTHOR_NAME = Lol
-AUTHOR_EMAIL = author@example.com
-SITE_TITLE = Lol's Website
-SITE_TAGLINE = WAT?!
-BASE_DOMAIN = http://example.org
-
-[settings]
-atom_posts_per_page = 0
-posts_per_page = 3
-
-[posts]
-foo
-bar
-post01
-post02
-post03
-post04
-post05
-post06
-post07
-post08
-post09
-post10
-post11
-
-[tags]
-qwe
-asd
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1 | tee "${TEMP}/output.txt"
-grep "_build/post/post01/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post02/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post03/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post04/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post05/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post06/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post07/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post08/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post09/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post10/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/post11/index\\.html" "${TEMP}/output.txt"
-grep "_build/tag/asd/index\\.html" "${TEMP}/output.txt"
-grep "_build/tag/asd/page/1/index\\.html" "${TEMP}/output.txt"
-grep "_build/tag/asd/page/2/index\\.html" "${TEMP}/output.txt"
-grep "_build/tag/asd/page/3/index\\.html" "${TEMP}/output.txt"
-grep "_build/tag/asd/page/4/index\\.html" "${TEMP}/output.txt"
-grep -v "_build/tag/asd/page/5/index\\.html" "${TEMP}/output.txt"
-grep "_build/tag/qwe/index\\.html" "${TEMP}/output.txt"
-grep "_build/tag/qwe/page/1/index\\.html" "${TEMP}/output.txt"
-grep -v "_build/tag/qwe/page/2/index\\.html" "${TEMP}/output.txt"
-
-rm "${TEMP}/output.txt"
-
-cat > "${TEMP}/expected-tag-asd1.html" <<EOF
-
-Listing: asd - Post 11 - Sep 11, 2016, 12:00 AM GMT
-
-Listing: asd - Post 10 - Sep 10, 2016, 12:00 AM GMT
-
-Listing: asd - Post 09 - Sep 09, 2016, 12:00 AM GMT
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/tag/asd/index.html" "${TEMP}/expected-tag-asd1.html"
-diff -uN "${TEMP}/proj/_build/tag/asd/page/1/index.html" "${TEMP}/expected-tag-asd1.html"
-
-cat > "${TEMP}/expected-tag-asd2.html" <<EOF
-
-Listing: asd - Post 08 - Sep 08, 2016, 12:00 AM GMT
-
-Listing: asd - Post 07 - Sep 07, 2016, 12:00 AM GMT
-
-Listing: asd - Post 06 - Sep 06, 2016, 12:00 AM GMT
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/tag/asd/page/2/index.html" "${TEMP}/expected-tag-asd2.html"
-
-cat > "${TEMP}/expected-tag-asd3.html" <<EOF
-
-Listing: asd - Post 05 - Sep 05, 2016, 12:00 AM GMT
-
-Listing: asd - Post 04 - Sep 04, 2016, 12:00 AM GMT
-
-Listing: asd - Post 03 - Sep 03, 2016, 12:00 AM GMT
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/tag/asd/page/3/index.html" "${TEMP}/expected-tag-asd3.html"
-
-cat > "${TEMP}/expected-tag-asd4.html" <<EOF
-
-Listing: asd - Post 02 - Sep 02, 2016, 12:00 AM GMT
-
-Listing: asd - Post 01 - Sep 01, 2016, 12:00 AM GMT
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/tag/asd/page/4/index.html" "${TEMP}/expected-tag-asd4.html"
-
-cat > "${TEMP}/expected-tag-qwe1.html" <<EOF
-
-Listing: qwe - Bar - Sep 01, 2016, 12:00 AM GMT
-
-Listing: qwe - Foo - Oct 01, 2016, 12:00 AM GMT
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/tag/qwe/index.html" "${TEMP}/expected-tag-qwe1.html"
-diff -uN "${TEMP}/proj/_build/tag/qwe/page/1/index.html" "${TEMP}/expected-tag-qwe1.html"
-
-rm -rf "${TEMP}/proj/_build"
-
-
-### default settings with some posts, order asc, posts_sort
-
-cat > "${TEMP}/proj/blogcfile" <<EOF
-[global]
-AUTHOR_NAME = Lol
-AUTHOR_EMAIL = author@example.com
-SITE_TITLE = Lol's Website
-SITE_TAGLINE = WAT?!
-BASE_DOMAIN = http://example.org
-
-[settings]
-html_order = asc
-atom_order = asc
-posts_sort = yes
-
-[posts]
-foo
-bar
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1 | tee "${TEMP}/output.txt"
-grep "_build/index\\.html" "${TEMP}/output.txt"
-grep "_build/atom\\.xml" "${TEMP}/output.txt"
-grep "_build/page/1/index\\.html" "${TEMP}/output.txt"
-grep -v "_build/page/2/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/foo/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/bar/index\\.html" "${TEMP}/output.txt"
-
-rm "${TEMP}/output.txt"
-
-cat > "${TEMP}/expected-index.html" <<EOF
-
-Listing: Bar - Sep 01, 2016, 12:00 AM GMT
-
-Listing: Foo - Oct 01, 2016, 12:00 AM GMT
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/index.html" "${TEMP}/expected-index.html"
-diff -uN "${TEMP}/proj/_build/page/1/index.html" "${TEMP}/expected-index.html"
-
-cat > "${TEMP}/expected-atom.xml" <<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Lol's Website</title>
- <id>http://example.org/atom.xml</id>
- <updated>2016-09-01T00:00:00Z</updated>
- <link href="http://example.org/" />
- <link href="http://example.org/atom.xml" rel="self" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <subtitle type="text">WAT?!</subtitle>
- <entry>
- <title type="text">Bar</title>
- <id>http://example.org/post/bar/index.html</id>
- <updated>2016-09-01T00:00:00Z</updated>
- <published>2016-09-01T00:00:00Z</published>
- <link href="http://example.org/post/bar/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is bar.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Foo</title>
- <id>http://example.org/post/foo/index.html</id>
- <updated>2016-10-01T00:00:00Z</updated>
- <published>2016-10-01T00:00:00Z</published>
- <link href="http://example.org/post/foo/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is foo.</p>
-]]></content>
- </entry>
-</feed>
-EOF
-diff -uN "${TEMP}/proj/_build/atom.xml" "${TEMP}/expected-atom.xml"
-
-cat > "${TEMP}/expected-post-foo.html" <<EOF
-
-
-Foo - Oct 01, 2016, 12:00 AM GMT
-
-<p>This is foo.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/post/foo/index.html" "${TEMP}/expected-post-foo.html"
-
-cat > "${TEMP}/expected-post-bar.html" <<EOF
-
-
-Bar - Sep 01, 2016, 12:00 AM GMT
-
-<p>This is bar.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/post/bar/index.html" "${TEMP}/expected-post-bar.html"
-
-rm -rf "${TEMP}/proj/_build"
-
-
-### default settings with some posts, order desc, posts_sort
-
-cat > "${TEMP}/proj/blogcfile" <<EOF
-[global]
-AUTHOR_NAME = Lol
-AUTHOR_EMAIL = author@example.com
-SITE_TITLE = Lol's Website
-SITE_TAGLINE = WAT?!
-BASE_DOMAIN = http://example.org
-
-[settings]
-posts_sort = yes
-
-[posts]
-foo
-bar
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1 | tee "${TEMP}/output.txt"
-grep "_build/index\\.html" "${TEMP}/output.txt"
-grep "_build/atom\\.xml" "${TEMP}/output.txt"
-grep "_build/page/1/index\\.html" "${TEMP}/output.txt"
-grep -v "_build/page/2/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/foo/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/bar/index\\.html" "${TEMP}/output.txt"
-
-rm "${TEMP}/output.txt"
-
-cat > "${TEMP}/expected-index.html" <<EOF
-
-Listing: Foo - Oct 01, 2016, 12:00 AM GMT
-
-Listing: Bar - Sep 01, 2016, 12:00 AM GMT
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/index.html" "${TEMP}/expected-index.html"
-diff -uN "${TEMP}/proj/_build/page/1/index.html" "${TEMP}/expected-index.html"
-
-cat > "${TEMP}/expected-atom.xml" <<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Lol's Website</title>
- <id>http://example.org/atom.xml</id>
- <updated>2016-10-01T00:00:00Z</updated>
- <link href="http://example.org/" />
- <link href="http://example.org/atom.xml" rel="self" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <subtitle type="text">WAT?!</subtitle>
- <entry>
- <title type="text">Foo</title>
- <id>http://example.org/post/foo/index.html</id>
- <updated>2016-10-01T00:00:00Z</updated>
- <published>2016-10-01T00:00:00Z</published>
- <link href="http://example.org/post/foo/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is foo.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Bar</title>
- <id>http://example.org/post/bar/index.html</id>
- <updated>2016-09-01T00:00:00Z</updated>
- <published>2016-09-01T00:00:00Z</published>
- <link href="http://example.org/post/bar/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is bar.</p>
-]]></content>
- </entry>
-</feed>
-EOF
-diff -uN "${TEMP}/proj/_build/atom.xml" "${TEMP}/expected-atom.xml"
-
-cat > "${TEMP}/expected-post-foo.html" <<EOF
-
-
-Foo - Oct 01, 2016, 12:00 AM GMT
-
-<p>This is foo.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/post/foo/index.html" "${TEMP}/expected-post-foo.html"
-
-cat > "${TEMP}/expected-post-bar.html" <<EOF
-
-
-Bar - Sep 01, 2016, 12:00 AM GMT
-
-<p>This is bar.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/post/bar/index.html" "${TEMP}/expected-post-bar.html"
-
-rm -rf "${TEMP}/proj/_build"
-
-
-### default settings with some posts, order asc, listing_entry
-
-cat > "${TEMP}/proj/content/hue.txt" <<EOF
-TITLE: Hue
-----------------
-This is hue.
-EOF
-
-cat > "${TEMP}/proj/blogcfile" <<EOF
-[global]
-AUTHOR_NAME = Lol
-AUTHOR_EMAIL = author@example.com
-SITE_TITLE = Lol's Website
-SITE_TAGLINE = WAT?!
-BASE_DOMAIN = http://example.org
-
-[settings]
-html_order = ASC
-atom_order = ASC
-listing_entry = hue
-
-[posts]
-foo
-bar
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1 | tee "${TEMP}/output.txt"
-grep "_build/index\\.html" "${TEMP}/output.txt"
-grep "_build/atom\\.xml" "${TEMP}/output.txt"
-grep "_build/page/1/index\\.html" "${TEMP}/output.txt"
-grep -v "_build/page/2/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/foo/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/bar/index\\.html" "${TEMP}/output.txt"
-
-rm "${TEMP}/output.txt"
-
-cat > "${TEMP}/expected-index.html" <<EOF
-<p>This is hue.</p>
-
-Listing: Foo - Oct 01, 2016, 12:00 AM GMT
-
-Listing: Bar - Sep 01, 2016, 12:00 AM GMT
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/index.html" "${TEMP}/expected-index.html"
-diff -uN "${TEMP}/proj/_build/page/1/index.html" "${TEMP}/expected-index.html"
-
-cat > "${TEMP}/expected-atom.xml" <<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Lol's Website</title>
- <id>http://example.org/atom.xml</id>
- <updated>2016-10-01T00:00:00Z</updated>
- <link href="http://example.org/" />
- <link href="http://example.org/atom.xml" rel="self" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <subtitle type="text">WAT?!</subtitle>
- <entry>
- <title type="text">Foo</title>
- <id>http://example.org/post/foo/index.html</id>
- <updated>2016-10-01T00:00:00Z</updated>
- <published>2016-10-01T00:00:00Z</published>
- <link href="http://example.org/post/foo/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is foo.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Bar</title>
- <id>http://example.org/post/bar/index.html</id>
- <updated>2016-09-01T00:00:00Z</updated>
- <published>2016-09-01T00:00:00Z</published>
- <link href="http://example.org/post/bar/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is bar.</p>
-]]></content>
- </entry>
-</feed>
-EOF
-diff -uN "${TEMP}/proj/_build/atom.xml" "${TEMP}/expected-atom.xml"
-
-cat > "${TEMP}/expected-post-foo.html" <<EOF
-
-
-Foo - Oct 01, 2016, 12:00 AM GMT
-
-<p>This is foo.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/post/foo/index.html" "${TEMP}/expected-post-foo.html"
-
-cat > "${TEMP}/expected-post-bar.html" <<EOF
-
-
-Bar - Sep 01, 2016, 12:00 AM GMT
-
-<p>This is bar.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/post/bar/index.html" "${TEMP}/expected-post-bar.html"
-
-rm -rf "${TEMP}/proj/_build"
-
-
-### default settings with some posts and tags, order asc, listing_entry
-
-cat > "${TEMP}/proj/content/post/baz.txt" <<EOF
-TITLE: Baz
-DATE: 2016-08-01
-TAGS: tag1 tag2
-----------------
-This is baz.
-EOF
-
-cat >> "${TEMP}/proj/blogcfile" <<EOF
-baz
-[tags]
-tag1
-tag2
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1 | tee "${TEMP}/output.txt"
-grep "_build/index\\.html" "${TEMP}/output.txt"
-grep "_build/atom\\.xml" "${TEMP}/output.txt"
-grep "_build/atom/tag1\\.xml" "${TEMP}/output.txt"
-grep "_build/atom/tag2\\.xml" "${TEMP}/output.txt"
-grep "_build/page/1/index\\.html" "${TEMP}/output.txt"
-grep -v "_build/page/2/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/foo/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/bar/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/baz/index\\.html" "${TEMP}/output.txt"
-grep "_build/tag/tag1/index\\.html" "${TEMP}/output.txt"
-grep "_build/tag/tag1/page/1/index\\.html" "${TEMP}/output.txt"
-grep -v "_build/tag/tag1/page/2/index\\.html" "${TEMP}/output.txt"
-grep "_build/tag/tag2/index\\.html" "${TEMP}/output.txt"
-grep "_build/tag/tag2/page/1/index\\.html" "${TEMP}/output.txt"
-grep -v "_build/tag/tag2/page/2/index\\.html" "${TEMP}/output.txt"
-
-rm "${TEMP}/output.txt"
-
-cat > "${TEMP}/expected-index.html" <<EOF
-<p>This is hue.</p>
-
-Listing: Foo - Oct 01, 2016, 12:00 AM GMT
-
-Listing: Bar - Sep 01, 2016, 12:00 AM GMT
-
-Listing: Baz - Aug 01, 2016, 12:00 AM GMT
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/index.html" "${TEMP}/expected-index.html"
-diff -uN "${TEMP}/proj/_build/page/1/index.html" "${TEMP}/expected-index.html"
-
-cat > "${TEMP}/expected-atom.xml" <<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Lol's Website</title>
- <id>http://example.org/atom.xml</id>
- <updated>2016-10-01T00:00:00Z</updated>
- <link href="http://example.org/" />
- <link href="http://example.org/atom.xml" rel="self" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <subtitle type="text">WAT?!</subtitle>
- <entry>
- <title type="text">Foo</title>
- <id>http://example.org/post/foo/index.html</id>
- <updated>2016-10-01T00:00:00Z</updated>
- <published>2016-10-01T00:00:00Z</published>
- <link href="http://example.org/post/foo/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is foo.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Bar</title>
- <id>http://example.org/post/bar/index.html</id>
- <updated>2016-09-01T00:00:00Z</updated>
- <published>2016-09-01T00:00:00Z</published>
- <link href="http://example.org/post/bar/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is bar.</p>
-]]></content>
- </entry>
- <entry>
- <title type="text">Baz</title>
- <id>http://example.org/post/baz/index.html</id>
- <updated>2016-08-01T00:00:00Z</updated>
- <published>2016-08-01T00:00:00Z</published>
- <link href="http://example.org/post/baz/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is baz.</p>
-]]></content>
- </entry>
-</feed>
-EOF
-diff -uN "${TEMP}/proj/_build/atom.xml" "${TEMP}/expected-atom.xml"
-
-cat > "${TEMP}/expected-atom-tag1.xml" <<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Lol's Website - tag1</title>
- <id>http://example.org/atom/tag1.xml</id>
- <updated>2016-08-01T00:00:00Z</updated>
- <link href="http://example.org/" />
- <link href="http://example.org/atom/tag1.xml" rel="self" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <subtitle type="text">WAT?!</subtitle>
- <entry>
- <title type="text">Baz</title>
- <id>http://example.org/post/baz/index.html</id>
- <updated>2016-08-01T00:00:00Z</updated>
- <published>2016-08-01T00:00:00Z</published>
- <link href="http://example.org/post/baz/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is baz.</p>
-]]></content>
- </entry>
-</feed>
-EOF
-diff -uN "${TEMP}/proj/_build/atom/tag1.xml" "${TEMP}/expected-atom-tag1.xml"
-
-cat > "${TEMP}/expected-atom-tag2.xml" <<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Lol's Website - tag2</title>
- <id>http://example.org/atom/tag2.xml</id>
- <updated>2016-08-01T00:00:00Z</updated>
- <link href="http://example.org/" />
- <link href="http://example.org/atom/tag2.xml" rel="self" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <subtitle type="text">WAT?!</subtitle>
- <entry>
- <title type="text">Baz</title>
- <id>http://example.org/post/baz/index.html</id>
- <updated>2016-08-01T00:00:00Z</updated>
- <published>2016-08-01T00:00:00Z</published>
- <link href="http://example.org/post/baz/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is baz.</p>
-]]></content>
- </entry>
-</feed>
-EOF
-diff -uN "${TEMP}/proj/_build/atom/tag2.xml" "${TEMP}/expected-atom-tag2.xml"
-
-cat > "${TEMP}/expected-post-baz.html" <<EOF
-
-
-Baz - Aug 01, 2016, 12:00 AM GMT
-
-<p>This is baz.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/post/foo/index.html" "${TEMP}/expected-post-foo.html"
-diff -uN "${TEMP}/proj/_build/post/bar/index.html" "${TEMP}/expected-post-bar.html"
-diff -uN "${TEMP}/proj/_build/post/baz/index.html" "${TEMP}/expected-post-baz.html"
-
-cat > "${TEMP}/expected-tag1.html" <<EOF
-<p>This is hue.</p>
-
-Listing: tag1 - Baz - Aug 01, 2016, 12:00 AM GMT
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/tag/tag1/index.html" "${TEMP}/expected-tag1.html"
-diff -uN "${TEMP}/proj/_build/tag/tag1/page/1/index.html" "${TEMP}/expected-tag1.html"
-
-cat > "${TEMP}/expected-tag2.html" <<EOF
-<p>This is hue.</p>
-
-Listing: tag2 - Baz - Aug 01, 2016, 12:00 AM GMT
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/tag/tag2/index.html" "${TEMP}/expected-tag2.html"
-diff -uN "${TEMP}/proj/_build/tag/tag2/page/1/index.html" "${TEMP}/expected-tag2.html"
-
-rm -rf "${TEMP}/proj/_build"
-
-
-### default settings with some posts, pages and tags, order asc
-
-cat > "${TEMP}/proj/content/page1.txt" <<EOF
-TITLE: Page 1
--------------
-This is page 1.
-EOF
-
-cat > "${TEMP}/proj/content/page2.txt" <<EOF
-TITLE: Page 2
--------------
-This is page 2.
-EOF
-
-cat >> "${TEMP}/proj/blogcfile" <<EOF
-[pages]
-page1
-page2
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1 | tee "${TEMP}/output.txt"
-grep "_build/index\\.html" "${TEMP}/output.txt"
-grep "_build/atom\\.xml" "${TEMP}/output.txt"
-grep "_build/atom/tag1\\.xml" "${TEMP}/output.txt"
-grep "_build/atom/tag2\\.xml" "${TEMP}/output.txt"
-grep "_build/page/1/index\\.html" "${TEMP}/output.txt"
-grep -v "_build/page/2/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/foo/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/bar/index\\.html" "${TEMP}/output.txt"
-grep "_build/post/baz/index\\.html" "${TEMP}/output.txt"
-grep "_build/tag/tag1/index\\.html" "${TEMP}/output.txt"
-grep "_build/tag/tag1/page/1/index\\.html" "${TEMP}/output.txt"
-grep -v "_build/tag/tag1/page/2/index\\.html" "${TEMP}/output.txt"
-grep "_build/tag/tag2/index\\.html" "${TEMP}/output.txt"
-grep "_build/tag/tag2/page/1/index\\.html" "${TEMP}/output.txt"
-grep -v "_build/tag/tag2/page/2/index\\.html" "${TEMP}/output.txt"
-grep "_build/page1/index\\.html" "${TEMP}/output.txt"
-grep "_build/page2/index\\.html" "${TEMP}/output.txt"
-
-rm "${TEMP}/output.txt"
-
-diff -uN "${TEMP}/proj/_build/index.html" "${TEMP}/expected-index.html"
-diff -uN "${TEMP}/proj/_build/page/1/index.html" "${TEMP}/expected-index.html"
-
-diff -uN "${TEMP}/proj/_build/atom.xml" "${TEMP}/expected-atom.xml"
-
-diff -uN "${TEMP}/proj/_build/atom/tag1.xml" "${TEMP}/expected-atom-tag1.xml"
-diff -uN "${TEMP}/proj/_build/atom/tag2.xml" "${TEMP}/expected-atom-tag2.xml"
-
-diff -uN "${TEMP}/proj/_build/post/foo/index.html" "${TEMP}/expected-post-foo.html"
-diff -uN "${TEMP}/proj/_build/post/bar/index.html" "${TEMP}/expected-post-bar.html"
-diff -uN "${TEMP}/proj/_build/post/baz/index.html" "${TEMP}/expected-post-baz.html"
-
-diff -uN "${TEMP}/proj/_build/tag/tag1/index.html" "${TEMP}/expected-tag1.html"
-diff -uN "${TEMP}/proj/_build/tag/tag1/page/1/index.html" "${TEMP}/expected-tag1.html"
-diff -uN "${TEMP}/proj/_build/tag/tag2/index.html" "${TEMP}/expected-tag2.html"
-diff -uN "${TEMP}/proj/_build/tag/tag2/page/1/index.html" "${TEMP}/expected-tag2.html"
-
-cat > "${TEMP}/expected-page1.html" <<EOF
-
-
-Page 1
-
-<p>This is page 1.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/page1/index.html" "${TEMP}/expected-page1.html"
-
-cat > "${TEMP}/expected-page2.html" <<EOF
-
-
-Page 2
-
-<p>This is page 2.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/page2/index.html" "${TEMP}/expected-page2.html"
-
-rm -rf "${TEMP}/proj"
-mkdir -p "${TEMP}"/proj{,/temp,/contents/poost}
-
-
-### custom settings with some posts
-
-cat > "${TEMP}/proj/contents/poost/foo.blogc" <<EOF
-TITLE: Foo
-DATE: 2016-10-01
-----------------
-This is foo.
-EOF
-
-cat > "${TEMP}/proj/contents/poost/bar.blogc" <<EOF
-TITLE: Bar
-DATE: 2016-09-01
-----------------
-This is bar.
-EOF
-
-cat > "${TEMP}/proj/temp/main.html" <<EOF
-{% block listing %}
-Listing: {% ifdef FILTER_TAG %}{{ FILTER_TAG }} - {% endif %}{{ TITLE }} - {{ DATE_FORMATTED }}
-{% endblock %}
-{% block entry %}
-{{ TITLE }}{% if MAKE_TYPE == "post" %} - {{ DATE_FORMATTED }}{% endif %}
-
-{{ CONTENT }}
-{% endblock %}
-EOF
-
-cat > "${TEMP}/proj/blogcfile" <<EOF
-[settings]
-content_dir = contents
-template_dir = temp
-main_template = main.html
-source_ext = .blogc
-pagination_prefix = pagination
-posts_per_page = 1
-atom_posts_per_page = 1
-html_ext = .html
-index_prefix = posts
-post_prefix = poost
-tag_prefix = taag
-atom_prefix = atoom
-atom_ext = /index.xml
-date_format = %b %d, %Y
-locale = en_US.utf8
-html_order = ASC
-atom_order = ASC
-
-[global]
-AUTHOR_NAME = Lol
-AUTHOR_EMAIL = author@example.com
-SITE_TITLE = Lol's Website
-SITE_TAGLINE = WAT?!
-BASE_DOMAIN = http://example.org
-
-[posts]
-foo
-bar
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1 | tee "${TEMP}/output.txt"
-grep "_build/posts\\.html" "${TEMP}/output.txt"
-grep "_build/atoom/index\\.xml" "${TEMP}/output.txt"
-grep "_build/pagination/1\\.html" "${TEMP}/output.txt"
-grep "_build/pagination/2\\.html" "${TEMP}/output.txt"
-grep -v "_build/pagination/3\\.html" "${TEMP}/output.txt"
-grep "_build/poost/foo\\.html" "${TEMP}/output.txt"
-grep "_build/poost/bar\\.html" "${TEMP}/output.txt"
-
-rm "${TEMP}/output.txt"
-
-cat > "${TEMP}/expected-index.html" <<EOF
-
-Listing: Foo - Oct 01, 2016
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/posts.html" "${TEMP}/expected-index.html"
-diff -uN "${TEMP}/proj/_build/pagination/1.html" "${TEMP}/expected-index.html"
-
-cat > "${TEMP}/expected-page-2.html" <<EOF
-
-Listing: Bar - Sep 01, 2016
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/pagination/2.html" "${TEMP}/expected-page-2.html"
-
-cat > "${TEMP}/expected-atom.xml" <<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Lol's Website</title>
- <id>http://example.org/atoom/index.xml</id>
- <updated>2016-10-01T00:00:00Z</updated>
- <link href="http://example.org/" />
- <link href="http://example.org/atoom/index.xml" rel="self" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <subtitle type="text">WAT?!</subtitle>
- <entry>
- <title type="text">Foo</title>
- <id>http://example.org/poost/foo.html</id>
- <updated>2016-10-01T00:00:00Z</updated>
- <published>2016-10-01T00:00:00Z</published>
- <link href="http://example.org/poost/foo.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is foo.</p>
-]]></content>
- </entry>
-</feed>
-EOF
-diff -uN "${TEMP}/proj/_build/atoom/index.xml" "${TEMP}/expected-atom.xml"
-
-cat > "${TEMP}/expected-post-foo.html" <<EOF
-
-
-Foo - Oct 01, 2016
-
-<p>This is foo.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/poost/foo.html" "${TEMP}/expected-post-foo.html"
-
-cat > "${TEMP}/expected-post-bar.html" <<EOF
-
-
-Bar - Sep 01, 2016
-
-<p>This is bar.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/poost/bar.html" "${TEMP}/expected-post-bar.html"
-
-rm -rf "${TEMP}/proj/_build"
-
-
-### custom settings with some posts and tags
-
-cat > "${TEMP}/proj/contents/poost/baz.blogc" <<EOF
-TITLE: Baz
-DATE: 2016-08-01
-TAGS: tag1 tag2
-----------------
-This is baz.
-EOF
-
-cat >> "${TEMP}/proj/blogcfile" <<EOF
-baz
-[tags]
-tag1
-tag2
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1 | tee "${TEMP}/output.txt"
-grep "_build/posts\\.html" "${TEMP}/output.txt"
-grep "_build/atoom/index\\.xml" "${TEMP}/output.txt"
-grep "_build/atoom/tag1/index\\.xml" "${TEMP}/output.txt"
-grep "_build/atoom/tag2/index\\.xml" "${TEMP}/output.txt"
-grep "_build/pagination/1\\.html" "${TEMP}/output.txt"
-grep "_build/pagination/2\\.html" "${TEMP}/output.txt"
-grep "_build/pagination/3\\.html" "${TEMP}/output.txt"
-grep -v "_build/pagination/4\\.html" "${TEMP}/output.txt"
-grep "_build/poost/foo\\.html" "${TEMP}/output.txt"
-grep "_build/poost/bar\\.html" "${TEMP}/output.txt"
-grep "_build/poost/baz\\.html" "${TEMP}/output.txt"
-grep "_build/taag/tag1\\.html" "${TEMP}/output.txt"
-grep "_build/taag/tag1/pagination/1\\.html" "${TEMP}/output.txt"
-grep -v "_build/taag/tag1/pagination/2\\.html" "${TEMP}/output.txt"
-grep "_build/taag/tag2\\.html" "${TEMP}/output.txt"
-grep "_build/taag/tag2/pagination/1\\.html" "${TEMP}/output.txt"
-grep -v "_build/taag/tag2/pagination/2\\.html" "${TEMP}/output.txt"
-
-rm "${TEMP}/output.txt"
-
-diff -uN "${TEMP}/proj/_build/posts.html" "${TEMP}/expected-index.html"
-diff -uN "${TEMP}/proj/_build/pagination/1.html" "${TEMP}/expected-index.html"
-diff -uN "${TEMP}/proj/_build/pagination/2.html" "${TEMP}/expected-page-2.html"
-
-cat > "${TEMP}/expected-page-3.html" <<EOF
-
-Listing: Baz - Aug 01, 2016
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/pagination/3.html" "${TEMP}/expected-page-3.html"
-
-diff -uN "${TEMP}/proj/_build/atoom/index.xml" "${TEMP}/expected-atom.xml"
-
-cat > "${TEMP}/expected-atom-tag1.xml" <<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Lol's Website - tag1</title>
- <id>http://example.org/atoom/tag1/index.xml</id>
- <updated>2016-08-01T00:00:00Z</updated>
- <link href="http://example.org/" />
- <link href="http://example.org/atoom/tag1/index.xml" rel="self" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <subtitle type="text">WAT?!</subtitle>
- <entry>
- <title type="text">Baz</title>
- <id>http://example.org/poost/baz.html</id>
- <updated>2016-08-01T00:00:00Z</updated>
- <published>2016-08-01T00:00:00Z</published>
- <link href="http://example.org/poost/baz.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is baz.</p>
-]]></content>
- </entry>
-</feed>
-EOF
-diff -uN "${TEMP}/proj/_build/atoom/tag1/index.xml" "${TEMP}/expected-atom-tag1.xml"
-
-cat > "${TEMP}/expected-atom-tag2.xml" <<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Lol's Website - tag2</title>
- <id>http://example.org/atoom/tag2/index.xml</id>
- <updated>2016-08-01T00:00:00Z</updated>
- <link href="http://example.org/" />
- <link href="http://example.org/atoom/tag2/index.xml" rel="self" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <subtitle type="text">WAT?!</subtitle>
- <entry>
- <title type="text">Baz</title>
- <id>http://example.org/poost/baz.html</id>
- <updated>2016-08-01T00:00:00Z</updated>
- <published>2016-08-01T00:00:00Z</published>
- <link href="http://example.org/poost/baz.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is baz.</p>
-]]></content>
- </entry>
-</feed>
-EOF
-diff -uN "${TEMP}/proj/_build/atoom/tag2/index.xml" "${TEMP}/expected-atom-tag2.xml"
-
-cat > "${TEMP}/expected-post-baz.html" <<EOF
-
-
-Baz - Aug 01, 2016
-
-<p>This is baz.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/poost/foo.html" "${TEMP}/expected-post-foo.html"
-diff -uN "${TEMP}/proj/_build/poost/bar.html" "${TEMP}/expected-post-bar.html"
-diff -uN "${TEMP}/proj/_build/poost/baz.html" "${TEMP}/expected-post-baz.html"
-
-cat > "${TEMP}/expected-tag1.html" <<EOF
-
-Listing: tag1 - Baz - Aug 01, 2016
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/taag/tag1.html" "${TEMP}/expected-tag1.html"
-diff -uN "${TEMP}/proj/_build/taag/tag1/pagination/1.html" "${TEMP}/expected-tag1.html"
-
-cat > "${TEMP}/expected-tag2.html" <<EOF
-
-Listing: tag2 - Baz - Aug 01, 2016
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/taag/tag2.html" "${TEMP}/expected-tag2.html"
-diff -uN "${TEMP}/proj/_build/taag/tag2/pagination/1.html" "${TEMP}/expected-tag2.html"
-
-rm -rf "${TEMP}/proj/_build"
-
-
-### custom settings with some posts, pages and tags
-
-cat > "${TEMP}/proj/contents/page1.blogc" <<EOF
-TITLE: Page 1
--------------
-This is page 1.
-EOF
-
-cat > "${TEMP}/proj/contents/page2.blogc" <<EOF
-TITLE: Page 2
--------------
-This is page 2.
-EOF
-
-cat >> "${TEMP}/proj/blogcfile" <<EOF
-[pages]
-page1
-page2
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1 | tee "${TEMP}/output.txt"
-grep "_build/posts\\.html" "${TEMP}/output.txt"
-grep "_build/atoom/index\\.xml" "${TEMP}/output.txt"
-grep "_build/atoom/tag1/index\\.xml" "${TEMP}/output.txt"
-grep "_build/atoom/tag2/index\\.xml" "${TEMP}/output.txt"
-grep "_build/pagination/1\\.html" "${TEMP}/output.txt"
-grep "_build/pagination/2\\.html" "${TEMP}/output.txt"
-grep "_build/pagination/3\\.html" "${TEMP}/output.txt"
-grep -v "_build/pagination/4\\.html" "${TEMP}/output.txt"
-grep "_build/poost/foo\\.html" "${TEMP}/output.txt"
-grep "_build/poost/bar\\.html" "${TEMP}/output.txt"
-grep "_build/poost/baz\\.html" "${TEMP}/output.txt"
-grep "_build/taag/tag1\\.html" "${TEMP}/output.txt"
-grep "_build/taag/tag1/pagination/1\\.html" "${TEMP}/output.txt"
-grep -v "_build/taag/tag1/pagination/2\\.html" "${TEMP}/output.txt"
-grep "_build/taag/tag2\\.html" "${TEMP}/output.txt"
-grep "_build/taag/tag2/pagination/1\\.html" "${TEMP}/output.txt"
-grep -v "_build/taag/tag2/pagination/2\\.html" "${TEMP}/output.txt"
-grep "_build/page1\\.html" "${TEMP}/output.txt"
-grep "_build/page2\\.html" "${TEMP}/output.txt"
-
-rm "${TEMP}/output.txt"
-
-diff -uN "${TEMP}/proj/_build/posts.html" "${TEMP}/expected-index.html"
-diff -uN "${TEMP}/proj/_build/pagination/1.html" "${TEMP}/expected-index.html"
-diff -uN "${TEMP}/proj/_build/pagination/2.html" "${TEMP}/expected-page-2.html"
-diff -uN "${TEMP}/proj/_build/pagination/3.html" "${TEMP}/expected-page-3.html"
-
-diff -uN "${TEMP}/proj/_build/atoom/index.xml" "${TEMP}/expected-atom.xml"
-diff -uN "${TEMP}/proj/_build/atoom/tag1/index.xml" "${TEMP}/expected-atom-tag1.xml"
-diff -uN "${TEMP}/proj/_build/atoom/tag2/index.xml" "${TEMP}/expected-atom-tag2.xml"
-
-diff -uN "${TEMP}/proj/_build/poost/foo.html" "${TEMP}/expected-post-foo.html"
-diff -uN "${TEMP}/proj/_build/poost/bar.html" "${TEMP}/expected-post-bar.html"
-diff -uN "${TEMP}/proj/_build/poost/baz.html" "${TEMP}/expected-post-baz.html"
-
-diff -uN "${TEMP}/proj/_build/taag/tag1.html" "${TEMP}/expected-tag1.html"
-diff -uN "${TEMP}/proj/_build/taag/tag1/pagination/1.html" "${TEMP}/expected-tag1.html"
-diff -uN "${TEMP}/proj/_build/taag/tag2.html" "${TEMP}/expected-tag2.html"
-diff -uN "${TEMP}/proj/_build/taag/tag2/pagination/1.html" "${TEMP}/expected-tag2.html"
-
-cat > "${TEMP}/expected-page1.html" <<EOF
-
-
-Page 1
-
-<p>This is page 1.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/page1.html" "${TEMP}/expected-page1.html"
-
-cat > "${TEMP}/expected-page2.html" <<EOF
-
-
-Page 2
-
-<p>This is page 2.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/page2.html" "${TEMP}/expected-page2.html"
-
-rm -rf "${TEMP}/proj/_build"
-
-
-### copy rule
-
-mkdir -p "${TEMP}"/proj/{a/b/c,d/e,f}
-echo bola > "${TEMP}/proj/a/b/c/foo"
-echo guda > "${TEMP}/proj/a/b/bar"
-echo chunda > "${TEMP}/proj/a/baz"
-echo lol > "${TEMP}/proj/d/e/fuu"
-echo hehe > "${TEMP}/proj/d/xd"
-echo FFFUUUUUU > "${TEMP}/proj/f/XDDDD"
-
-cat >> "${TEMP}/proj/blogcfile" <<EOF
-[copy]
-a
-d/e/fuu
-d/xd
-f
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1 | tee "${TEMP}/output.txt"
-grep "_build/posts\\.html" "${TEMP}/output.txt"
-grep "_build/atoom/index\\.xml" "${TEMP}/output.txt"
-grep "_build/atoom/tag1/index\\.xml" "${TEMP}/output.txt"
-grep "_build/atoom/tag2/index\\.xml" "${TEMP}/output.txt"
-grep "_build/pagination/1\\.html" "${TEMP}/output.txt"
-grep "_build/pagination/2\\.html" "${TEMP}/output.txt"
-grep "_build/pagination/3\\.html" "${TEMP}/output.txt"
-grep -v "_build/pagination/4\\.html" "${TEMP}/output.txt"
-grep "_build/poost/foo\\.html" "${TEMP}/output.txt"
-grep "_build/poost/bar\\.html" "${TEMP}/output.txt"
-grep "_build/poost/baz\\.html" "${TEMP}/output.txt"
-grep "_build/taag/tag1\\.html" "${TEMP}/output.txt"
-grep "_build/taag/tag1/pagination/1\\.html" "${TEMP}/output.txt"
-grep -v "_build/taag/tag1/pagination/2\\.html" "${TEMP}/output.txt"
-grep "_build/taag/tag2\\.html" "${TEMP}/output.txt"
-grep "_build/taag/tag2/pagination/1\\.html" "${TEMP}/output.txt"
-grep -v "_build/taag/tag2/pagination/2\\.html" "${TEMP}/output.txt"
-grep "_build/page1\\.html" "${TEMP}/output.txt"
-grep "_build/page2\\.html" "${TEMP}/output.txt"
-grep "_build/a/b/c/foo" "${TEMP}/output.txt"
-grep "_build/a/b/bar" "${TEMP}/output.txt"
-grep "_build/a/baz" "${TEMP}/output.txt"
-grep "_build/d/e/fuu" "${TEMP}/output.txt"
-grep "_build/d/xd" "${TEMP}/output.txt"
-grep "_build/f/XDDDD" "${TEMP}/output.txt"
-
-rm "${TEMP}/output.txt"
-
-test "$(cat "${TEMP}/proj/_build/a/b/c/foo")" = "bola"
-test "$(cat "${TEMP}/proj/_build/a/b/bar")" = "guda"
-test "$(cat "${TEMP}/proj/_build/a/baz")" = "chunda"
-test "$(cat "${TEMP}/proj/_build/d/e/fuu")" = "lol"
-test "$(cat "${TEMP}/proj/_build/d/xd")" = "hehe"
-test "$(cat "${TEMP}/proj/_build/f/XDDDD")" = "FFFUUUUUU"
-
-
-### clean rule
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" clean 2>&1 | tee "${TEMP}/output.txt"
-grep "_build/posts\\.html" "${TEMP}/output.txt"
-grep "_build/atoom/index\\.xml" "${TEMP}/output.txt"
-grep "_build/atoom/tag1/index\\.xml" "${TEMP}/output.txt"
-grep "_build/atoom/tag2/index\\.xml" "${TEMP}/output.txt"
-grep "_build/pagination/1\\.html" "${TEMP}/output.txt"
-grep "_build/pagination/2\\.html" "${TEMP}/output.txt"
-grep "_build/pagination/3\\.html" "${TEMP}/output.txt"
-grep -v "_build/pagination/4\\.html" "${TEMP}/output.txt"
-grep "_build/poost/foo\\.html" "${TEMP}/output.txt"
-grep "_build/poost/bar\\.html" "${TEMP}/output.txt"
-grep "_build/poost/baz\\.html" "${TEMP}/output.txt"
-grep "_build/taag/tag1\\.html" "${TEMP}/output.txt"
-grep "_build/taag/tag1/pagination/1\\.html" "${TEMP}/output.txt"
-grep -v "_build/taag/tag1/pagination/2\\.html" "${TEMP}/output.txt"
-grep "_build/taag/tag2\\.html" "${TEMP}/output.txt"
-grep "_build/taag/tag2/pagination/1\\.html" "${TEMP}/output.txt"
-grep -v "_build/taag/tag2/pagination/2\\.html" "${TEMP}/output.txt"
-grep "_build/page1\\.html" "${TEMP}/output.txt"
-grep "_build/page2\\.html" "${TEMP}/output.txt"
-grep "_build/a/b/c/foo" "${TEMP}/output.txt"
-grep "_build/a/b/bar" "${TEMP}/output.txt"
-grep "_build/a/baz" "${TEMP}/output.txt"
-grep "_build/d/e/fuu" "${TEMP}/output.txt"
-grep "_build/d/xd" "${TEMP}/output.txt"
-grep "_build/f/XDDDD" "${TEMP}/output.txt"
-
-rm "${TEMP}/output.txt"
-
-[[ ! -d "${TEMP}/proj/_build" ]]
-
-export OUTPUT_DIR="${TEMP}/___blogc_build"
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1 | tee "${TEMP}/output.txt"
-grep "___blogc_build/posts\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/atoom/index\\.xml" "${TEMP}/output.txt"
-grep "___blogc_build/atoom/tag1/index\\.xml" "${TEMP}/output.txt"
-grep "___blogc_build/atoom/tag2/index\\.xml" "${TEMP}/output.txt"
-grep "___blogc_build/pagination/1\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/pagination/2\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/pagination/3\\.html" "${TEMP}/output.txt"
-grep -v "___blogc_build/pagination/4\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/poost/foo\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/poost/bar\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/poost/baz\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/taag/tag1\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/taag/tag1/pagination/1\\.html" "${TEMP}/output.txt"
-grep -v "___blogc_build/taag/tag1/pagination/2\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/taag/tag2\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/taag/tag2/pagination/1\\.html" "${TEMP}/output.txt"
-grep -v "___blogc_build/taag/tag2/pagination/2\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/page1\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/page2\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/a/b/c/foo" "${TEMP}/output.txt"
-grep "___blogc_build/a/b/bar" "${TEMP}/output.txt"
-grep "___blogc_build/a/baz" "${TEMP}/output.txt"
-grep "___blogc_build/d/e/fuu" "${TEMP}/output.txt"
-grep "___blogc_build/d/xd" "${TEMP}/output.txt"
-grep "___blogc_build/f/XDDDD" "${TEMP}/output.txt"
-
-rm "${TEMP}/output.txt"
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" clean 2>&1 | tee "${TEMP}/output.txt"
-grep "___blogc_build/posts\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/atoom/index\\.xml" "${TEMP}/output.txt"
-grep "___blogc_build/atoom/tag1/index\\.xml" "${TEMP}/output.txt"
-grep "___blogc_build/atoom/tag2/index\\.xml" "${TEMP}/output.txt"
-grep "___blogc_build/pagination/1\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/pagination/2\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/pagination/3\\.html" "${TEMP}/output.txt"
-grep -v "___blogc_build/pagination/4\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/poost/foo\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/poost/bar\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/poost/baz\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/taag/tag1\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/taag/tag1/pagination/1\\.html" "${TEMP}/output.txt"
-grep -v "___blogc_build/taag/tag1/pagination/2\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/taag/tag2\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/taag/tag2/pagination/1\\.html" "${TEMP}/output.txt"
-grep -v "___blogc_build/taag/tag2/pagination/2\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/page1\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/page2\\.html" "${TEMP}/output.txt"
-grep "___blogc_build/a/b/c/foo" "${TEMP}/output.txt"
-grep "___blogc_build/a/b/bar" "${TEMP}/output.txt"
-grep "___blogc_build/a/baz" "${TEMP}/output.txt"
-grep "___blogc_build/d/e/fuu" "${TEMP}/output.txt"
-grep "___blogc_build/d/xd" "${TEMP}/output.txt"
-grep "___blogc_build/f/XDDDD" "${TEMP}/output.txt"
-
-rm "${TEMP}/output.txt"
-
-[[ ! -d "${OUTPUT_DIR}" ]]
-
-unset OUTPUT_DIR
-
-
-### atom_dump rule
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" atom_dump | tee "${TEMP}/atom.xml"
-
-cat > "${TEMP}/expected-atom-dump.xml" <<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">{{ SITE_TITLE }}{% ifdef FILTER_TAG %} - {{ FILTER_TAG }}{% endif %}</title>
- <id>{{ BASE_DOMAIN }}{{ BASE_URL }}/atoom{% ifdef FILTER_TAG %}/{{ FILTER_TAG }}{% endif %}/index.xml</id>
- <updated>{{ DATE_FIRST_FORMATTED }}</updated>
- <link href="{{ BASE_DOMAIN }}{{ BASE_URL }}/" />
- <link href="{{ BASE_DOMAIN }}{{ BASE_URL }}/atoom{% ifdef FILTER_TAG %}/{{ FILTER_TAG }}{% endif %}/index.xml" rel="self" />
- <author>
- <name>{{ AUTHOR_NAME }}</name>
- <email>{{ AUTHOR_EMAIL }}</email>
- </author>
- <subtitle type="text">{{ SITE_TAGLINE }}</subtitle>
- {%- block listing %}
- <entry>
- <title type="text">{{ TITLE }}</title>
- <id>{{ BASE_DOMAIN }}{{ BASE_URL }}/poost/{{ FILENAME }}.html</id>
- <updated>{{ DATE_FORMATTED }}</updated>
- <published>{{ DATE_FORMATTED }}</published>
- <link href="{{ BASE_DOMAIN }}{{ BASE_URL }}/poost/{{ FILENAME }}.html" />
- <author>
- <name>{{ AUTHOR_NAME }}</name>
- <email>{{ AUTHOR_EMAIL }}</email>
- </author>
- <content type="html"><![CDATA[{{ CONTENT }}]]></content>
- </entry>
- {%- endblock %}
-</feed>
-EOF
-diff -uN "${TEMP}/atom.xml" "${TEMP}/expected-atom-dump.xml"
-
-rm "${TEMP}/atom.xml"
-rm -rf "${TEMP}/proj"
-
-
-###############################################################################
-
-### empty prefixes with some posts
-
-mkdir -p "${TEMP}/proj/"{contents,temp}
-
-cat > "${TEMP}/proj/contents/foo.blogc" <<EOF
-TITLE: Foo
-DATE: 2016-10-01
-----------------
-This is foo.
-EOF
-
-cat > "${TEMP}/proj/contents/bar.blogc" <<EOF
-TITLE: Bar
-DATE: 2016-09-01
-----------------
-This is bar.
-EOF
-
-cat > "${TEMP}/proj/temp/main.html" <<EOF
-{% block listing %}
-Listing: {% ifdef FILTER_TAG %}{{ FILTER_TAG }} - {% endif %}{{ TITLE }} - {{ DATE_FORMATTED }}
-{% endblock %}
-{% block entry %}
-{{ TITLE }}{% if MAKE_TYPE == "post" %} - {{ DATE_FORMATTED }}{% endif %}
-
-{{ CONTENT }}
-{% endblock %}
-EOF
-
-cat > "${TEMP}/proj/blogcfile" <<EOF
-[settings]
-content_dir = contents
-template_dir = temp
-main_template = main.html
-source_ext = .blogc
-pagination_prefix =
-posts_per_page = 1
-atom_posts_per_page = 1
-html_ext = /index.html
-index_prefix =
-post_prefix =
-tag_prefix =
-atom_prefix =
-atom_ext = .xml
-date_format = %b %d, %Y
-locale = en_US.utf8
-html_order = ASC
-atom_order = ASC
-
-[global]
-AUTHOR_NAME = Lol
-AUTHOR_EMAIL = author@example.com
-SITE_TITLE = Lol's Website
-SITE_TAGLINE = WAT?!
-BASE_DOMAIN = http://example.org
-
-[posts]
-foo
-bar
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1 | tee "${TEMP}/output.txt"
-grep "_build/index\\.html" "${TEMP}/output.txt"
-grep "_build/index\\.xml" "${TEMP}/output.txt"
-grep "_build/1/index\\.html" "${TEMP}/output.txt"
-grep "_build/2/index\\.html" "${TEMP}/output.txt"
-grep -v "_build/3/index\\.html" "${TEMP}/output.txt"
-grep "_build/foo/index\\.html" "${TEMP}/output.txt"
-grep "_build/bar/index\\.html" "${TEMP}/output.txt"
-
-rm "${TEMP}/output.txt"
-
-cat > "${TEMP}/expected-index.html" <<EOF
-
-Listing: Foo - Oct 01, 2016
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/index.html" "${TEMP}/expected-index.html"
-diff -uN "${TEMP}/proj/_build/1/index.html" "${TEMP}/expected-index.html"
-
-cat > "${TEMP}/expected-page-2.html" <<EOF
-
-Listing: Bar - Sep 01, 2016
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/2/index.html" "${TEMP}/expected-page-2.html"
-
-cat > "${TEMP}/expected-atom.xml" <<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Lol's Website</title>
- <id>http://example.org/index.xml</id>
- <updated>2016-10-01T00:00:00Z</updated>
- <link href="http://example.org/" />
- <link href="http://example.org/index.xml" rel="self" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <subtitle type="text">WAT?!</subtitle>
- <entry>
- <title type="text">Foo</title>
- <id>http://example.org/foo/index.html</id>
- <updated>2016-10-01T00:00:00Z</updated>
- <published>2016-10-01T00:00:00Z</published>
- <link href="http://example.org/foo/index.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is foo.</p>
-]]></content>
- </entry>
-</feed>
-EOF
-diff -uN "${TEMP}/proj/_build/index.xml" "${TEMP}/expected-atom.xml"
-
-cat > "${TEMP}/expected-post-foo.html" <<EOF
-
-
-Foo - Oct 01, 2016
-
-<p>This is foo.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/foo/index.html" "${TEMP}/expected-post-foo.html"
-
-cat > "${TEMP}/expected-post-bar.html" <<EOF
-
-
-Bar - Sep 01, 2016
-
-<p>This is bar.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/bar/index.html" "${TEMP}/expected-post-bar.html"
-
-rm -rf "${TEMP}/proj/_build"
-
-
-### empty prefixes with some posts and tags, and different exts
-
-cat > "${TEMP}/proj/contents/baz.blogc" <<EOF
-TITLE: Baz
-DATE: 2016-08-01
-TAGS: tag1 tag2
-----------------
-This is baz.
-EOF
-
-cat > "${TEMP}/proj/blogcfile" <<EOF
-[settings]
-content_dir = contents
-template_dir = temp
-main_template = main.html
-source_ext = .blogc
-pagination_prefix =
-posts_per_page = 1
-atom_posts_per_page = 1
-html_ext = .html
-index_prefix =
-post_prefix =
-tag_prefix =
-atom_prefix =
-atom_ext = /index.xml
-date_format = %b %d, %Y
-locale = en_US.utf8
-html_order = ASC
-atom_order = ASC
-
-[global]
-AUTHOR_NAME = Lol
-AUTHOR_EMAIL = author@example.com
-SITE_TITLE = Lol's Website
-SITE_TAGLINE = WAT?!
-BASE_DOMAIN = http://example.org
-
-[posts]
-foo
-bar
-baz
-
-[tags]
-tag1
-tag2
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1 | tee "${TEMP}/output.txt"
-grep "_build/index\\.html" "${TEMP}/output.txt"
-grep "_build/index\\.xml" "${TEMP}/output.txt"
-grep "_build/tag1/index\\.xml" "${TEMP}/output.txt"
-grep "_build/tag2/index\\.xml" "${TEMP}/output.txt"
-grep "_build/1\\.html" "${TEMP}/output.txt"
-grep "_build/2\\.html" "${TEMP}/output.txt"
-grep "_build/3\\.html" "${TEMP}/output.txt"
-grep -v "_build/4\\.html" "${TEMP}/output.txt"
-grep "_build/foo\\.html" "${TEMP}/output.txt"
-grep "_build/bar\\.html" "${TEMP}/output.txt"
-grep "_build/baz\\.html" "${TEMP}/output.txt"
-grep "_build/tag1\\.html" "${TEMP}/output.txt"
-grep "_build/tag1/1\\.html" "${TEMP}/output.txt"
-grep -v "_build/tag1/2\\.html" "${TEMP}/output.txt"
-grep "_build/tag2\\.html" "${TEMP}/output.txt"
-grep "_build/tag2/1\\.html" "${TEMP}/output.txt"
-grep -v "_build/tag2/2\\.html" "${TEMP}/output.txt"
-
-rm "${TEMP}/output.txt"
-
-diff -uN "${TEMP}/proj/_build/index.html" "${TEMP}/expected-index.html"
-diff -uN "${TEMP}/proj/_build/1.html" "${TEMP}/expected-index.html"
-diff -uN "${TEMP}/proj/_build/2.html" "${TEMP}/expected-page-2.html"
-
-cat > "${TEMP}/expected-page-3.html" <<EOF
-
-Listing: Baz - Aug 01, 2016
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/3.html" "${TEMP}/expected-page-3.html"
-
-cat > "${TEMP}/expected-atom.xml" <<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Lol's Website</title>
- <id>http://example.org/index.xml</id>
- <updated>2016-10-01T00:00:00Z</updated>
- <link href="http://example.org/" />
- <link href="http://example.org/index.xml" rel="self" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <subtitle type="text">WAT?!</subtitle>
- <entry>
- <title type="text">Foo</title>
- <id>http://example.org/foo.html</id>
- <updated>2016-10-01T00:00:00Z</updated>
- <published>2016-10-01T00:00:00Z</published>
- <link href="http://example.org/foo.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is foo.</p>
-]]></content>
- </entry>
-</feed>
-EOF
-diff -uN "${TEMP}/proj/_build/index.xml" "${TEMP}/expected-atom.xml"
-
-cat > "${TEMP}/expected-atom-tag1.xml" <<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Lol's Website - tag1</title>
- <id>http://example.org/tag1/index.xml</id>
- <updated>2016-08-01T00:00:00Z</updated>
- <link href="http://example.org/" />
- <link href="http://example.org/tag1/index.xml" rel="self" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <subtitle type="text">WAT?!</subtitle>
- <entry>
- <title type="text">Baz</title>
- <id>http://example.org/baz.html</id>
- <updated>2016-08-01T00:00:00Z</updated>
- <published>2016-08-01T00:00:00Z</published>
- <link href="http://example.org/baz.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is baz.</p>
-]]></content>
- </entry>
-</feed>
-EOF
-diff -uN "${TEMP}/proj/_build/tag1/index.xml" "${TEMP}/expected-atom-tag1.xml"
-
-cat > "${TEMP}/expected-atom-tag2.xml" <<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Lol's Website - tag2</title>
- <id>http://example.org/tag2/index.xml</id>
- <updated>2016-08-01T00:00:00Z</updated>
- <link href="http://example.org/" />
- <link href="http://example.org/tag2/index.xml" rel="self" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <subtitle type="text">WAT?!</subtitle>
- <entry>
- <title type="text">Baz</title>
- <id>http://example.org/baz.html</id>
- <updated>2016-08-01T00:00:00Z</updated>
- <published>2016-08-01T00:00:00Z</published>
- <link href="http://example.org/baz.html" />
- <author>
- <name>Lol</name>
- <email>author@example.com</email>
- </author>
- <content type="html"><![CDATA[<p>This is baz.</p>
-]]></content>
- </entry>
-</feed>
-EOF
-diff -uN "${TEMP}/proj/_build/tag2/index.xml" "${TEMP}/expected-atom-tag2.xml"
-
-cat > "${TEMP}/expected-post-baz.html" <<EOF
-
-
-Baz - Aug 01, 2016
-
-<p>This is baz.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/foo.html" "${TEMP}/expected-post-foo.html"
-diff -uN "${TEMP}/proj/_build/bar.html" "${TEMP}/expected-post-bar.html"
-diff -uN "${TEMP}/proj/_build/baz.html" "${TEMP}/expected-post-baz.html"
-
-cat > "${TEMP}/expected-tag1.html" <<EOF
-
-Listing: tag1 - Baz - Aug 01, 2016
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/tag1.html" "${TEMP}/expected-tag1.html"
-
-cat > "${TEMP}/expected-tag2.html" <<EOF
-
-Listing: tag2 - Baz - Aug 01, 2016
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/tag2.html" "${TEMP}/expected-tag2.html"
-
-rm -rf "${TEMP}/proj/_build"
-
-
-### custom settings with some posts, pages and tags
-
-cat > "${TEMP}/proj/contents/page1.blogc" <<EOF
-TITLE: Page 1
--------------
-This is page 1.
-EOF
-
-cat > "${TEMP}/proj/contents/page2.blogc" <<EOF
-TITLE: Page 2
--------------
-This is page 2.
-EOF
-
-cat >> "${TEMP}/proj/blogcfile" <<EOF
-[pages]
-page1
-page2
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1 | tee "${TEMP}/output.txt"
-grep "_build/index\\.html" "${TEMP}/output.txt"
-grep "_build/index\\.xml" "${TEMP}/output.txt"
-grep "_build/tag1/index\\.xml" "${TEMP}/output.txt"
-grep "_build/tag2/index\\.xml" "${TEMP}/output.txt"
-grep "_build/1\\.html" "${TEMP}/output.txt"
-grep "_build/2\\.html" "${TEMP}/output.txt"
-grep "_build/3\\.html" "${TEMP}/output.txt"
-grep -v "_build/4\\.html" "${TEMP}/output.txt"
-grep "_build/foo\\.html" "${TEMP}/output.txt"
-grep "_build/bar\\.html" "${TEMP}/output.txt"
-grep "_build/baz\\.html" "${TEMP}/output.txt"
-grep "_build/tag1\\.html" "${TEMP}/output.txt"
-grep "_build/tag2\\.html" "${TEMP}/output.txt"
-grep "_build/page1\\.html" "${TEMP}/output.txt"
-grep "_build/page2\\.html" "${TEMP}/output.txt"
-
-rm "${TEMP}/output.txt"
-
-diff -uN "${TEMP}/proj/_build/index.html" "${TEMP}/expected-index.html"
-diff -uN "${TEMP}/proj/_build/1.html" "${TEMP}/expected-index.html"
-diff -uN "${TEMP}/proj/_build/2.html" "${TEMP}/expected-page-2.html"
-diff -uN "${TEMP}/proj/_build/3.html" "${TEMP}/expected-page-3.html"
-
-diff -uN "${TEMP}/proj/_build/index.xml" "${TEMP}/expected-atom.xml"
-diff -uN "${TEMP}/proj/_build/tag1/index.xml" "${TEMP}/expected-atom-tag1.xml"
-diff -uN "${TEMP}/proj/_build/tag2/index.xml" "${TEMP}/expected-atom-tag2.xml"
-
-diff -uN "${TEMP}/proj/_build/foo.html" "${TEMP}/expected-post-foo.html"
-diff -uN "${TEMP}/proj/_build/bar.html" "${TEMP}/expected-post-bar.html"
-diff -uN "${TEMP}/proj/_build/baz.html" "${TEMP}/expected-post-baz.html"
-
-diff -uN "${TEMP}/proj/_build/tag1.html" "${TEMP}/expected-tag1.html"
-diff -uN "${TEMP}/proj/_build/tag2.html" "${TEMP}/expected-tag2.html"
-
-cat > "${TEMP}/expected-page1.html" <<EOF
-
-
-Page 1
-
-<p>This is page 1.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/page1.html" "${TEMP}/expected-page1.html"
-
-cat > "${TEMP}/expected-page2.html" <<EOF
-
-
-Page 2
-
-<p>This is page 2.</p>
-
-
-EOF
-diff -uN "${TEMP}/proj/_build/page2.html" "${TEMP}/expected-page2.html"
-
-rm -rf "${TEMP}/proj/_build"
diff --git a/tests/blogc-make/check_exec.c b/tests/blogc-make/check_exec.c
deleted file mode 100644
index 6b15423..0000000
--- a/tests/blogc-make/check_exec.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif /* HAVE_CONFIG_H */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "../../src/blogc-make/exec.h"
-#include "../../src/blogc-make/settings.h"
-#include "../../src/common/utils.h"
-
-
-int
-__wrap_access(const char *pathname, int mode)
-{
- assert_int_equal(mode, X_OK);
- assert_string_equal(pathname, mock_type(const char*));
- return mock_type(int);
-}
-
-
-static void
-test_find_binary(void **state)
-{
- unsetenv("BLOGC");
-
- char *bin = bm_exec_find_binary(NULL, "blogc", "BLOGC");
- assert_string_equal(bin, "blogc");
- free(bin);
-
- bin = bm_exec_find_binary("blogc-make", "blogc", "BLOGC");
- assert_string_equal(bin, "blogc");
- free(bin);
-
- will_return(__wrap_access, "../blogc");
- will_return(__wrap_access, 0);
- bin = bm_exec_find_binary("../blogc-make", "blogc", "BLOGC");
- assert_string_equal(bin, "'../blogc'");
- free(bin);
-
- will_return(__wrap_access, "/usr/bin/blogc");
- will_return(__wrap_access, 0);
- bin = bm_exec_find_binary("/usr/bin/blogc-make", "blogc", "BLOGC");
- assert_string_equal(bin, "'/usr/bin/blogc'");
- free(bin);
-
- will_return(__wrap_access, "../blogc");
- will_return(__wrap_access, 1);
- bin = bm_exec_find_binary("../blogc-make", "blogc", "BLOGC");
- assert_string_equal(bin, "blogc");
- free(bin);
-
- setenv("BLOGC", "/path/to/blogc", 1);
- bin = bm_exec_find_binary(NULL, "blogc", "BLOGC");
- assert_string_equal(bin, "'/path/to/blogc'");
- free(bin);
- unsetenv("BLOGC");
-}
-
-
-static void
-test_build_blogc_cmd_with_settings(void **state)
-{
- bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
- settings->settings = bc_trie_new(free);
- bc_trie_insert(settings->settings, "locale", bc_strdup("en_US.utf8"));
- settings->global = bc_trie_new(free);
- bc_trie_insert(settings->global, "FOO", bc_strdup("BAR"));
- bc_trie_insert(settings->global, "BAR", bc_strdup("BAZ"));
- bc_trie_t *variables = bc_trie_new(free);
- bc_trie_insert(variables, "LOL", bc_strdup("HEHE"));
- bc_trie_t *local = bc_trie_new(free);
- bc_trie_insert(local, "ASD", bc_strdup("QWE"));
- settings->tags = NULL;
-
- char *rv = bm_exec_build_blogc_cmd("blogc", settings, variables, local, NULL,
- true, NULL, "main.tmpl", "foo.html", false, true);
- assert_string_equal(rv,
- "LC_ALL='en_US.utf8' blogc -D FOO='BAR' -D BAR='BAZ' -D LOL='HEHE' "
- "-D ASD='QWE' -l -t 'main.tmpl' -o 'foo.html' -i");
- free(rv);
-
- rv = bm_exec_build_blogc_cmd("blogc", settings, variables, local, NULL, true,
- "foo.txt", "main.tmpl", "foo.html", false, true);
- assert_string_equal(rv,
- "LC_ALL='en_US.utf8' blogc -D FOO='BAR' -D BAR='BAZ' -D LOL='HEHE' "
- "-D ASD='QWE' -l -e 'foo.txt' -t 'main.tmpl' -o 'foo.html' -i");
- free(rv);
-
- rv = bm_exec_build_blogc_cmd("blogc", settings, variables, NULL, NULL, false,
- NULL, NULL, NULL, false, false);
- assert_string_equal(rv,
- "LC_ALL='en_US.utf8' blogc -D FOO='BAR' -D BAR='BAZ' -D LOL='HEHE'");
- free(rv);
-
- rv = bm_exec_build_blogc_cmd("blogc", settings, NULL, NULL, NULL, false,
- NULL, NULL, NULL, false, false);
- assert_string_equal(rv,
- "LC_ALL='en_US.utf8' blogc -D FOO='BAR' -D BAR='BAZ'");
- free(rv);
-
- bc_trie_free(local);
- bc_trie_free(variables);
- bc_trie_free(settings->settings);
- bc_trie_free(settings->global);
- free(settings);
-}
-
-
-static void
-test_build_blogc_cmd_with_settings_and_dev(void **state)
-{
- bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
- settings->settings = bc_trie_new(free);
- bc_trie_insert(settings->settings, "locale", bc_strdup("en_US.utf8"));
- settings->global = bc_trie_new(free);
- bc_trie_insert(settings->global, "FOO", bc_strdup("BAR"));
- bc_trie_insert(settings->global, "BAR", bc_strdup("BAZ"));
- bc_trie_t *variables = bc_trie_new(free);
- bc_trie_insert(variables, "LOL", bc_strdup("HEHE"));
- bc_trie_t *local = bc_trie_new(free);
- bc_trie_insert(local, "ASD", bc_strdup("QWE"));
- settings->tags = NULL;
-
- char *rv = bm_exec_build_blogc_cmd("blogc", settings, variables, local, NULL,
- true, NULL, "main.tmpl", "foo.html", true, true);
- assert_string_equal(rv,
- "LC_ALL='en_US.utf8' blogc -D FOO='BAR' -D BAR='BAZ' -D LOL='HEHE' "
- "-D ASD='QWE' -D MAKE_ENV_DEV=1 -D MAKE_ENV='dev' -l -t 'main.tmpl' "
- "-o 'foo.html' -i");
- free(rv);
-
- rv = bm_exec_build_blogc_cmd("blogc", settings, variables, local, NULL, true,
- "foo.txt", "main.tmpl", "foo.html", true, true);
- assert_string_equal(rv,
- "LC_ALL='en_US.utf8' blogc -D FOO='BAR' -D BAR='BAZ' -D LOL='HEHE' "
- "-D ASD='QWE' -D MAKE_ENV_DEV=1 -D MAKE_ENV='dev' -l -e 'foo.txt' "
- "-t 'main.tmpl' -o 'foo.html' -i");
- free(rv);
-
- rv = bm_exec_build_blogc_cmd("blogc", settings, variables, NULL, NULL, false,
- NULL, NULL, NULL, true, false);
- assert_string_equal(rv,
- "LC_ALL='en_US.utf8' blogc -D FOO='BAR' -D BAR='BAZ' -D LOL='HEHE' "
- "-D MAKE_ENV_DEV=1 -D MAKE_ENV='dev'");
- free(rv);
-
- rv = bm_exec_build_blogc_cmd("blogc", settings, NULL, NULL, NULL, false,
- NULL, NULL, NULL, true, false);
- assert_string_equal(rv,
- "LC_ALL='en_US.utf8' blogc -D FOO='BAR' -D BAR='BAZ' "
- "-D MAKE_ENV_DEV=1 -D MAKE_ENV='dev'");
- free(rv);
-
- bc_trie_free(local);
- bc_trie_free(variables);
- bc_trie_free(settings->settings);
- bc_trie_free(settings->global);
- free(settings);
-}
-
-
-static void
-test_build_blogc_cmd_with_settings_and_tags(void **state)
-{
- bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
- settings->settings = bc_trie_new(free);
- bc_trie_insert(settings->settings, "locale", bc_strdup("en_US.utf8"));
- settings->global = bc_trie_new(free);
- bc_trie_insert(settings->global, "FOO", bc_strdup("BAR"));
- bc_trie_insert(settings->global, "BAR", bc_strdup("BAZ"));
- bc_trie_t *variables = bc_trie_new(free);
- bc_trie_insert(variables, "LOL", bc_strdup("HEHE"));
- bc_trie_t *local = bc_trie_new(free);
- bc_trie_insert(local, "ASD", bc_strdup("QWE"));
- settings->tags = bc_str_split("asd foo bar", ' ', 0);
-
- char *rv = bm_exec_build_blogc_cmd("blogc", settings, variables, local, NULL,
- true, NULL, "main.tmpl", "foo.html", true, true);
- assert_string_equal(rv,
- "LC_ALL='en_US.utf8' blogc -D MAKE_TAGS='asd foo bar' -D FOO='BAR' "
- "-D BAR='BAZ' -D LOL='HEHE' -D ASD='QWE' -D MAKE_ENV_DEV=1 "
- "-D MAKE_ENV='dev' -l -t 'main.tmpl' -o 'foo.html' -i");
- free(rv);
-
- rv = bm_exec_build_blogc_cmd("blogc", settings, variables, local, NULL, true,
- "foo.txt", "main.tmpl", "foo.html", true, true);
- assert_string_equal(rv,
- "LC_ALL='en_US.utf8' blogc -D MAKE_TAGS='asd foo bar' -D FOO='BAR' "
- "-D BAR='BAZ' -D LOL='HEHE' -D ASD='QWE' -D MAKE_ENV_DEV=1 "
- "-D MAKE_ENV='dev' -l -e 'foo.txt' -t 'main.tmpl' -o 'foo.html' -i");
- free(rv);
-
- rv = bm_exec_build_blogc_cmd("blogc", settings, variables, NULL, NULL, false,
- NULL, NULL, NULL, true, false);
- assert_string_equal(rv,
- "LC_ALL='en_US.utf8' blogc -D MAKE_TAGS='asd foo bar' -D FOO='BAR' "
- "-D BAR='BAZ' -D LOL='HEHE' -D MAKE_ENV_DEV=1 -D MAKE_ENV='dev'");
- free(rv);
-
- rv = bm_exec_build_blogc_cmd("blogc", settings, NULL, NULL, NULL, false,
- NULL, NULL, NULL, true, false);
- assert_string_equal(rv,
- "LC_ALL='en_US.utf8' blogc -D MAKE_TAGS='asd foo bar' -D FOO='BAR' "
- "-D BAR='BAZ' -D MAKE_ENV_DEV=1 -D MAKE_ENV='dev'");
- free(rv);
-
- bc_trie_free(local);
- bc_trie_free(variables);
- bc_trie_free(settings->settings);
- bc_trie_free(settings->global);
- bc_strv_free(settings->tags);
- free(settings);
-}
-
-
-static void
-test_build_blogc_cmd_without_settings(void **state)
-{
- bc_trie_t *variables = bc_trie_new(free);
- bc_trie_insert(variables, "LOL", bc_strdup("HEHE"));
- bc_trie_t *local = bc_trie_new(free);
- bc_trie_insert(local, "ASD", bc_strdup("QWE"));
-
- char *rv = bm_exec_build_blogc_cmd("blogc", NULL, variables, local, NULL,
- true, NULL, "main.tmpl", "foo.html", false, true);
- assert_string_equal(rv,
- "blogc -D LOL='HEHE' -D ASD='QWE' -l -t 'main.tmpl' -o 'foo.html' -i");
- free(rv);
-
- rv = bm_exec_build_blogc_cmd("blogc", NULL, variables, local, NULL, true,
- "foo.txt", "main.tmpl", "foo.html", false, true);
- assert_string_equal(rv,
- "blogc -D LOL='HEHE' -D ASD='QWE' -l -e 'foo.txt' -t 'main.tmpl' "
- "-o 'foo.html' -i");
- free(rv);
-
- rv = bm_exec_build_blogc_cmd("blogc", NULL, variables, NULL, NULL, false,
- NULL, NULL, NULL, false, false);
- assert_string_equal(rv,
- "blogc -D LOL='HEHE'");
- free(rv);
-
- rv = bm_exec_build_blogc_cmd("blogc", NULL, NULL, NULL, NULL, false, NULL,
- NULL, NULL, false, false);
- assert_string_equal(rv,
- "blogc");
- free(rv);
-
- bc_trie_free(local);
- bc_trie_free(variables);
-}
-
-
-static void
-test_build_blogc_cmd_print(void **state)
-{
- bc_trie_t *variables = bc_trie_new(free);
- bc_trie_insert(variables, "LOL", bc_strdup("HEHE"));
- bc_trie_t *local = bc_trie_new(free);
- bc_trie_insert(local, "ASD", bc_strdup("QWE"));
-
- char *rv = bm_exec_build_blogc_cmd("blogc", NULL, variables, local, "LOL",
- false, NULL, NULL, NULL, false, true);
- assert_string_equal(rv, "blogc -D LOL='HEHE' -D ASD='QWE' -p LOL -i");
- free(rv);
-
- rv = bm_exec_build_blogc_cmd("blogc", NULL, variables, local, "LOL", true,
- NULL, NULL, NULL, false, false);
- assert_string_equal(rv, "blogc -D LOL='HEHE' -D ASD='QWE' -p LOL -l");
- free(rv);
-
- rv = bm_exec_build_blogc_cmd("blogc", NULL, variables, NULL, "LOL", false,
- NULL, NULL, NULL, false, true);
- assert_string_equal(rv,
- "blogc -D LOL='HEHE' -p LOL -i");
- free(rv);
-
- rv = bm_exec_build_blogc_cmd("blogc", NULL, NULL, NULL, "LOL", false, NULL,
- NULL, NULL, false, false);
- assert_string_equal(rv,
- "blogc -p LOL");
- free(rv);
-
- bc_trie_free(local);
- bc_trie_free(variables);
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
-#ifndef MAKE_EMBEDDED
- cmocka_unit_test(test_find_binary),
-#endif
- cmocka_unit_test(test_build_blogc_cmd_with_settings),
- cmocka_unit_test(test_build_blogc_cmd_with_settings_and_dev),
- cmocka_unit_test(test_build_blogc_cmd_with_settings_and_tags),
- cmocka_unit_test(test_build_blogc_cmd_without_settings),
- cmocka_unit_test(test_build_blogc_cmd_print),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/blogc-make/check_rules.c b/tests/blogc-make/check_rules.c
deleted file mode 100644
index 5da412f..0000000
--- a/tests/blogc-make/check_rules.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "../../src/blogc-make/rules.h"
-#include "../../src/common/utils.h"
-
-
-static void
-test_rule_parse_args(void **state)
-{
- bc_trie_t *t = bm_rule_parse_args("bola:foo=" + 4);
- assert_non_null(t);
- assert_int_equal(bc_trie_size(t), 1);
- assert_string_equal(bc_trie_lookup(t, "foo"), "");
- bc_trie_free(t);
- t = bm_rule_parse_args("bola:foo=bar" + 4);
- assert_non_null(t);
- assert_int_equal(bc_trie_size(t), 1);
- assert_string_equal(bc_trie_lookup(t, "foo"), "bar");
- bc_trie_free(t);
- t = bm_rule_parse_args("bola:foo=,baz=lol" + 4);
- assert_non_null(t);
- assert_int_equal(bc_trie_size(t), 2);
- assert_string_equal(bc_trie_lookup(t, "foo"), "");
- assert_string_equal(bc_trie_lookup(t, "baz"), "lol");
- bc_trie_free(t);
- t = bm_rule_parse_args("bola:foo=bar,baz=" + 4);
- assert_non_null(t);
- assert_int_equal(bc_trie_size(t), 2);
- assert_string_equal(bc_trie_lookup(t, "foo"), "bar");
- assert_string_equal(bc_trie_lookup(t, "baz"), "");
- bc_trie_free(t);
- t = bm_rule_parse_args("bola:foo=bar,baz=lol" + 4);
- assert_non_null(t);
- assert_int_equal(bc_trie_size(t), 2);
- assert_string_equal(bc_trie_lookup(t, "foo"), "bar");
- assert_string_equal(bc_trie_lookup(t, "baz"), "lol");
- bc_trie_free(t);
- t = bm_rule_parse_args("bola:foo=,baz=lol,asd=qwe" + 4);
- assert_non_null(t);
- assert_int_equal(bc_trie_size(t), 3);
- assert_string_equal(bc_trie_lookup(t, "foo"), "");
- assert_string_equal(bc_trie_lookup(t, "baz"), "lol");
- assert_string_equal(bc_trie_lookup(t, "asd"), "qwe");
- bc_trie_free(t);
- t = bm_rule_parse_args("bola:foo=bar,baz=,asd=qwe" + 4);
- assert_non_null(t);
- assert_int_equal(bc_trie_size(t), 3);
- assert_string_equal(bc_trie_lookup(t, "foo"), "bar");
- assert_string_equal(bc_trie_lookup(t, "baz"), "");
- assert_string_equal(bc_trie_lookup(t, "asd"), "qwe");
- bc_trie_free(t);
- t = bm_rule_parse_args("bola:foo=bar,baz=lol,asd=" + 4);
- assert_non_null(t);
- assert_int_equal(bc_trie_size(t), 3);
- assert_string_equal(bc_trie_lookup(t, "foo"), "bar");
- assert_string_equal(bc_trie_lookup(t, "baz"), "lol");
- assert_string_equal(bc_trie_lookup(t, "asd"), "");
- bc_trie_free(t);
- t = bm_rule_parse_args("bola:foo=bar,baz=lol,asd=qwe" + 4);
- assert_non_null(t);
- assert_int_equal(bc_trie_size(t), 3);
- assert_string_equal(bc_trie_lookup(t, "foo"), "bar");
- assert_string_equal(bc_trie_lookup(t, "baz"), "lol");
- assert_string_equal(bc_trie_lookup(t, "asd"), "qwe");
- bc_trie_free(t);
-}
-
-
-static void
-test_rule_parse_args_error(void **state)
-{
- assert_null(bm_rule_parse_args(NULL));
- assert_null(bm_rule_parse_args("bola" + 4));
- assert_null(bm_rule_parse_args("bola:" + 4));
- assert_null(bm_rule_parse_args("bola:asd" + 4));
- assert_null(bm_rule_parse_args("bola:asd=foo,lol" + 4));
- assert_null(bm_rule_parse_args("bola:asd=foo,qwe=bar,lol" + 4));
- assert_null(bm_rule_parse_args("bolaasd" + 4));
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_rule_parse_args),
- cmocka_unit_test(test_rule_parse_args_error),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/blogc-make/check_settings.c b/tests/blogc-make/check_settings.c
deleted file mode 100644
index b268570..0000000
--- a/tests/blogc-make/check_settings.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "../../src/blogc-make/settings.h"
-#include "../../src/common/error.h"
-#include "../../src/common/utils.h"
-
-
-static void
-test_settings_empty(void **state)
-{
- const char *a = "";
- bc_error_t *err = NULL;
- bm_settings_t *s = bm_settings_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(s);
- assert_int_equal(err->type, BLOGC_MAKE_ERROR_SETTINGS);
- assert_string_equal(err->msg,
- "[global] key required but not found or empty: AUTHOR_NAME");
- bc_error_free(err);
-}
-
-
-static void
-test_settings(void **state)
-{
- const char *a =
- "[settings]\n"
- "content_dir = guda\n"
- "main_template = foo.tmpl\n"
- "\n"
- "[global]\n"
- "BOLA = asd\n"
- "GUDA = qwe\n";
- bc_error_t *err = NULL;
- bm_settings_t *s = bm_settings_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(s);
- assert_int_equal(err->type, BLOGC_MAKE_ERROR_SETTINGS);
- assert_string_equal(err->msg,
- "[global] key required but not found or empty: AUTHOR_NAME");
- bc_error_free(err);
-
- a =
- "[settings]\n"
- "content_dir = guda\n"
- "main_template = foo.tmpl\n"
- "\n"
- "[global]\n"
- "bOLA = asd\n"
- "GUDA = qwe\n";
- err = NULL;
- s = bm_settings_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(s);
- assert_int_equal(err->type, BLOGC_MAKE_ERROR_SETTINGS);
- assert_string_equal(err->msg,
- "Invalid [global] key (first character must be uppercase): bOLA");
- bc_error_free(err);
-
- a =
- "[settings]\n"
- "content_dir = guda\n"
- "main_template = foo.tmpl\n"
- "\n"
- "[global]\n"
- "BOLA = asd\n"
- "GUDa = qwe\n";
- err = NULL;
- s = bm_settings_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(s);
- assert_int_equal(err->type, BLOGC_MAKE_ERROR_SETTINGS);
- assert_string_equal(err->msg,
- "Invalid [global] key (must be uppercase with '_' and digits after first character): GUDa");
- bc_error_free(err);
-}
-
-
-static void
-test_settings_env(void **state)
-{
- const char *a =
- "[settings]\n"
- "content_dir = guda\n"
- "main_template = foo.tmpl\n"
- "\n"
- "[environment]\n"
- "BOLA = asd\n"
- "GUDA = qwe\n";
- bc_error_t *err = NULL;
- bm_settings_t *s = bm_settings_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(s);
- assert_int_equal(err->type, BLOGC_MAKE_ERROR_SETTINGS);
- assert_string_equal(err->msg,
- "[environment] key required but not found or empty: AUTHOR_NAME");
- bc_error_free(err);
-}
-
-
-static void
-test_settings2(void **state)
-{
- const char *a =
- "[settings]\n"
- "content_dir = guda\n"
- "main_template = foo.tmpl\n"
- "\n"
- "[global]\n"
- "BOLA = asd\n"
- "GUDA = qwe\n"
- "AUTHOR_NAME = chunda\n"
- "AUTHOR_EMAIL = chunda@example.com\n"
- "SITE_TITLE = Fuuuuuuuuu\n"
- "SITE_TAGLINE = My cool tagline\n"
- "BASE_DOMAIN = http://example.com\n"
- "\n"
- "[posts]\n"
- "\n"
- "aaaa\n"
- "bbbb\n"
- "cccc\n"
- "[pages]\n"
- " dddd\n"
- "eeee\n"
- "ffff\n"
- "[tags]\n"
- "gggg\n"
- "\n"
- " hhhh\n"
- "iiii\n"
- "[copy]\n"
- "jjjj\n"
- "kkkk\n"
- "llll\n";
- bc_error_t *err = NULL;
- bm_settings_t *s = bm_settings_parse(a, strlen(a), &err);
- assert_null(err);
- assert_non_null(s);
- assert_int_equal(bc_trie_size(s->global), 7);
- assert_string_equal(bc_trie_lookup(s->global, "BOLA"), "asd");
- assert_string_equal(bc_trie_lookup(s->global, "GUDA"), "qwe");
- assert_string_equal(bc_trie_lookup(s->global, "AUTHOR_NAME"), "chunda");
- assert_string_equal(bc_trie_lookup(s->global, "AUTHOR_EMAIL"), "chunda@example.com");
- assert_string_equal(bc_trie_lookup(s->global, "SITE_TITLE"), "Fuuuuuuuuu");
- assert_string_equal(bc_trie_lookup(s->global, "SITE_TAGLINE"), "My cool tagline");
- assert_string_equal(bc_trie_lookup(s->global, "BASE_DOMAIN"), "http://example.com");
- assert_int_equal(bc_trie_size(s->settings), 16);
- assert_string_equal(bc_trie_lookup(s->settings, "source_ext"), ".txt");
- assert_string_equal(bc_trie_lookup(s->settings, "html_ext"), "/index.html");
- assert_string_equal(bc_trie_lookup(s->settings, "content_dir"), "guda");
- assert_string_equal(bc_trie_lookup(s->settings, "template_dir"), "templates");
- assert_string_equal(bc_trie_lookup(s->settings, "main_template"), "foo.tmpl");
- assert_string_equal(bc_trie_lookup(s->settings, "date_format"),
- "%b %d, %Y, %I:%M %p GMT");
- assert_string_equal(bc_trie_lookup(s->settings, "posts_per_page"), "10");
- assert_string_equal(bc_trie_lookup(s->settings, "atom_prefix"), "atom");
- assert_string_equal(bc_trie_lookup(s->settings, "atom_ext"), ".xml");
- assert_string_equal(bc_trie_lookup(s->settings, "atom_posts_per_page"), "10");
- assert_string_equal(bc_trie_lookup(s->settings, "pagination_prefix"), "page");
- assert_string_equal(bc_trie_lookup(s->settings, "post_prefix"), "post");
- assert_string_equal(bc_trie_lookup(s->settings, "tag_prefix"), "tag");
- assert_string_equal(bc_trie_lookup(s->settings, "html_order"), "DESC");
- assert_string_equal(bc_trie_lookup(s->settings, "atom_order"), "DESC");
- assert_string_equal(bc_trie_lookup(s->settings, "index_prefix"), "");
- assert_non_null(s->posts);
- assert_string_equal(s->posts[0], "aaaa");
- assert_string_equal(s->posts[1], "bbbb");
- assert_string_equal(s->posts[2], "cccc");
- assert_null(s->posts[3]);
- assert_non_null(s->pages);
- assert_string_equal(s->pages[0], "dddd");
- assert_string_equal(s->pages[1], "eeee");
- assert_string_equal(s->pages[2], "ffff");
- assert_null(s->pages[3]);
- assert_non_null(s->copy);
- assert_string_equal(s->copy[0], "jjjj");
- assert_string_equal(s->copy[1], "kkkk");
- assert_string_equal(s->copy[2], "llll");
- assert_null(s->copy[3]);
- assert_non_null(s->tags);
- assert_string_equal(s->tags[0], "gggg");
- assert_string_equal(s->tags[1], "hhhh");
- assert_string_equal(s->tags[2], "iiii");
- assert_null(s->tags[3]);
- bm_settings_free(s);
-}
-
-
-static void
-test_settings_env2(void **state)
-{
- const char *a =
- "[settings]\n"
- "content_dir = guda\n"
- "main_template = foo.tmpl\n"
- "\n"
- "[environment]\n"
- "BOLA = asd\n"
- "GUDA = qwe\n"
- "AUTHOR_NAME = chunda\n"
- "AUTHOR_EMAIL = chunda@example.com\n"
- "SITE_TITLE = Fuuuuuuuuu\n"
- "SITE_TAGLINE = My cool tagline\n"
- "BASE_DOMAIN = http://example.com\n"
- "\n"
- "[posts]\n"
- "\n"
- "aaaa\n"
- "bbbb\n"
- "cccc\n"
- "[pages]\n"
- " dddd\n"
- "eeee\n"
- "ffff\n"
- "[tags]\n"
- "gggg\n"
- "\n"
- " hhhh\n"
- "iiii\n"
- "[copy]\n"
- "jjjj\n"
- "kkkk\n"
- "llll\n";
- bc_error_t *err = NULL;
- bm_settings_t *s = bm_settings_parse(a, strlen(a), &err);
- assert_null(err);
- assert_non_null(s);
- assert_int_equal(bc_trie_size(s->global), 7);
- assert_string_equal(bc_trie_lookup(s->global, "BOLA"), "asd");
- assert_string_equal(bc_trie_lookup(s->global, "GUDA"), "qwe");
- assert_string_equal(bc_trie_lookup(s->global, "AUTHOR_NAME"), "chunda");
- assert_string_equal(bc_trie_lookup(s->global, "AUTHOR_EMAIL"), "chunda@example.com");
- assert_string_equal(bc_trie_lookup(s->global, "SITE_TITLE"), "Fuuuuuuuuu");
- assert_string_equal(bc_trie_lookup(s->global, "SITE_TAGLINE"), "My cool tagline");
- assert_string_equal(bc_trie_lookup(s->global, "BASE_DOMAIN"), "http://example.com");
- assert_int_equal(bc_trie_size(s->settings), 16);
- assert_string_equal(bc_trie_lookup(s->settings, "source_ext"), ".txt");
- assert_string_equal(bc_trie_lookup(s->settings, "html_ext"), "/index.html");
- assert_string_equal(bc_trie_lookup(s->settings, "content_dir"), "guda");
- assert_string_equal(bc_trie_lookup(s->settings, "template_dir"), "templates");
- assert_string_equal(bc_trie_lookup(s->settings, "main_template"), "foo.tmpl");
- assert_string_equal(bc_trie_lookup(s->settings, "date_format"),
- "%b %d, %Y, %I:%M %p GMT");
- assert_string_equal(bc_trie_lookup(s->settings, "posts_per_page"), "10");
- assert_string_equal(bc_trie_lookup(s->settings, "atom_prefix"), "atom");
- assert_string_equal(bc_trie_lookup(s->settings, "atom_ext"), ".xml");
- assert_string_equal(bc_trie_lookup(s->settings, "atom_posts_per_page"), "10");
- assert_string_equal(bc_trie_lookup(s->settings, "pagination_prefix"), "page");
- assert_string_equal(bc_trie_lookup(s->settings, "post_prefix"), "post");
- assert_string_equal(bc_trie_lookup(s->settings, "tag_prefix"), "tag");
- assert_string_equal(bc_trie_lookup(s->settings, "html_order"), "DESC");
- assert_string_equal(bc_trie_lookup(s->settings, "atom_order"), "DESC");
- assert_string_equal(bc_trie_lookup(s->settings, "index_prefix"), "");
- assert_non_null(s->posts);
- assert_string_equal(s->posts[0], "aaaa");
- assert_string_equal(s->posts[1], "bbbb");
- assert_string_equal(s->posts[2], "cccc");
- assert_null(s->posts[3]);
- assert_non_null(s->pages);
- assert_string_equal(s->pages[0], "dddd");
- assert_string_equal(s->pages[1], "eeee");
- assert_string_equal(s->pages[2], "ffff");
- assert_null(s->pages[3]);
- assert_non_null(s->copy);
- assert_string_equal(s->copy[0], "jjjj");
- assert_string_equal(s->copy[1], "kkkk");
- assert_string_equal(s->copy[2], "llll");
- assert_null(s->copy[3]);
- assert_non_null(s->tags);
- assert_string_equal(s->tags[0], "gggg");
- assert_string_equal(s->tags[1], "hhhh");
- assert_string_equal(s->tags[2], "iiii");
- assert_null(s->tags[3]);
- bm_settings_free(s);
-}
-
-
-static void
-test_settings_copy_files(void **state)
-{
- const char *a =
- "[settings]\n"
- "content_dir = guda\n"
- "main_template = foo.tmpl\n"
- "\n"
- "[global]\n"
- "BOLA = asd\n"
- "GUDA = qwe\n"
- "AUTHOR_NAME = chunda\n"
- "AUTHOR_EMAIL = chunda@example.com\n"
- "SITE_TITLE = Fuuuuuuuuu\n"
- "SITE_TAGLINE = My cool tagline\n"
- "BASE_DOMAIN = http://example.com\n"
- "\n"
- "[posts]\n"
- "\n"
- "aaaa\n"
- "bbbb\n"
- "cccc\n"
- "[pages]\n"
- " dddd\n"
- "eeee\n"
- "ffff\n"
- "[tags]\n"
- "gggg\n"
- "\n"
- " hhhh\n"
- "iiii\n"
- "[copy_files]\n"
- "jjjj\n"
- "kkkk\n"
- "llll\n";
- bc_error_t *err = NULL;
- bm_settings_t *s = bm_settings_parse(a, strlen(a), &err);
- assert_null(err);
- assert_non_null(s);
- assert_int_equal(bc_trie_size(s->global), 7);
- assert_string_equal(bc_trie_lookup(s->global, "BOLA"), "asd");
- assert_string_equal(bc_trie_lookup(s->global, "GUDA"), "qwe");
- assert_string_equal(bc_trie_lookup(s->global, "AUTHOR_NAME"), "chunda");
- assert_string_equal(bc_trie_lookup(s->global, "AUTHOR_EMAIL"), "chunda@example.com");
- assert_string_equal(bc_trie_lookup(s->global, "SITE_TITLE"), "Fuuuuuuuuu");
- assert_string_equal(bc_trie_lookup(s->global, "SITE_TAGLINE"), "My cool tagline");
- assert_string_equal(bc_trie_lookup(s->global, "BASE_DOMAIN"), "http://example.com");
- assert_int_equal(bc_trie_size(s->settings), 16);
- assert_string_equal(bc_trie_lookup(s->settings, "source_ext"), ".txt");
- assert_string_equal(bc_trie_lookup(s->settings, "html_ext"), "/index.html");
- assert_string_equal(bc_trie_lookup(s->settings, "content_dir"), "guda");
- assert_string_equal(bc_trie_lookup(s->settings, "template_dir"), "templates");
- assert_string_equal(bc_trie_lookup(s->settings, "main_template"), "foo.tmpl");
- assert_string_equal(bc_trie_lookup(s->settings, "date_format"),
- "%b %d, %Y, %I:%M %p GMT");
- assert_string_equal(bc_trie_lookup(s->settings, "posts_per_page"), "10");
- assert_string_equal(bc_trie_lookup(s->settings, "atom_prefix"), "atom");
- assert_string_equal(bc_trie_lookup(s->settings, "atom_ext"), ".xml");
- assert_string_equal(bc_trie_lookup(s->settings, "atom_posts_per_page"), "10");
- assert_string_equal(bc_trie_lookup(s->settings, "pagination_prefix"), "page");
- assert_string_equal(bc_trie_lookup(s->settings, "post_prefix"), "post");
- assert_string_equal(bc_trie_lookup(s->settings, "tag_prefix"), "tag");
- assert_string_equal(bc_trie_lookup(s->settings, "html_order"), "DESC");
- assert_string_equal(bc_trie_lookup(s->settings, "atom_order"), "DESC");
- assert_string_equal(bc_trie_lookup(s->settings, "index_prefix"), "");
- assert_non_null(s->posts);
- assert_string_equal(s->posts[0], "aaaa");
- assert_string_equal(s->posts[1], "bbbb");
- assert_string_equal(s->posts[2], "cccc");
- assert_null(s->posts[3]);
- assert_non_null(s->pages);
- assert_string_equal(s->pages[0], "dddd");
- assert_string_equal(s->pages[1], "eeee");
- assert_string_equal(s->pages[2], "ffff");
- assert_null(s->pages[3]);
- assert_non_null(s->copy);
- assert_string_equal(s->copy[0], "jjjj");
- assert_string_equal(s->copy[1], "kkkk");
- assert_string_equal(s->copy[2], "llll");
- assert_null(s->copy[3]);
- assert_non_null(s->tags);
- assert_string_equal(s->tags[0], "gggg");
- assert_string_equal(s->tags[1], "hhhh");
- assert_string_equal(s->tags[2], "iiii");
- assert_null(s->tags[3]);
- bm_settings_free(s);
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_settings_empty),
- cmocka_unit_test(test_settings),
- cmocka_unit_test(test_settings_env),
- cmocka_unit_test(test_settings2),
- cmocka_unit_test(test_settings_env2),
- cmocka_unit_test(test_settings_copy_files),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/blogc-make/check_utils.c b/tests/blogc-make/check_utils.c
deleted file mode 100644
index 09d1580..0000000
--- a/tests/blogc-make/check_utils.c
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-
-#include <stdlib.h>
-
-#include "../../src/blogc-make/utils.h"
-#include "../../src/common/utils.h"
-
-
-static void
-test_generate_filename(void **state)
-{
- char *rv;
-
- assert_null(bm_generate_filename(NULL, NULL, NULL, NULL));
- assert_null(bm_generate_filename(NULL, "", "", ""));
- assert_null(bm_generate_filename("_build", NULL, NULL, NULL));
- assert_null(bm_generate_filename("_build", "", "", ""));
-
- rv = bm_generate_filename(NULL, NULL, NULL, ".html");
- assert_string_equal(rv, "/index.html");
- free(rv);
-
- rv = bm_generate_filename(NULL, NULL, NULL, "/index.html");
- assert_string_equal(rv, "/index.html");
- free(rv);
-
- rv = bm_generate_filename(NULL, "lol", NULL, ".html");
- assert_string_equal(rv, "/lol.html");
- free(rv);
-
- rv = bm_generate_filename(NULL, "lol", NULL, "/index.html");
- assert_string_equal(rv, "/lol/index.html");
- free(rv);
-
- rv = bm_generate_filename(NULL, NULL, "foo", ".html");
- assert_string_equal(rv, "/foo.html");
- free(rv);
-
- rv = bm_generate_filename(NULL, NULL, "foo", "/index.html");
- assert_string_equal(rv, "/foo/index.html");
- free(rv);
-
- rv = bm_generate_filename(NULL, NULL, "index", ".html");
- assert_string_equal(rv, "/index.html");
- free(rv);
-
- rv = bm_generate_filename(NULL, "lol", "index", ".html");
- assert_string_equal(rv, "/lol/index.html");
- free(rv);
-
- rv = bm_generate_filename(NULL, NULL, "index", "/index.html");
- assert_string_equal(rv, "/index.html");
- free(rv);
-
- rv = bm_generate_filename(NULL, "lol", "index", "/index.html");
- assert_string_equal(rv, "/lol/index/index.html");
- free(rv);
-
- rv = bm_generate_filename(NULL, "bar", "foo", ".html");
- assert_string_equal(rv, "/bar/foo.html");
- free(rv);
-
- rv = bm_generate_filename(NULL, "bar", "foo", "/index.html");
- assert_string_equal(rv, "/bar/foo/index.html");
- free(rv);
-
- rv = bm_generate_filename("_build", NULL, NULL, ".html");
- assert_string_equal(rv, "_build/index.html");
- free(rv);
-
- rv = bm_generate_filename("_build", NULL, NULL, "/index.html");
- assert_string_equal(rv, "_build/index.html");
- free(rv);
-
- rv = bm_generate_filename("_build", "lol", NULL, ".html");
- assert_string_equal(rv, "_build/lol.html");
- free(rv);
-
- rv = bm_generate_filename("_build", "lol", NULL, "/index.html");
- assert_string_equal(rv, "_build/lol/index.html");
- free(rv);
-
- rv = bm_generate_filename("_build", NULL, "foo", ".html");
- assert_string_equal(rv, "_build/foo.html");
- free(rv);
-
- rv = bm_generate_filename("_build", NULL, "foo", "/index.html");
- assert_string_equal(rv, "_build/foo/index.html");
- free(rv);
-
- rv = bm_generate_filename("_build", NULL, "index", ".html");
- assert_string_equal(rv, "_build/index.html");
- free(rv);
-
- rv = bm_generate_filename("_build", "lol", "index", ".html");
- assert_string_equal(rv, "_build/lol/index.html");
- free(rv);
-
- rv = bm_generate_filename("_build", NULL, "index", "/index.html");
- assert_string_equal(rv, "_build/index.html");
- free(rv);
-
- rv = bm_generate_filename("_build", "lol", "index", "/index.html");
- assert_string_equal(rv, "_build/lol/index/index.html");
- free(rv);
-
- rv = bm_generate_filename("_build", "bar", "foo", ".html");
- assert_string_equal(rv, "_build/bar/foo.html");
- free(rv);
-
- rv = bm_generate_filename("_build", "bar", "foo", "/index.html");
- assert_string_equal(rv, "_build/bar/foo/index.html");
- free(rv);
-}
-
-
-static void
-test_generate_filename2(void **state)
-{
- char *rv;
-
- assert_null(bm_generate_filename2(NULL, NULL, NULL, NULL, NULL, NULL));
- assert_null(bm_generate_filename2(NULL, "", "", "", "", ""));
- assert_null(bm_generate_filename2("_build", NULL, NULL, NULL, NULL, NULL));
- assert_null(bm_generate_filename2("_build", "", "", "", "", ""));
-
- rv = bm_generate_filename2(NULL, NULL, NULL, NULL, NULL, ".html");
- assert_string_equal(rv, "/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, "p", NULL, NULL, NULL, ".html");
- assert_string_equal(rv, "/p.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, NULL, "q", NULL, NULL, ".html");
- assert_string_equal(rv, "/q.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, "p", "q", NULL, NULL, ".html");
- assert_string_equal(rv, "/p/q.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, NULL, NULL, NULL, NULL, "/index.html");
- assert_string_equal(rv, "/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, "p", NULL, NULL, NULL, "/index.html");
- assert_string_equal(rv, "/p/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, NULL, "q", NULL, NULL, "/index.html");
- assert_string_equal(rv, "/q/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, "p", "q", NULL, NULL, "/index.html");
- assert_string_equal(rv, "/p/q/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, NULL, NULL, "lol", NULL, ".html");
- assert_string_equal(rv, "/lol.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, "p", NULL, "lol", NULL, ".html");
- assert_string_equal(rv, "/p/lol.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, NULL, "q", "lol", NULL, ".html");
- assert_string_equal(rv, "/q/lol.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, "p", "q", "lol", NULL, ".html");
- assert_string_equal(rv, "/p/q/lol.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, NULL, NULL, "lol", NULL, "/index.html");
- assert_string_equal(rv, "/lol/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, "p", NULL, "lol", NULL, "/index.html");
- assert_string_equal(rv, "/p/lol/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, NULL, "q", "lol", NULL, "/index.html");
- assert_string_equal(rv, "/q/lol/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, "p", "q", "lol", NULL, "/index.html");
- assert_string_equal(rv, "/p/q/lol/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, NULL, NULL, NULL, "foo", ".html");
- assert_string_equal(rv, "/foo.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, "p", NULL, NULL, "foo", ".html");
- assert_string_equal(rv, "/p/foo.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, NULL, "q", NULL, "foo", ".html");
- assert_string_equal(rv, "/q/foo.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, "p", "q", NULL, "foo", ".html");
- assert_string_equal(rv, "/p/q/foo.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, NULL, NULL, NULL, "foo", "/index.html");
- assert_string_equal(rv, "/foo/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, "p", NULL, NULL, "foo", "/index.html");
- assert_string_equal(rv, "/p/foo/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, NULL, "q", NULL, "foo", "/index.html");
- assert_string_equal(rv, "/q/foo/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, "p", "q", NULL, "foo", "/index.html");
- assert_string_equal(rv, "/p/q/foo/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, NULL, NULL, NULL, "index", ".html");
- assert_string_equal(rv, "/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, "p", NULL, NULL, "index", ".html");
- assert_string_equal(rv, "/p/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, NULL, "q", NULL, "index", ".html");
- assert_string_equal(rv, "/q/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, "p", "q", NULL, "index", ".html");
- assert_string_equal(rv, "/p/q/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, NULL, NULL, NULL, "index", "/index.html");
- assert_string_equal(rv, "/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, "p", NULL, NULL, "index", "/index.html");
- assert_string_equal(rv, "/p/index/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, NULL, "q", NULL, "index", "/index.html");
- assert_string_equal(rv, "/q/index/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, "p", "q", NULL, "index", "/index.html");
- assert_string_equal(rv, "/p/q/index/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, NULL, NULL, "bar", "foo", ".html");
- assert_string_equal(rv, "/bar/foo.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, "p", NULL, "bar", "foo", ".html");
- assert_string_equal(rv, "/p/bar/foo.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, NULL, "q", "bar", "foo", ".html");
- assert_string_equal(rv, "/q/bar/foo.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, "p", "q", "bar", "foo", ".html");
- assert_string_equal(rv, "/p/q/bar/foo.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, NULL, NULL, "bar", "foo", "/index.html");
- assert_string_equal(rv, "/bar/foo/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, "p", NULL, "bar", "foo", "/index.html");
- assert_string_equal(rv, "/p/bar/foo/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, NULL, "q", "bar", "foo", "/index.html");
- assert_string_equal(rv, "/q/bar/foo/index.html");
- free(rv);
-
- rv = bm_generate_filename2(NULL, "p", "q", "bar", "foo", "/index.html");
- assert_string_equal(rv, "/p/q/bar/foo/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", NULL, NULL, NULL, NULL, ".html");
- assert_string_equal(rv, "_build/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", "p", NULL, NULL, NULL, ".html");
- assert_string_equal(rv, "_build/p.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", NULL, "q", NULL, NULL, ".html");
- assert_string_equal(rv, "_build/q.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", "p", "q", NULL, NULL, ".html");
- assert_string_equal(rv, "_build/p/q.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", NULL, NULL, NULL, NULL, "/index.html");
- assert_string_equal(rv, "_build/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", "p", NULL, NULL, NULL, "/index.html");
- assert_string_equal(rv, "_build/p/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", NULL, "q", NULL, NULL, "/index.html");
- assert_string_equal(rv, "_build/q/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", "p", "q", NULL, NULL, "/index.html");
- assert_string_equal(rv, "_build/p/q/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", NULL, NULL, "lol", NULL, ".html");
- assert_string_equal(rv, "_build/lol.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", "p", NULL, "lol", NULL, ".html");
- assert_string_equal(rv, "_build/p/lol.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", NULL, "q", "lol", NULL, ".html");
- assert_string_equal(rv, "_build/q/lol.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", "p", "q", "lol", NULL, ".html");
- assert_string_equal(rv, "_build/p/q/lol.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", NULL, NULL, "lol", NULL, "/index.html");
- assert_string_equal(rv, "_build/lol/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", "p", NULL, "lol", NULL, "/index.html");
- assert_string_equal(rv, "_build/p/lol/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", NULL, "q", "lol", NULL, "/index.html");
- assert_string_equal(rv, "_build/q/lol/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", "p", "q", "lol", NULL, "/index.html");
- assert_string_equal(rv, "_build/p/q/lol/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", NULL, NULL, NULL, "foo", ".html");
- assert_string_equal(rv, "_build/foo.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", "p", NULL, NULL, "foo", ".html");
- assert_string_equal(rv, "_build/p/foo.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", NULL, "q", NULL, "foo", ".html");
- assert_string_equal(rv, "_build/q/foo.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", "p", "q", NULL, "foo", ".html");
- assert_string_equal(rv, "_build/p/q/foo.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", NULL, NULL, NULL, "foo", "/index.html");
- assert_string_equal(rv, "_build/foo/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", "p", NULL, NULL, "foo", "/index.html");
- assert_string_equal(rv, "_build/p/foo/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", NULL, "q", NULL, "foo", "/index.html");
- assert_string_equal(rv, "_build/q/foo/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", "p", "q", NULL, "foo", "/index.html");
- assert_string_equal(rv, "_build/p/q/foo/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", NULL, NULL, NULL, "index", ".html");
- assert_string_equal(rv, "_build/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", "p", NULL, NULL, "index", ".html");
- assert_string_equal(rv, "_build/p/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", NULL, "q", NULL, "index", ".html");
- assert_string_equal(rv, "_build/q/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", "p", "q", NULL, "index", ".html");
- assert_string_equal(rv, "_build/p/q/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", NULL, NULL, NULL, "index", "/index.html");
- assert_string_equal(rv, "_build/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", "p", NULL, NULL, "index", "/index.html");
- assert_string_equal(rv, "_build/p/index/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", NULL, "q", NULL, "index", "/index.html");
- assert_string_equal(rv, "_build/q/index/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", "p", "q", NULL, "index", "/index.html");
- assert_string_equal(rv, "_build/p/q/index/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", NULL, NULL, "bar", "foo", ".html");
- assert_string_equal(rv, "_build/bar/foo.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", "p", NULL, "bar", "foo", ".html");
- assert_string_equal(rv, "_build/p/bar/foo.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", NULL, "q", "bar", "foo", ".html");
- assert_string_equal(rv, "_build/q/bar/foo.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", "p", "q", "bar", "foo", ".html");
- assert_string_equal(rv, "_build/p/q/bar/foo.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", NULL, NULL, "bar", "foo", "/index.html");
- assert_string_equal(rv, "_build/bar/foo/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", "p", NULL, "bar", "foo", "/index.html");
- assert_string_equal(rv, "_build/p/bar/foo/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", NULL, "q", "bar", "foo", "/index.html");
- assert_string_equal(rv, "_build/q/bar/foo/index.html");
- free(rv);
-
- rv = bm_generate_filename2("_build", "p", "q", "bar", "foo", "/index.html");
- assert_string_equal(rv, "_build/p/q/bar/foo/index.html");
- free(rv);
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_generate_filename),
- cmocka_unit_test(test_generate_filename2),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/blogc-runserver/check_httpd_utils.c b/tests/blogc-runserver/check_httpd_utils.c
deleted file mode 100644
index 9b2c39c..0000000
--- a/tests/blogc-runserver/check_httpd_utils.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#include <stdlib.h>
-#include <string.h>
-#include "../../src/common/utils.h"
-#include "../../src/blogc-runserver/httpd-utils.h"
-
-
-ssize_t
-__wrap_read(int fd, void *buf, size_t count)
-{
- assert_int_equal(fd, mock_type(int));
- const char *mock_buf = mock_type(const char*);
- strcpy(buf, mock_buf);
- assert_int_equal(count, READLINE_BUFFER_SIZE);
- return strlen(mock_buf) > 0 ? strlen(mock_buf) : -1;
-}
-
-
-static void
-test_readline(void **state)
-{
- char *t;
- will_return(__wrap_read, 1234);
- will_return(__wrap_read, "bola");
- t = br_readline(1234);
- assert_string_equal(t, "bola");
- free(t);
- will_return(__wrap_read, 1234);
- will_return(__wrap_read, "bola1\nguda\nxd");
- t = br_readline(1234);
- assert_string_equal(t, "bola1");
- free(t);
- will_return(__wrap_read, 1234);
- will_return(__wrap_read, "bola2\rguda\rxd");
- t = br_readline(1234);
- assert_string_equal(t, "bola2");
- free(t);
- will_return(__wrap_read, 1234);
- will_return(__wrap_read, "bola3\r\nguda\r\nxd");
- t = br_readline(1234);
- assert_string_equal(t, "bola3");
- free(t);
-}
-
-
-static void
-test_hextoi(void **state)
-{
- assert_int_equal(br_hextoi('0'), 0);
- assert_int_equal(br_hextoi('1'), 1);
- assert_int_equal(br_hextoi('2'), 2);
- assert_int_equal(br_hextoi('3'), 3);
- assert_int_equal(br_hextoi('4'), 4);
- assert_int_equal(br_hextoi('5'), 5);
- assert_int_equal(br_hextoi('6'), 6);
- assert_int_equal(br_hextoi('7'), 7);
- assert_int_equal(br_hextoi('8'), 8);
- assert_int_equal(br_hextoi('9'), 9);
- assert_int_equal(br_hextoi('a'), 10);
- assert_int_equal(br_hextoi('b'), 11);
- assert_int_equal(br_hextoi('c'), 12);
- assert_int_equal(br_hextoi('d'), 13);
- assert_int_equal(br_hextoi('e'), 14);
- assert_int_equal(br_hextoi('f'), 15);
- assert_int_equal(br_hextoi('A'), 10);
- assert_int_equal(br_hextoi('B'), 11);
- assert_int_equal(br_hextoi('C'), 12);
- assert_int_equal(br_hextoi('D'), 13);
- assert_int_equal(br_hextoi('E'), 14);
- assert_int_equal(br_hextoi('F'), 15);
- assert_int_equal(br_hextoi('g'), -1);
- assert_int_equal(br_hextoi('G'), -1);
- assert_int_equal(br_hextoi('-'), -1);
-}
-
-
-static void
-test_urldecode(void **state)
-{
- for (size_t i = 0; i < 128; i++) {
- char *t = bc_strdup_printf("%%%02x", i);
- char *r = br_urldecode(t);
- assert_int_equal(r[0], i);
- assert_int_equal(r[1], 0);
- free(r);
- free(t);
- }
- char *r = br_urldecode("%Ab");
- assert_string_equal(r, "\xab");
- free(r);
- r = br_urldecode("%xb");
- assert_string_equal(r, "%xb");
- free(r);
- r = br_urldecode("%C3%BC");
- assert_string_equal(r, "\xc3\xbc");
- free(r);
-}
-
-
-static void
-test_get_extension(void **state)
-{
- assert_null(br_get_extension("bola"));
- assert_string_equal(br_get_extension("bola.txt"), "txt");
- assert_string_equal(br_get_extension("bola.txt.jpg"), "jpg");
- assert_null(br_get_extension("bola.txt/foo"));
- assert_string_equal(br_get_extension("bola.txt/foo.jpg"), "jpg");
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_readline),
- cmocka_unit_test(test_hextoi),
- cmocka_unit_test(test_urldecode),
- cmocka_unit_test(test_get_extension),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/blogc-runserver/check_mime.c b/tests/blogc-runserver/check_mime.c
deleted file mode 100644
index 59d7238..0000000
--- a/tests/blogc-runserver/check_mime.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include "../../src/blogc-runserver/mime.h"
-
-
-int
-__wrap_access(const char *pathname, int mode)
-{
- assert_string_equal(pathname, mock_type(const char*));
- assert_int_equal(mode, F_OK);
- return mock_type(int);
-}
-
-
-static void
-test_guess_content_type(void **state)
-{
- assert_string_equal(br_mime_guess_content_type("foo.html"), "text/html");
- assert_string_equal(br_mime_guess_content_type("foo.jpg"), "image/jpeg");
- assert_string_equal(br_mime_guess_content_type("foo.mp4"), "video/mp4");
- assert_string_equal(br_mime_guess_content_type("foo.bola"), "application/octet-stream");
-}
-
-
-static void
-test_guess_index(void **state)
-{
- char *t;
- will_return(__wrap_access, "dir/index.html");
- will_return(__wrap_access, 0);
- t = br_mime_guess_index("dir");
- assert_string_equal(t, "dir/index.html");
- free(t);
- will_return(__wrap_access, "dir/index.html");
- will_return(__wrap_access, 1);
- will_return(__wrap_access, "dir/index.htm");
- will_return(__wrap_access, 0);
- t = br_mime_guess_index("dir");
- assert_string_equal(t, "dir/index.htm");
- free(t);
- will_return(__wrap_access, "dir/index.html");
- will_return(__wrap_access, 1);
- will_return(__wrap_access, "dir/index.htm");
- will_return(__wrap_access, 1);
- will_return(__wrap_access, "dir/index.shtml");
- will_return(__wrap_access, 1);
- will_return(__wrap_access, "dir/index.xml");
- will_return(__wrap_access, 1);
- will_return(__wrap_access, "dir/index.txt");
- will_return(__wrap_access, 1);
- will_return(__wrap_access, "dir/index.xhtml");
- will_return(__wrap_access, 0);
- t = br_mime_guess_index("dir");
- assert_string_equal(t, "dir/index.xhtml");
- free(t);
- will_return(__wrap_access, "dir/index.html");
- will_return(__wrap_access, 1);
- will_return(__wrap_access, "dir/index.htm");
- will_return(__wrap_access, 1);
- will_return(__wrap_access, "dir/index.shtml");
- will_return(__wrap_access, 1);
- will_return(__wrap_access, "dir/index.xml");
- will_return(__wrap_access, 1);
- will_return(__wrap_access, "dir/index.txt");
- will_return(__wrap_access, 1);
- will_return(__wrap_access, "dir/index.xhtml");
- will_return(__wrap_access, 1);
- assert_null(br_mime_guess_index("dir"));
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_guess_content_type),
- cmocka_unit_test(test_guess_index),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/blogc/check_blogc.sh.in b/tests/blogc/check_blogc.sh.in
deleted file mode 100755
index 208524d..0000000
--- a/tests/blogc/check_blogc.sh.in
+++ /dev/null
@@ -1,638 +0,0 @@
-#!@BASH@
-
-set -xe -o pipefail
-
-export LC_ALL=C
-
-TEMP="$(mktemp -d)"
-[[ -n "${TEMP}" ]]
-
-trap_func() {
- [[ -n "${TEMP}" ]] && rm -rf "${TEMP}"
-}
-
-trap trap_func EXIT
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc -v | grep blogc
-
-cat > "${TEMP}/post1.txt" <<EOF
-TITLE: foo
-DATE: 2010-01-01 11:11:11
--------------------------
-foo?
-EOF
-
-cat > "${TEMP}/post2.txt" <<EOF
-TITLE: bar
-DATE: 2010-01-01 22:22:22
--------------------------
-bar?
-EOF
-
-cat > "${TEMP}/post3.txt" <<EOF
-TITLE: baz
-DATE: 2010-02-02 22:22:22
--------------------------
-bar?
-EOF
-
-cat > "${TEMP}/atom.tmpl" <<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">{{ SITE_TITLE }}</title>
- <id>{{ BASE_URL }}/atom.xml</id>
- <updated>{{ DATE_FIRST_FORMATTED }}</updated>
- <link href="{{ BASE_DOMAIN }}{{ BASE_URL }}/" />
- <link href="{{ BASE_DOMAIN }}{{ BASE_URL }}/atom.xml" rel="self" />
- <author>
- <name>{{ AUTHOR_NAME }}</name>
- <email>{{ AUTHOR_EMAIL }}</email>
- </author>
- <subtitle type="text">{{ SITE_TAGLINE }}</subtitle>
- {% block listing %}
- <entry>
- <title type="text">{{ TITLE }}</title>
- <id>{{ BASE_URL }}/post/{{ FILENAME }}/</id>
- <updated>{{ DATE_FORMATTED }}</updated>
- <published>{{ DATE_FORMATTED }}</published>
- <link href="{{ BASE_DOMAIN }}{{ BASE_URL }}/post/{{ FILENAME }}/" />
- <author>
- <name>{{ AUTHOR_NAME }}</name>
- <email>{{ AUTHOR_EMAIL }}</email>
- </author>
- <content type="html"><![CDATA[{{ CONTENT_4 }}]]></content>
- </entry>
- {% endblock %}
-</feed>
-EOF
-
-cat > "${TEMP}/expected-output.xml" <<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Chunda's website</title>
- <id>/atom.xml</id>
- <updated>2010-01-01T11:11:11Z</updated>
- <link href="http://bola.com//" />
- <link href="http://bola.com//atom.xml" rel="self" />
- <author>
- <name>Chunda</name>
- <email>chunda@bola.com</email>
- </author>
- <subtitle type="text"></subtitle>
-
- <entry>
- <title type="text">foo</title>
- <id>/post/post1/</id>
- <updated>2010-01-01T11:11:11Z</updated>
- <published>2010-01-01T11:11:11Z</published>
- <link href="http://bola.com//post/post1/" />
- <author>
- <name>Chunda</name>
- <email>chunda@bola.com</email>
- </author>
- <content type="html"><![CDATA[<p>f]]></content>
- </entry>
-
- <entry>
- <title type="text">bar</title>
- <id>/post/post2/</id>
- <updated>2010-01-01T22:22:22Z</updated>
- <published>2010-01-01T22:22:22Z</published>
- <link href="http://bola.com//post/post2/" />
- <author>
- <name>Chunda</name>
- <email>chunda@bola.com</email>
- </author>
- <content type="html"><![CDATA[<p>b]]></content>
- </entry>
-
-</feed>
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D BASE_DOMAIN=http://bola.com/ \
- -D BASE_URL= \
- -D AUTHOR_NAME=Chunda \
- -D AUTHOR_EMAIL=chunda@bola.com \
- -D SITE_TITLE="Chunda's website" \
- -D DATE_FORMAT="%Y-%m-%dT%H:%M:%SZ" \
- -t "${TEMP}/atom.tmpl" \
- -o "${TEMP}/output.xml" \
- -l \
- "${TEMP}/post1.txt" "${TEMP}/post2.txt"
-
-diff -uN "${TEMP}/output.xml" "${TEMP}/expected-output.xml"
-
-echo -e "${TEMP}/post1.txt\n${TEMP}/post2.txt" | ${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D BASE_DOMAIN=http://bola.com/ \
- -D BASE_URL= \
- -D AUTHOR_NAME=Chunda \
- -D AUTHOR_EMAIL=chunda@bola.com \
- -D SITE_TITLE="Chunda's website" \
- -D DATE_FORMAT="%Y-%m-%dT%H:%M:%SZ" \
- -t "${TEMP}/atom.tmpl" \
- -o "${TEMP}/output2.xml" \
- -l \
- -i
-
-diff -uN "${TEMP}/output2.xml" "${TEMP}/expected-output.xml"
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D BASE_DOMAIN=http://bola.com/ \
- -D BASE_URL= \
- -D AUTHOR_NAME=Chunda \
- -D AUTHOR_EMAIL=chunda@bola.com \
- -D SITE_TITLE="Chunda's website" \
- -D DATE_FORMAT="%Y-%m-%dT%H:%M:%SZ" \
- -t "${TEMP}/atom.tmpl" \
- -l \
- "${TEMP}/post1.txt" "${TEMP}/post2.txt" > "${TEMP}/output3.xml"
-
-diff -uN "${TEMP}/output3.xml" "${TEMP}/expected-output.xml"
-
-echo -e "${TEMP}/post1.txt\n${TEMP}/post2.txt" | ${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D BASE_DOMAIN=http://bola.com/ \
- -D BASE_URL= \
- -D AUTHOR_NAME=Chunda \
- -D AUTHOR_EMAIL=chunda@bola.com \
- -D SITE_TITLE="Chunda's website" \
- -D DATE_FORMAT="%Y-%m-%dT%H:%M:%SZ" \
- -t "${TEMP}/atom.tmpl" \
- -l \
- -i > "${TEMP}/output4.xml"
-
-diff -uN "${TEMP}/output4.xml" "${TEMP}/expected-output.xml"
-
-cat > "${TEMP}/main.tmpl" <<EOF
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <title>{% ifdef FOO1 %}{{ FOO1 }} {% endif %}{% block entry %}{{ TITLE }}{% endblock %}{% block listing_once %}{{ SITE_TITLE }}{% endblock %}</title>
- </head>
- <body>
- <a href="{{ BASE_URL }}/"><div class="name">{{ SITE_TITLE }}</div></a>{% block listing_entry %}{{ CONTENT }}{% endblock %}{% block listing_entry %}{{ CONTENT }}{% endblock %}
- {% block listing_once %}
- <section class="main">
- <div class="container">
- <div class="content">
- <div class="page-heading">Blog</div>
- <ul>
- {% endblock %}
- {% block listing %}
- <li class="post-item">
- <div class="meta">{{ DATE_FORMATTED }}</div>
- <a href="{{ BASE_URL }}/post/{{ FILENAME }}/"><div>{{ TITLE }}</div></a>
- </li>
- {% endblock %}{% block listing_empty %}vazio{% endblock %}
- {% block listing_once %}
- </ul>
- </div>
- </div>
- </section>
- {% endblock %}
- {% block entry %}
- <section class="main{% ifdef IS_POST %} post non-narrow zero-top-spacing{% endif %}">
- <div class="container">
- <div class="content">
- {% ifdef IS_POST %}<div class="front-matter">{% endif %}
- <div class="title-container">
- <div class="page-heading">{{ TITLE }}</div>
- </div>
- {% ifdef IS_POST %}
- <div class="meta">
- <div class="date">{{ DATE_FORMATTED }}</div>
- </div>
- </div>
- {% endif %}
- <div class="markdown">
- {{ CONTENT }}
- {% ifdef IS_POST %}
- <br>
- <p><a href="{{ BASE_URL }}/">Back to posts</a></p>
- {% endif %}
- </div>
- </div>
- </div>
- </section>
- {% endblock %}
- </body>
-</html>
-EOF
-
-cat > "${TEMP}/expected-output.html" <<EOF
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <title>asd Chunda's website</title>
- </head>
- <body>
- <a href="/"><div class="name">Chunda's website</div></a>
-
- <section class="main">
- <div class="container">
- <div class="content">
- <div class="page-heading">Blog</div>
- <ul>
-
-
- <li class="post-item">
- <div class="meta">Jan 01, 2010, 11:11 AM GMT</div>
- <a href="/post/post1/"><div>foo</div></a>
- </li>
-
- <li class="post-item">
- <div class="meta">Jan 01, 2010, 10:22 PM GMT</div>
- <a href="/post/post2/"><div>bar</div></a>
- </li>
-
-
- </ul>
- </div>
- </div>
- </section>
-
-
- </body>
-</html>
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D BASE_DOMAIN=http://bola.com/ \
- -D BASE_URL= \
- -D SITE_TITLE="Chunda's website" \
- -D DATE_FORMAT="%b %d, %Y, %I:%M %p GMT" \
- -D FOO1="asd" \
- -t "${TEMP}/main.tmpl" \
- -o "${TEMP}/output.html" \
- -l \
- "${TEMP}/post1.txt" "${TEMP}/post2.txt"
-
-diff -uN "${TEMP}/output.html" "${TEMP}/expected-output.html"
-
-echo -e "${TEMP}/post1.txt\n${TEMP}/post2.txt" | ${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D BASE_DOMAIN=http://bola.com/ \
- -D BASE_URL= \
- -D SITE_TITLE="Chunda's website" \
- -D DATE_FORMAT="%b %d, %Y, %I:%M %p GMT" \
- -D FOO1="asd" \
- -t "${TEMP}/main.tmpl" \
- -o "${TEMP}/output2.html" \
- -l \
- -i
-
-diff -uN "${TEMP}/output2.html" "${TEMP}/expected-output.html"
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D BASE_DOMAIN=http://bola.com/ \
- -D BASE_URL= \
- -D SITE_TITLE="Chunda's website" \
- -D DATE_FORMAT="%b %d, %Y, %I:%M %p GMT" \
- -D FOO1="asd" \
- -t "${TEMP}/main.tmpl" \
- -l \
- "${TEMP}/post1.txt" "${TEMP}/post2.txt" > "${TEMP}/output3.html"
-
-diff -uN "${TEMP}/output3.html" "${TEMP}/expected-output.html"
-
-echo -e "${TEMP}/post1.txt\n${TEMP}/post2.txt" | ${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D BASE_DOMAIN=http://bola.com/ \
- -D BASE_URL= \
- -D SITE_TITLE="Chunda's website" \
- -D DATE_FORMAT="%b %d, %Y, %I:%M %p GMT" \
- -D FOO1="asd" \
- -t "${TEMP}/main.tmpl" \
- -l \
- -i > "${TEMP}/output4.html"
-
-diff -uN "${TEMP}/output4.html" "${TEMP}/expected-output.html"
-
-cat > "${TEMP}/expected-output2.html" <<EOF
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <title>foo</title>
- </head>
- <body>
- <a href="/"><div class="name">Chunda's website</div></a>
-
-
-
-
- <section class="main">
- <div class="container">
- <div class="content">
-
- <div class="title-container">
- <div class="page-heading">foo</div>
- </div>
-
- <div class="markdown">
- <p>foo?</p>
-
-
- </div>
- </div>
- </div>
- </section>
-
- </body>
-</html>
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D BASE_DOMAIN=http://bola.com/ \
- -D BASE_URL= \
- -D SITE_TITLE="Chunda's website" \
- -D DATE_FORMAT="%b %d, %Y, %I:%M %p GMT" \
- -t "${TEMP}/main.tmpl" \
- -o "${TEMP}/output5.html" \
- "${TEMP}/post1.txt"
-
-diff -uN "${TEMP}/output5.html" "${TEMP}/expected-output2.html"
-
-echo -e "${TEMP}/post1.txt" | ${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D BASE_DOMAIN=http://bola.com/ \
- -D BASE_URL= \
- -D SITE_TITLE="Chunda's website" \
- -D DATE_FORMAT="%b %d, %Y, %I:%M %p GMT" \
- -t "${TEMP}/main.tmpl" \
- -o "${TEMP}/output6.html" \
- -i
-
-diff -uN "${TEMP}/output6.html" "${TEMP}/expected-output2.html"
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D BASE_DOMAIN=http://bola.com/ \
- -D BASE_URL= \
- -D SITE_TITLE="Chunda's website" \
- -D DATE_FORMAT="%b %d, %Y, %I:%M %p GMT" \
- -t "${TEMP}/main.tmpl" \
- "${TEMP}/post1.txt" > "${TEMP}/output7.html"
-
-diff -uN "${TEMP}/output7.html" "${TEMP}/expected-output2.html"
-
-echo -e "${TEMP}/post1.txt" | ${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D BASE_DOMAIN=http://bola.com/ \
- -D BASE_URL= \
- -D SITE_TITLE="Chunda's website" \
- -D DATE_FORMAT="%b %d, %Y, %I:%M %p GMT" \
- -t "${TEMP}/main.tmpl" \
- -i > "${TEMP}/output8.html"
-
-diff -uN "${TEMP}/output8.html" "${TEMP}/expected-output2.html"
-
-cat > "${TEMP}/expected-output3.html" <<EOF
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <title>Chunda's website</title>
- </head>
- <body>
- <a href="/"><div class="name">Chunda's website</div></a><p>bar?</p>
-
-
- <section class="main">
- <div class="container">
- <div class="content">
- <div class="page-heading">Blog</div>
- <ul>
-
-
- <li class="post-item">
- <div class="meta">Jan 01, 2010, 11:11 AM GMT</div>
- <a href="/post/post1/"><div>foo</div></a>
- </li>
-
- <li class="post-item">
- <div class="meta">Jan 01, 2010, 10:22 PM GMT</div>
- <a href="/post/post2/"><div>bar</div></a>
- </li>
-
-
- </ul>
- </div>
- </div>
- </section>
-
-
- </body>
-</html>
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D BASE_DOMAIN=http://bola.com/ \
- -D BASE_URL= \
- -D SITE_TITLE="Chunda's website" \
- -D DATE_FORMAT="%b %d, %Y, %I:%M %p GMT" \
- -e "${TEMP}/post3.txt" \
- -t "${TEMP}/main.tmpl" \
- -o "${TEMP}/output9.html" \
- -l \
- "${TEMP}/post1.txt" "${TEMP}/post2.txt"
-
-diff -uN "${TEMP}/output9.html" "${TEMP}/expected-output3.html"
-
-echo -e "${TEMP}/post1.txt\n${TEMP}/post2.txt" | ${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D BASE_DOMAIN=http://bola.com/ \
- -D BASE_URL= \
- -D SITE_TITLE="Chunda's website" \
- -D DATE_FORMAT="%b %d, %Y, %I:%M %p GMT" \
- -e "${TEMP}/post3.txt" \
- -t "${TEMP}/main.tmpl" \
- -o "${TEMP}/output10.html" \
- -l \
- -i
-
-diff -uN "${TEMP}/output10.html" "${TEMP}/expected-output3.html"
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D BASE_DOMAIN=http://bola.com/ \
- -D BASE_URL= \
- -D SITE_TITLE="Chunda's website" \
- -D DATE_FORMAT="%b %d, %Y, %I:%M %p GMT" \
- -e "${TEMP}/post3.txt" \
- -t "${TEMP}/main.tmpl" \
- -l \
- "${TEMP}/post1.txt" "${TEMP}/post2.txt" > "${TEMP}/output11.html"
-
-diff -uN "${TEMP}/output11.html" "${TEMP}/expected-output3.html"
-
-echo -e "${TEMP}/post1.txt\n${TEMP}/post2.txt" | ${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D BASE_DOMAIN=http://bola.com/ \
- -D BASE_URL= \
- -D SITE_TITLE="Chunda's website" \
- -D DATE_FORMAT="%b %d, %Y, %I:%M %p GMT" \
- -e "${TEMP}/post3.txt" \
- -t "${TEMP}/main.tmpl" \
- -l \
- -i > "${TEMP}/output12.html"
-
-diff -uN "${TEMP}/output12.html" "${TEMP}/expected-output3.html"
-
-cat > "${TEMP}/expected-output4.html" <<EOF
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <title>Chunda's website</title>
- </head>
- <body>
- <a href="/"><div class="name">Chunda's website</div></a><p>foo?</p>
-
-
- <section class="main">
- <div class="container">
- <div class="content">
- <div class="page-heading">Blog</div>
- <ul>
-
-
- <li class="post-item">
- <div class="meta">Jan 01, 2010, 11:11 AM GMT</div>
- <a href="/post/post1/"><div>foo</div></a>
- </li>
-
- <li class="post-item">
- <div class="meta">Jan 01, 2010, 10:22 PM GMT</div>
- <a href="/post/post2/"><div>bar</div></a>
- </li>
-
-
- </ul>
- </div>
- </div>
- </section>
-
-
- </body>
-</html>
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D BASE_DOMAIN=http://bola.com/ \
- -D BASE_URL= \
- -D SITE_TITLE="Chunda's website" \
- -D DATE_FORMAT="%b %d, %Y, %I:%M %p GMT" \
- -e "" \
- -e "${TEMP}/post1.txt" \
- -e "${TEMP}/post3.txt" \
- -t "${TEMP}/main.tmpl" \
- -o "${TEMP}/output13.html" \
- -l \
- "${TEMP}/post1.txt" "${TEMP}/post2.txt"
-
-diff -uN "${TEMP}/output13.html" "${TEMP}/expected-output4.html"
-
-
-cat > "${TEMP}/expected-output5.html" <<EOF
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <title>Chunda's website</title>
- </head>
- <body>
- <a href="/"><div class="name">Chunda's website</div></a><p>foo?</p>
-<p>bar?</p>
-
-
- <section class="main">
- <div class="container">
- <div class="content">
- <div class="page-heading">Blog</div>
- <ul>
-
-
- <li class="post-item">
- <div class="meta">Jan 01, 2010, 11:11 AM GMT</div>
- <a href="/post/post1/"><div>foo</div></a>
- </li>
-
- <li class="post-item">
- <div class="meta">Jan 01, 2010, 10:22 PM GMT</div>
- <a href="/post/post2/"><div>bar</div></a>
- </li>
-
-
- </ul>
- </div>
- </div>
- </section>
-
-
- </body>
-</html>
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D BASE_DOMAIN=http://bola.com/ \
- -D BASE_URL= \
- -D SITE_TITLE="Chunda's website" \
- -D DATE_FORMAT="%b %d, %Y, %I:%M %p GMT" \
- -e "${TEMP}/post1.txt" \
- -e "${TEMP}/post3.txt" \
- -t "${TEMP}/main.tmpl" \
- -o "${TEMP}/output14.html" \
- -l \
- "${TEMP}/post1.txt" "${TEMP}/post2.txt"
-
-diff -uN "${TEMP}/output14.html" "${TEMP}/expected-output5.html"
-
-
-cat > "${TEMP}/expected-output6.html" <<EOF
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <title>Chunda's website</title>
- </head>
- <body>
- <a href="/"><div class="name">Chunda's website</div></a>
-
- <section class="main">
- <div class="container">
- <div class="content">
- <div class="page-heading">Blog</div>
- <ul>
-
- vazio
-
- </ul>
- </div>
- </div>
- </section>
-
-
- </body>
-</html>
-EOF
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D BASE_DOMAIN=http://bola.com/ \
- -D BASE_URL= \
- -D SITE_TITLE="Chunda's website" \
- -D DATE_FORMAT="%b %d, %Y, %I:%M %p GMT" \
- -t "${TEMP}/main.tmpl" \
- -o "${TEMP}/output15.html" \
- -l
-
-diff -uN "${TEMP}/output15.html" "${TEMP}/expected-output6.html"
-
-echo "{% block listig %}foo{% endblock %}\n" > "${TEMP}/error.tmpl"
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -t "${TEMP}/error.tmpl" \
- "${TEMP}/post1.txt" 2>&1 | tee "${TEMP}/output.txt" || true
-
-grep "blogc: error: template: Invalid block type" "${TEMP}/output.txt"
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D 123=a 2>&1 | tee "${TEMP}/output.txt" || true
-
-grep \
- "blogc: error: invalid value for -D (first character in configuration key must be uppercase): 123" \
- "${TEMP}/output.txt"
-
-${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
- -D A1-3=a 2>&1 | tee "${TEMP}/output.txt" || true
-
-grep \
- "blogc: error: invalid value for -D (configuration key must be uppercase with '_' and digits after first character): A1-3" \
- "${TEMP}/output.txt"
diff --git a/tests/blogc/check_filelist_parser.c b/tests/blogc/check_filelist_parser.c
deleted file mode 100644
index da1698e..0000000
--- a/tests/blogc/check_filelist_parser.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#include <string.h>
-#include <stdlib.h>
-#include "../../src/common/utils.h"
-#include "../../src/blogc/filelist-parser.h"
-
-
-static void
-test_filelist_parse_empty(void **state)
-{
- bc_slist_t *l = blogc_filelist_parse("", 0);
- assert_null(l);
-}
-
-
-static void
-test_filelist_parse(void **state)
-{
- const char *a =
- "content/post/post1.txt";
- bc_slist_t *l = blogc_filelist_parse(a, strlen(a));
- assert_non_null(l);
- assert_string_equal(l->data, "content/post/post1.txt");
- assert_null(l->next);
- bc_slist_free_full(l, free);
- a =
- "content/post/post1.txt\n";
- l = blogc_filelist_parse(a, strlen(a));
- assert_non_null(l);
- assert_string_equal(l->data, "content/post/post1.txt");
- assert_null(l->next);
- bc_slist_free_full(l, free);
- a =
- "content/post/post1.txt\n"
- "content/post/post2.txt\n";
- l = blogc_filelist_parse(a, strlen(a));
- assert_non_null(l);
- assert_string_equal(l->data, "content/post/post1.txt");
- assert_string_equal(l->next->data, "content/post/post2.txt");
- assert_null(l->next->next);
- bc_slist_free_full(l, free);
- a =
- "content/post/post1.txt\n"
- "content/post/post2.txt\n"
- "content/post/post3.txt";
- l = blogc_filelist_parse(a, strlen(a));
- assert_non_null(l);
- assert_string_equal(l->data, "content/post/post1.txt");
- assert_string_equal(l->next->data, "content/post/post2.txt");
- assert_string_equal(l->next->next->data, "content/post/post3.txt");
- assert_null(l->next->next->next);
- bc_slist_free_full(l, free);
- a =
- " content/post/post1.txt\n"
- "content/post/post2.txt\t\n"
- "\tcontent/post/post3.txt";
- l = blogc_filelist_parse(a, strlen(a));
- assert_non_null(l);
- assert_string_equal(l->data, "content/post/post1.txt");
- assert_string_equal(l->next->data, "content/post/post2.txt");
- assert_string_equal(l->next->next->data, "content/post/post3.txt");
- assert_null(l->next->next->next);
- bc_slist_free_full(l, free);
-}
-
-
-static void
-test_filelist_parse_crlf(void **state)
-{
- const char *a =
- "content/post/post1.txt\r\n";
- bc_slist_t *l = blogc_filelist_parse(a, strlen(a));
- assert_non_null(l);
- assert_string_equal(l->data, "content/post/post1.txt");
- assert_null(l->next);
- bc_slist_free_full(l, free);
- a =
- "content/post/post1.txt\r\n"
- "content/post/post2.txt\r\n";
- l = blogc_filelist_parse(a, strlen(a));
- assert_non_null(l);
- assert_string_equal(l->data, "content/post/post1.txt");
- assert_string_equal(l->next->data, "content/post/post2.txt");
- assert_null(l->next->next);
- bc_slist_free_full(l, free);
- a =
- "content/post/post1.txt\r\n"
- "content/post/post2.txt\r\n"
- "content/post/post3.txt";
- l = blogc_filelist_parse(a, strlen(a));
- assert_non_null(l);
- assert_string_equal(l->data, "content/post/post1.txt");
- assert_string_equal(l->next->data, "content/post/post2.txt");
- assert_string_equal(l->next->next->data, "content/post/post3.txt");
- assert_null(l->next->next->next);
- bc_slist_free_full(l, free);
- a =
- " content/post/post1.txt\r\n"
- "content/post/post2.txt\t\r\n"
- "\tcontent/post/post3.txt";
- l = blogc_filelist_parse(a, strlen(a));
- assert_non_null(l);
- assert_string_equal(l->data, "content/post/post1.txt");
- assert_string_equal(l->next->data, "content/post/post2.txt");
- assert_string_equal(l->next->next->data, "content/post/post3.txt");
- assert_null(l->next->next->next);
- bc_slist_free_full(l, free);
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_filelist_parse_empty),
- cmocka_unit_test(test_filelist_parse),
- cmocka_unit_test(test_filelist_parse_crlf),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/blogc/check_funcvars.c b/tests/blogc/check_funcvars.c
deleted file mode 100644
index 23f1723..0000000
--- a/tests/blogc/check_funcvars.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include "../../src/common/error.h"
-#include "../../src/common/utils.h"
-#include "../../src/blogc/funcvars.h"
-
-
-char*
-__wrap_bc_file_get_contents(const char *path, bool utf8, size_t *len, bc_error_t **err)
-{
- assert_string_equal(path, "/proc/1/cgroup");
- assert_false(utf8);
- char *rv = mock_type(char*);
- *len = strlen(rv);
- return rv;
-}
-
-
-static void
-test_funcvars_eval(void **state)
-{
- bc_trie_t *t = bc_trie_new(free);
- blogc_funcvars_eval(t, NULL);
- blogc_funcvars_eval(t, "");
- blogc_funcvars_eval(t, "BOLA");
- assert_int_equal(bc_trie_size(t), 0);
-
- bc_trie_insert(t, "BOLA", bc_strdup("GUDA"));
- blogc_funcvars_eval(t, "BOLA");
- assert_int_equal(bc_trie_size(t), 1);
-
- bc_trie_free(t);
-}
-
-
-static void
-test_funcvars_eval_mocked(void **state)
-{
- bc_trie_t *t = bc_trie_new(free);
-
- // this is the only function that isn't hidden behind conditional macros
- // as of when this test was written. the other functions should be tested
- // separately
- will_return(__wrap_bc_file_get_contents, bc_strdup("asd/docker/asd"));
- blogc_funcvars_eval(t, "BLOGC_SYSINFO_INSIDE_DOCKER");
- assert_string_equal(bc_trie_lookup(t, "BLOGC_SYSINFO_INSIDE_DOCKER"), "1");
- assert_int_equal(bc_trie_size(t), 1);
-
- // this specific function call is cached, so calling it again should not
- // call bc_file_get_contents_again
- blogc_funcvars_eval(t, "BLOGC_SYSINFO_INSIDE_DOCKER");
- assert_string_equal(bc_trie_lookup(t, "BLOGC_SYSINFO_INSIDE_DOCKER"), "1");
- assert_int_equal(bc_trie_size(t), 1);
-
- bc_trie_free(t);
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_funcvars_eval),
- cmocka_unit_test(test_funcvars_eval_mocked),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/blogc/check_loader.c b/tests/blogc/check_loader.c
deleted file mode 100644
index caeb8d8..0000000
--- a/tests/blogc/check_loader.c
+++ /dev/null
@@ -1,1050 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include "../../src/common/error.h"
-#include "../../src/common/utils.h"
-#include "../../src/blogc/template-parser.h"
-#include "../../src/blogc/loader.h"
-
-
-static void
-test_get_filename(void **state)
-{
- char *f = blogc_get_filename("/home/foo/asd/bola.txt");
- assert_string_equal(f, "bola");
- free(f);
- f = blogc_get_filename("/home/foo/asd/bola.guda.txt");
- assert_string_equal(f, "bola.guda");
- free(f);
- f = blogc_get_filename("bola.txt");
- assert_string_equal(f, "bola");
- free(f);
- f = blogc_get_filename("bola.guda.txt");
- assert_string_equal(f, "bola.guda");
- free(f);
- f = blogc_get_filename("/home/foo/asd/bola");
- assert_string_equal(f, "bola");
- free(f);
- f = blogc_get_filename("bola");
- assert_string_equal(f, "bola");
- free(f);
- f = blogc_get_filename("");
- assert_null(f);
- free(f);
- f = blogc_get_filename(NULL);
- assert_null(f);
- free(f);
-}
-
-
-char*
-__wrap_bc_file_get_contents(const char *path, bool utf8, size_t *len, bc_error_t **err)
-{
- assert_true(utf8);
- assert_null(*err);
- const char *_path = mock_type(const char*);
- if (_path != NULL)
- assert_string_equal(path, _path);
- char *rv = mock_type(char*);
- *len = 0;
- if (rv != NULL)
- *len = strlen(rv);
- return rv;
-}
-
-
-static void
-test_template_parse_from_file(void **state)
-{
- bc_error_t *err = NULL;
- will_return(__wrap_bc_file_get_contents, "bola");
- will_return(__wrap_bc_file_get_contents, bc_strdup("{{ BOLA }}\n"));
- bc_slist_t *l = blogc_template_parse_from_file("bola", &err);
- assert_null(err);
- assert_non_null(l);
- assert_int_equal(bc_slist_length(l), 2);
- blogc_template_free_ast(l);
-}
-
-
-static void
-test_template_parse_from_file_null(void **state)
-{
- bc_error_t *err = NULL;
- will_return(__wrap_bc_file_get_contents, "bola");
- will_return(__wrap_bc_file_get_contents, NULL);
- bc_slist_t *l = blogc_template_parse_from_file("bola", &err);
- assert_null(err);
- assert_null(l);
-}
-
-
-static void
-test_source_parse_from_file(void **state)
-{
- bc_error_t *err = NULL;
- will_return(__wrap_bc_file_get_contents, "bola.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 123\n"
- "--------\n"
- "bola"));
- bc_trie_t *c = bc_trie_new(free);
- bc_trie_t *t = blogc_source_parse_from_file(c, "bola.txt", &err);
- assert_null(err);
- assert_non_null(t);
- assert_int_equal(bc_trie_size(t), 6);
- assert_string_equal(bc_trie_lookup(t, "ASD"), "123");
- assert_string_equal(bc_trie_lookup(t, "FILENAME"), "bola");
- assert_string_equal(bc_trie_lookup(t, "EXCERPT"), "<p>bola</p>\n");
- assert_string_equal(bc_trie_lookup(t, "CONTENT"), "<p>bola</p>\n");
- assert_string_equal(bc_trie_lookup(t, "RAW_CONTENT"), "bola");
- assert_string_equal(bc_trie_lookup(t, "DESCRIPTION"), "bola");
- bc_trie_free(c);
- bc_trie_free(t);
-}
-
-
-static void
-test_source_parse_from_file_maxdepth(void **state)
-{
- bc_error_t *err = NULL;
- will_return(__wrap_bc_file_get_contents, "bola.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 123\n"
- "TOCTREE_MAXDEPTH: 1\n"
- "--------\n"
- "### bola\n"
- "#### guda"));
- bc_trie_t *c = bc_trie_new(free);
- bc_trie_insert(c, "TOCTREE_MAXDEPTH", bc_strdup("-1"));
- bc_trie_t *t = blogc_source_parse_from_file(c, "bola.txt", &err);
- assert_null(err);
- assert_non_null(t);
- assert_int_equal(bc_trie_size(t), 8);
- assert_string_equal(bc_trie_lookup(t, "ASD"), "123");
- assert_string_equal(bc_trie_lookup(t, "TOCTREE_MAXDEPTH"), "1");
- assert_string_equal(bc_trie_lookup(t, "FILENAME"), "bola");
- assert_string_equal(bc_trie_lookup(t, "EXCERPT"),
- "<h3 id=\"bola\">bola</h3>\n"
- "<h4 id=\"guda\">guda</h4>\n");
- assert_string_equal(bc_trie_lookup(t, "CONTENT"),
- "<h3 id=\"bola\">bola</h3>\n"
- "<h4 id=\"guda\">guda</h4>\n");
- assert_string_equal(bc_trie_lookup(t, "RAW_CONTENT"),
- "### bola\n"
- "#### guda");
- assert_string_equal(bc_trie_lookup(t, "FIRST_HEADER"), "bola");
- assert_string_equal(bc_trie_lookup(t, "TOCTREE"),
- "<ul>\n"
- " <li><a href=\"#bola\">bola</a></li>\n"
- "</ul>\n");
- bc_trie_free(c);
- bc_trie_free(t);
-}
-
-
-static void
-test_source_parse_from_file_maxdepth2(void **state)
-{
- bc_error_t *err = NULL;
- will_return(__wrap_bc_file_get_contents, "bola.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 123\n"
- "--------\n"
- "### bola\n"
- "#### guda"));
- bc_trie_t *c = bc_trie_new(free);
- bc_trie_insert(c, "TOCTREE_MAXDEPTH", bc_strdup("1"));
- bc_trie_t *t = blogc_source_parse_from_file(c, "bola.txt", &err);
- assert_null(err);
- assert_non_null(t);
- assert_int_equal(bc_trie_size(t), 7);
- assert_string_equal(bc_trie_lookup(t, "ASD"), "123");
- assert_string_equal(bc_trie_lookup(t, "FILENAME"), "bola");
- assert_string_equal(bc_trie_lookup(t, "EXCERPT"),
- "<h3 id=\"bola\">bola</h3>\n"
- "<h4 id=\"guda\">guda</h4>\n");
- assert_string_equal(bc_trie_lookup(t, "CONTENT"),
- "<h3 id=\"bola\">bola</h3>\n"
- "<h4 id=\"guda\">guda</h4>\n");
- assert_string_equal(bc_trie_lookup(t, "RAW_CONTENT"),
- "### bola\n"
- "#### guda");
- assert_string_equal(bc_trie_lookup(t, "FIRST_HEADER"), "bola");
- assert_string_equal(bc_trie_lookup(t, "TOCTREE"),
- "<ul>\n"
- " <li><a href=\"#bola\">bola</a></li>\n"
- "</ul>\n");
- bc_trie_free(c);
- bc_trie_free(t);
-}
-
-
-static void
-test_source_parse_from_file_null(void **state)
-{
- bc_error_t *err = NULL;
- will_return(__wrap_bc_file_get_contents, "bola.txt");
- will_return(__wrap_bc_file_get_contents, NULL);
- bc_trie_t *c = bc_trie_new(free);
- bc_trie_t *t = blogc_source_parse_from_file(c, "bola.txt", &err);
- assert_null(err);
- assert_null(t);
- bc_trie_free(c);
-}
-
-
-static void
-test_source_parse_from_files(void **state)
-{
- will_return(__wrap_bc_file_get_contents, "bola1.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 123\n"
- "DATE: 2001-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola2.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 456\n"
- "DATE: 2002-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola3.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 789\n"
- "DATE: 2003-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- bc_error_t *err = NULL;
- bc_slist_t *s = NULL;
- s = bc_slist_append(s, bc_strdup("bola1.txt"));
- s = bc_slist_append(s, bc_strdup("bola2.txt"));
- s = bc_slist_append(s, bc_strdup("bola3.txt"));
- bc_trie_t *c = bc_trie_new(free);
- bc_slist_t *t = blogc_source_parse_from_files(c, s, &err);
- assert_null(err);
- assert_non_null(t);
- assert_int_equal(bc_slist_length(t), 3); // it is enough, no need to look at the items
- assert_int_equal(bc_trie_size(c), 4);
- assert_string_equal(bc_trie_lookup(c, "FILENAME_FIRST"), "bola1");
- assert_string_equal(bc_trie_lookup(c, "FILENAME_LAST"), "bola3");
- assert_string_equal(bc_trie_lookup(c, "DATE_FIRST"), "2001-02-03 04:05:06");
- assert_string_equal(bc_trie_lookup(c, "DATE_LAST"), "2003-02-03 04:05:06");
- bc_trie_free(c);
- bc_slist_free_full(s, free);
- bc_slist_free_full(t, (bc_free_func_t) bc_trie_free);
-}
-
-
-static void
-test_source_parse_from_files_filter_sort(void **state)
-{
- will_return(__wrap_bc_file_get_contents, "bola1.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 123\n"
- "DATE: 2001-02-02 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola2.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 456\n"
- "DATE: 2001-02-01 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola3.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 789\n"
- "DATE: 2011-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- bc_error_t *err = NULL;
- bc_slist_t *s = NULL;
- s = bc_slist_append(s, bc_strdup("bola1.txt"));
- s = bc_slist_append(s, bc_strdup("bola2.txt"));
- s = bc_slist_append(s, bc_strdup("bola3.txt"));
- bc_trie_t *c = bc_trie_new(free);
- bc_trie_insert(c, "FILTER_SORT", bc_strdup("1"));
- bc_slist_t *t = blogc_source_parse_from_files(c, s, &err);
- assert_null(err);
- assert_non_null(t);
- assert_int_equal(bc_slist_length(t), 3); // it is enough, no need to look at the items
- assert_int_equal(bc_trie_size(c), 5);
- assert_string_equal(bc_trie_lookup(c, "FILTER_SORT"), "1");
- assert_string_equal(bc_trie_lookup(c, "FILENAME_FIRST"), "bola3");
- assert_string_equal(bc_trie_lookup(c, "FILENAME_LAST"), "bola2");
- assert_string_equal(bc_trie_lookup(c, "DATE_FIRST"), "2011-02-03 04:05:06");
- assert_string_equal(bc_trie_lookup(c, "DATE_LAST"), "2001-02-01 04:05:06");
- bc_trie_free(c);
- bc_slist_free_full(s, free);
- bc_slist_free_full(t, (bc_free_func_t) bc_trie_free);
-}
-
-
-static void
-test_source_parse_from_files_filter_reverse(void **state)
-{
- will_return(__wrap_bc_file_get_contents, "bola1.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 123\n"
- "DATE: 2001-02-03 04:05:06\n"
- "TAGS: chunda\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola2.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 456\n"
- "DATE: 2002-02-03 04:05:06\n"
- "TAGS: bola, chunda\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola3.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 789\n"
- "DATE: 2003-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- bc_error_t *err = NULL;
- bc_slist_t *s = NULL;
- s = bc_slist_append(s, bc_strdup("bola1.txt"));
- s = bc_slist_append(s, bc_strdup("bola2.txt"));
- s = bc_slist_append(s, bc_strdup("bola3.txt"));
- bc_trie_t *c = bc_trie_new(free);
- bc_trie_insert(c, "FILTER_REVERSE", bc_strdup("1"));
- bc_slist_t *t = blogc_source_parse_from_files(c, s, &err);
- assert_null(err);
- assert_non_null(t);
- assert_int_equal(bc_slist_length(t), 3); // it is enough, no need to look at the items
- assert_int_equal(bc_trie_size(c), 5);
- assert_string_equal(bc_trie_lookup(c, "FILENAME_FIRST"), "bola3");
- assert_string_equal(bc_trie_lookup(c, "FILENAME_LAST"), "bola1");
- assert_string_equal(bc_trie_lookup(c, "DATE_FIRST"), "2003-02-03 04:05:06");
- assert_string_equal(bc_trie_lookup(c, "DATE_LAST"), "2001-02-03 04:05:06");
- assert_string_equal(bc_trie_lookup(c, "FILTER_REVERSE"), "1");
- bc_trie_free(c);
- bc_slist_free_full(s, free);
- bc_slist_free_full(t, (bc_free_func_t) bc_trie_free);
-}
-
-
-static void
-test_source_parse_from_files_filter_sort_reverse(void **state)
-{
- will_return(__wrap_bc_file_get_contents, "bola1.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 123\n"
- "DATE: 2001-02-02 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola2.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 456\n"
- "DATE: 2001-02-01 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola3.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 789\n"
- "DATE: 2011-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- bc_error_t *err = NULL;
- bc_slist_t *s = NULL;
- s = bc_slist_append(s, bc_strdup("bola1.txt"));
- s = bc_slist_append(s, bc_strdup("bola2.txt"));
- s = bc_slist_append(s, bc_strdup("bola3.txt"));
- bc_trie_t *c = bc_trie_new(free);
- bc_trie_insert(c, "FILTER_SORT", bc_strdup("1"));
- bc_trie_insert(c, "FILTER_REVERSE", bc_strdup("1"));
- bc_slist_t *t = blogc_source_parse_from_files(c, s, &err);
- assert_null(err);
- assert_non_null(t);
- assert_int_equal(bc_slist_length(t), 3); // it is enough, no need to look at the items
- assert_int_equal(bc_trie_size(c), 6);
- assert_string_equal(bc_trie_lookup(c, "FILTER_SORT"), "1");
- assert_string_equal(bc_trie_lookup(c, "FILTER_REVERSE"), "1");
- assert_string_equal(bc_trie_lookup(c, "FILENAME_FIRST"), "bola2");
- assert_string_equal(bc_trie_lookup(c, "FILENAME_LAST"), "bola3");
- assert_string_equal(bc_trie_lookup(c, "DATE_FIRST"), "2001-02-01 04:05:06");
- assert_string_equal(bc_trie_lookup(c, "DATE_LAST"), "2011-02-03 04:05:06");
- bc_trie_free(c);
- bc_slist_free_full(s, free);
- bc_slist_free_full(t, (bc_free_func_t) bc_trie_free);
-}
-
-
-static void
-test_source_parse_from_files_filter_by_tag(void **state)
-{
- will_return(__wrap_bc_file_get_contents, "bola1.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 123\n"
- "DATE: 2001-02-03 04:05:06\n"
- "TAGS: chunda\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola2.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 456\n"
- "DATE: 2002-02-03 04:05:06\n"
- "TAGS: bola, chunda\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola3.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 789\n"
- "DATE: 2003-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- bc_error_t *err = NULL;
- bc_slist_t *s = NULL;
- s = bc_slist_append(s, bc_strdup("bola1.txt"));
- s = bc_slist_append(s, bc_strdup("bola2.txt"));
- s = bc_slist_append(s, bc_strdup("bola3.txt"));
- bc_trie_t *c = bc_trie_new(free);
- bc_trie_insert(c, "FILTER_TAG", bc_strdup("chunda"));
- bc_slist_t *t = blogc_source_parse_from_files(c, s, &err);
- assert_null(err);
- assert_non_null(t);
- assert_int_equal(bc_slist_length(t), 2); // it is enough, no need to look at the items
- assert_int_equal(bc_trie_size(c), 5);
- assert_string_equal(bc_trie_lookup(c, "FILENAME_FIRST"), "bola1");
- assert_string_equal(bc_trie_lookup(c, "FILENAME_LAST"), "bola2");
- assert_string_equal(bc_trie_lookup(c, "DATE_FIRST"), "2001-02-03 04:05:06");
- assert_string_equal(bc_trie_lookup(c, "DATE_LAST"), "2002-02-03 04:05:06");
- assert_string_equal(bc_trie_lookup(c, "FILTER_TAG"), "chunda");
- bc_trie_free(c);
- bc_slist_free_full(s, free);
- bc_slist_free_full(t, (bc_free_func_t) bc_trie_free);
-}
-
-
-static void
-test_source_parse_from_files_filter_by_page(void **state)
-{
- will_return(__wrap_bc_file_get_contents, "bola1.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 123\n"
- "DATE: 2001-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola2.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 456\n"
- "DATE: 2002-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola3.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 789\n"
- "DATE: 2003-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola4.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7891\n"
- "DATE: 2004-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola5.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7892\n"
- "DATE: 2005-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola6.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7893\n"
- "DATE: 2006-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola7.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7894\n"
- "DATE: 2007-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- bc_error_t *err = NULL;
- bc_slist_t *s = NULL;
- s = bc_slist_append(s, bc_strdup("bola1.txt"));
- s = bc_slist_append(s, bc_strdup("bola2.txt"));
- s = bc_slist_append(s, bc_strdup("bola3.txt"));
- s = bc_slist_append(s, bc_strdup("bola4.txt"));
- s = bc_slist_append(s, bc_strdup("bola5.txt"));
- s = bc_slist_append(s, bc_strdup("bola6.txt"));
- s = bc_slist_append(s, bc_strdup("bola7.txt"));
- bc_trie_t *c = bc_trie_new(free);
- bc_trie_insert(c, "FILTER_PAGE", bc_strdup("1"));
- bc_trie_insert(c, "FILTER_PER_PAGE", bc_strdup("2"));
- bc_slist_t *t = blogc_source_parse_from_files(c, s, &err);
- assert_null(err);
- assert_non_null(t);
- assert_int_equal(bc_slist_length(t), 2); // it is enough, no need to look at the items
- assert_int_equal(bc_trie_size(c), 10);
- assert_string_equal(bc_trie_lookup(c, "FILENAME_FIRST"), "bola1");
- assert_string_equal(bc_trie_lookup(c, "FILENAME_LAST"), "bola2");
- assert_string_equal(bc_trie_lookup(c, "DATE_FIRST"), "2001-02-03 04:05:06");
- assert_string_equal(bc_trie_lookup(c, "DATE_LAST"), "2002-02-03 04:05:06");
- assert_string_equal(bc_trie_lookup(c, "FILTER_PAGE"), "1");
- assert_string_equal(bc_trie_lookup(c, "FILTER_PER_PAGE"), "2");
- assert_string_equal(bc_trie_lookup(c, "CURRENT_PAGE"), "1");
- assert_string_equal(bc_trie_lookup(c, "NEXT_PAGE"), "2");
- assert_string_equal(bc_trie_lookup(c, "FIRST_PAGE"), "1");
- assert_string_equal(bc_trie_lookup(c, "LAST_PAGE"), "4");
- bc_trie_free(c);
- bc_slist_free_full(s, free);
- bc_slist_free_full(t, (bc_free_func_t) bc_trie_free);
-}
-
-
-static void
-test_source_parse_from_files_filter_by_page2(void **state)
-{
- will_return(__wrap_bc_file_get_contents, "bola1.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 123\n"
- "DATE: 2001-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola2.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 456\n"
- "DATE: 2002-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola3.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 789\n"
- "DATE: 2003-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola4.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7891\n"
- "DATE: 2004-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola5.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7892\n"
- "DATE: 2005-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola6.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7893\n"
- "DATE: 2006-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola7.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7894\n"
- "DATE: 2007-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- bc_error_t *err = NULL;
- bc_slist_t *s = NULL;
- s = bc_slist_append(s, bc_strdup("bola1.txt"));
- s = bc_slist_append(s, bc_strdup("bola2.txt"));
- s = bc_slist_append(s, bc_strdup("bola3.txt"));
- s = bc_slist_append(s, bc_strdup("bola4.txt"));
- s = bc_slist_append(s, bc_strdup("bola5.txt"));
- s = bc_slist_append(s, bc_strdup("bola6.txt"));
- s = bc_slist_append(s, bc_strdup("bola7.txt"));
- bc_trie_t *c = bc_trie_new(free);
- bc_trie_insert(c, "FILTER_PAGE", bc_strdup("3"));
- bc_trie_insert(c, "FILTER_PER_PAGE", bc_strdup("2"));
- bc_slist_t *t = blogc_source_parse_from_files(c, s, &err);
- assert_null(err);
- assert_non_null(t);
- assert_int_equal(bc_slist_length(t), 2); // it is enough, no need to look at the items
- assert_int_equal(bc_trie_size(c), 11);
- assert_string_equal(bc_trie_lookup(c, "FILENAME_FIRST"), "bola5");
- assert_string_equal(bc_trie_lookup(c, "FILENAME_LAST"), "bola6");
- assert_string_equal(bc_trie_lookup(c, "DATE_FIRST"), "2005-02-03 04:05:06");
- assert_string_equal(bc_trie_lookup(c, "DATE_LAST"), "2006-02-03 04:05:06");
- assert_string_equal(bc_trie_lookup(c, "FILTER_PAGE"), "3");
- assert_string_equal(bc_trie_lookup(c, "FILTER_PER_PAGE"), "2");
- assert_string_equal(bc_trie_lookup(c, "CURRENT_PAGE"), "3");
- assert_string_equal(bc_trie_lookup(c, "PREVIOUS_PAGE"), "2");
- assert_string_equal(bc_trie_lookup(c, "NEXT_PAGE"), "4");
- assert_string_equal(bc_trie_lookup(c, "FIRST_PAGE"), "1");
- assert_string_equal(bc_trie_lookup(c, "LAST_PAGE"), "4");
- bc_trie_free(c);
- bc_slist_free_full(s, free);
- bc_slist_free_full(t, (bc_free_func_t) bc_trie_free);
-}
-
-
-static void
-test_source_parse_from_files_filter_by_page3(void **state)
-{
- will_return(__wrap_bc_file_get_contents, "bola1.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 123\n"
- "DATE: 2001-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola2.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 456\n"
- "DATE: 2002-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola3.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 789\n"
- "DATE: 2003-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola4.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7891\n"
- "DATE: 2004-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola5.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7892\n"
- "DATE: 2005-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola6.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7893\n"
- "DATE: 2006-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola7.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7894\n"
- "DATE: 2007-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- bc_error_t *err = NULL;
- bc_slist_t *s = NULL;
- s = bc_slist_append(s, bc_strdup("bola1.txt"));
- s = bc_slist_append(s, bc_strdup("bola2.txt"));
- s = bc_slist_append(s, bc_strdup("bola3.txt"));
- s = bc_slist_append(s, bc_strdup("bola4.txt"));
- s = bc_slist_append(s, bc_strdup("bola5.txt"));
- s = bc_slist_append(s, bc_strdup("bola6.txt"));
- s = bc_slist_append(s, bc_strdup("bola7.txt"));
- bc_trie_t *c = bc_trie_new(free);
- bc_trie_insert(c, "FILTER_PAGE", bc_strdup("1"));
- bc_trie_insert(c, "FILTER_PER_PAGE", bc_strdup("2"));
- bc_slist_t *t = blogc_source_parse_from_files(c, s, &err);
- assert_null(err);
- assert_non_null(t);
- assert_int_equal(bc_slist_length(t), 2); // it is enough, no need to look at the items
- assert_int_equal(bc_trie_size(c), 10);
- assert_string_equal(bc_trie_lookup(c, "FILENAME_FIRST"), "bola1");
- assert_string_equal(bc_trie_lookup(c, "FILENAME_LAST"), "bola2");
- assert_string_equal(bc_trie_lookup(c, "DATE_FIRST"), "2001-02-03 04:05:06");
- assert_string_equal(bc_trie_lookup(c, "DATE_LAST"), "2002-02-03 04:05:06");
- assert_string_equal(bc_trie_lookup(c, "FILTER_PAGE"), "1");
- assert_string_equal(bc_trie_lookup(c, "FILTER_PER_PAGE"), "2");
- assert_string_equal(bc_trie_lookup(c, "CURRENT_PAGE"), "1");
- assert_string_equal(bc_trie_lookup(c, "NEXT_PAGE"), "2");
- assert_string_equal(bc_trie_lookup(c, "FIRST_PAGE"), "1");
- assert_string_equal(bc_trie_lookup(c, "LAST_PAGE"), "4");
- bc_trie_free(c);
- bc_slist_free_full(s, free);
- bc_slist_free_full(t, (bc_free_func_t) bc_trie_free);
-}
-
-
-static void
-test_source_parse_from_files_filter_sort_and_by_page_and_tag(void **state)
-{
- will_return(__wrap_bc_file_get_contents, "bola1.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 123\n"
- "DATE: 2001-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola2.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 456\n"
- "DATE: 2002-02-03 04:05:06\n"
- "TAGS: chunda\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola3.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 789\n"
- "DATE: 2003-02-03 04:05:06\n"
- "TAGS: chunda bola\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola4.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7891\n"
- "DATE: 2004-02-03 04:05:06\n"
- "TAGS: bola\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola5.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7892\n"
- "DATE: 2005-02-03 04:05:06\n"
- "TAGS: chunda\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola6.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7893\n"
- "DATE: 2006-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola7.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7894\n"
- "DATE: 2007-02-03 04:05:06\n"
- "TAGS: yay chunda\n"
- "--------\n"
- "bola"));
- bc_error_t *err = NULL;
- bc_slist_t *s = NULL;
- s = bc_slist_append(s, bc_strdup("bola1.txt"));
- s = bc_slist_append(s, bc_strdup("bola2.txt"));
- s = bc_slist_append(s, bc_strdup("bola3.txt"));
- s = bc_slist_append(s, bc_strdup("bola4.txt"));
- s = bc_slist_append(s, bc_strdup("bola5.txt"));
- s = bc_slist_append(s, bc_strdup("bola6.txt"));
- s = bc_slist_append(s, bc_strdup("bola7.txt"));
- bc_trie_t *c = bc_trie_new(free);
- bc_trie_insert(c, "FILTER_SORT", bc_strdup("1"));
- bc_trie_insert(c, "FILTER_TAG", bc_strdup("chunda"));
- bc_trie_insert(c, "FILTER_PAGE", bc_strdup("2"));
- bc_trie_insert(c, "FILTER_PER_PAGE", bc_strdup("2"));
- bc_slist_t *t = blogc_source_parse_from_files(c, s, &err);
- assert_null(err);
- assert_non_null(t);
- assert_int_equal(bc_slist_length(t), 2); // it is enough, no need to look at the items
- assert_int_equal(bc_trie_size(c), 12);
- assert_string_equal(bc_trie_lookup(c, "FILENAME_FIRST"), "bola3");
- assert_string_equal(bc_trie_lookup(c, "FILENAME_LAST"), "bola2");
- assert_string_equal(bc_trie_lookup(c, "DATE_FIRST"), "2003-02-03 04:05:06");
- assert_string_equal(bc_trie_lookup(c, "DATE_LAST"), "2002-02-03 04:05:06");
- assert_string_equal(bc_trie_lookup(c, "FILTER_SORT"), "1");
- assert_string_equal(bc_trie_lookup(c, "FILTER_TAG"), "chunda");
- assert_string_equal(bc_trie_lookup(c, "FILTER_PAGE"), "2");
- assert_string_equal(bc_trie_lookup(c, "FILTER_PER_PAGE"), "2");
- assert_string_equal(bc_trie_lookup(c, "CURRENT_PAGE"), "2");
- assert_string_equal(bc_trie_lookup(c, "PREVIOUS_PAGE"), "1");
- assert_string_equal(bc_trie_lookup(c, "FIRST_PAGE"), "1");
- assert_string_equal(bc_trie_lookup(c, "LAST_PAGE"), "2");
- bc_trie_free(c);
- bc_slist_free_full(s, free);
- bc_slist_free_full(t, (bc_free_func_t) bc_trie_free);
-}
-
-
-static void
-test_source_parse_from_files_filter_by_page_invalid(void **state)
-{
- will_return(__wrap_bc_file_get_contents, "bola1.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 123\n"
- "DATE: 2001-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola2.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 456\n"
- "DATE: 2002-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola3.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 789\n"
- "DATE: 2003-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola4.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7891\n"
- "DATE: 2004-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola5.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7892\n"
- "DATE: 2005-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola6.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7893\n"
- "DATE: 2006-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola7.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7894\n"
- "DATE: 2007-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- bc_error_t *err = NULL;
- bc_slist_t *s = NULL;
- s = bc_slist_append(s, bc_strdup("bola1.txt"));
- s = bc_slist_append(s, bc_strdup("bola2.txt"));
- s = bc_slist_append(s, bc_strdup("bola3.txt"));
- s = bc_slist_append(s, bc_strdup("bola4.txt"));
- s = bc_slist_append(s, bc_strdup("bola5.txt"));
- s = bc_slist_append(s, bc_strdup("bola6.txt"));
- s = bc_slist_append(s, bc_strdup("bola7.txt"));
- bc_trie_t *c = bc_trie_new(free);
- bc_trie_insert(c, "FILTER_PAGE", bc_strdup("-1"));
- bc_trie_insert(c, "FILTER_PER_PAGE", bc_strdup("2"));
- bc_slist_t *t = blogc_source_parse_from_files(c, s, &err);
- assert_null(err);
- assert_non_null(t);
- assert_int_equal(bc_slist_length(t), 2); // it is enough, no need to look at the items
- assert_int_equal(bc_trie_size(c), 10);
- assert_string_equal(bc_trie_lookup(c, "FILENAME_FIRST"), "bola1");
- assert_string_equal(bc_trie_lookup(c, "FILENAME_LAST"), "bola2");
- assert_string_equal(bc_trie_lookup(c, "DATE_FIRST"), "2001-02-03 04:05:06");
- assert_string_equal(bc_trie_lookup(c, "DATE_LAST"), "2002-02-03 04:05:06");
- assert_string_equal(bc_trie_lookup(c, "FILTER_PAGE"), "-1");
- assert_string_equal(bc_trie_lookup(c, "FILTER_PER_PAGE"), "2");
- assert_string_equal(bc_trie_lookup(c, "CURRENT_PAGE"), "1");
- assert_string_equal(bc_trie_lookup(c, "NEXT_PAGE"), "2");
- assert_string_equal(bc_trie_lookup(c, "FIRST_PAGE"), "1");
- assert_string_equal(bc_trie_lookup(c, "LAST_PAGE"), "4");
- bc_trie_free(c);
- bc_slist_free_full(s, free);
- bc_slist_free_full(t, (bc_free_func_t) bc_trie_free);
-}
-
-
-static void
-test_source_parse_from_files_filter_by_page_invalid2(void **state)
-{
- will_return(__wrap_bc_file_get_contents, "bola1.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 123\n"
- "DATE: 2001-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola2.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 456\n"
- "DATE: 2002-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola3.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 789\n"
- "DATE: 2003-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola4.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7891\n"
- "DATE: 2004-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola5.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7892\n"
- "DATE: 2005-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola6.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7893\n"
- "DATE: 2006-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola7.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 7894\n"
- "DATE: 2007-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- bc_error_t *err = NULL;
- bc_slist_t *s = NULL;
- s = bc_slist_append(s, bc_strdup("bola1.txt"));
- s = bc_slist_append(s, bc_strdup("bola2.txt"));
- s = bc_slist_append(s, bc_strdup("bola3.txt"));
- s = bc_slist_append(s, bc_strdup("bola4.txt"));
- s = bc_slist_append(s, bc_strdup("bola5.txt"));
- s = bc_slist_append(s, bc_strdup("bola6.txt"));
- s = bc_slist_append(s, bc_strdup("bola7.txt"));
- bc_trie_t *c = bc_trie_new(free);
- bc_trie_insert(c, "FILTER_PAGE", bc_strdup("5"));
- bc_trie_insert(c, "FILTER_PER_PAGE", bc_strdup("2"));
- bc_slist_t *t = blogc_source_parse_from_files(c, s, &err);
- assert_null(err);
- assert_null(t);
- bc_trie_free(c);
- bc_slist_free_full(s, free);
-}
-
-
-static void
-test_source_parse_from_files_without_all_dates(void **state)
-{
- will_return(__wrap_bc_file_get_contents, "bola1.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 123\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola2.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 456\n"
- "DATE: 2002-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola3.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 789\n"
- "DATE: 2003-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- bc_error_t *err = NULL;
- bc_slist_t *s = NULL;
- s = bc_slist_append(s, bc_strdup("bola1.txt"));
- s = bc_slist_append(s, bc_strdup("bola2.txt"));
- s = bc_slist_append(s, bc_strdup("bola3.txt"));
- bc_trie_t *c = bc_trie_new(free);
- bc_slist_t *t = blogc_source_parse_from_files(c, s, &err);
- assert_null(t);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_LOADER);
- assert_string_equal(err->msg,
- "'DATE' variable provided for at least one source file, but not for "
- "all source files. It must be provided for all files.");
- bc_error_free(err);
- assert_int_equal(bc_trie_size(c), 0);
- bc_trie_free(c);
- bc_slist_free_full(s, free);
-}
-
-
-static void
-test_source_parse_from_files_filter_sort_without_all_dates(void **state)
-{
- will_return(__wrap_bc_file_get_contents, "bola1.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 123\n"
- "DATE: 2002-02-03 04:05:06\n"
- "--------\n"
- "bola"));
- will_return(__wrap_bc_file_get_contents, "bola2.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 456\n"
- "--------\n"
- "bola"));
- bc_error_t *err = NULL;
- bc_slist_t *s = NULL;
- s = bc_slist_append(s, bc_strdup("bola1.txt"));
- s = bc_slist_append(s, bc_strdup("bola2.txt"));
- s = bc_slist_append(s, bc_strdup("bola3.txt"));
- bc_trie_t *c = bc_trie_new(free);
- bc_trie_insert(c, "FILTER_SORT", bc_strdup("1"));
- bc_slist_t *t = blogc_source_parse_from_files(c, s, &err);
- assert_null(t);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_LOADER);
- assert_string_equal(err->msg,
- "'FILTER_SORT' requires that 'DATE' variable is set for every source "
- "file: bola2.txt");
- bc_error_free(err);
- assert_int_equal(bc_trie_size(c), 1);
- assert_string_equal(bc_trie_lookup(c, "FILTER_SORT"), "1");
- bc_trie_free(c);
- bc_slist_free_full(s, free);
-}
-
-
-static void
-test_source_parse_from_files_filter_sort_with_wrong_date(void **state)
-{
- will_return(__wrap_bc_file_get_contents, "bola1.txt");
- will_return(__wrap_bc_file_get_contents, bc_strdup(
- "ASD: 123\n"
- "DATE: 2002-02-03 04:05:ab\n"
- "--------\n"
- "bola"));
- bc_error_t *err = NULL;
- bc_slist_t *s = NULL;
- s = bc_slist_append(s, bc_strdup("bola1.txt"));
- s = bc_slist_append(s, bc_strdup("bola2.txt"));
- s = bc_slist_append(s, bc_strdup("bola3.txt"));
- bc_trie_t *c = bc_trie_new(free);
- bc_trie_insert(c, "FILTER_SORT", bc_strdup("1"));
- bc_slist_t *t = blogc_source_parse_from_files(c, s, &err);
- assert_null(t);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_LOADER);
- assert_string_equal(err->msg,
- "An error occurred while parsing 'DATE' variable: bola1.txt\n\nInvalid "
- "first digit of seconds. Found 'a', must be integer >= 0 and <= 6.");
- bc_error_free(err);
- assert_int_equal(bc_trie_size(c), 1);
- assert_string_equal(bc_trie_lookup(c, "FILTER_SORT"), "1");
- bc_trie_free(c);
- bc_slist_free_full(s, free);
-}
-
-
-static void
-test_source_parse_from_files_null(void **state)
-{
- bc_error_t *err = NULL;
- bc_slist_t *s = NULL;
- bc_trie_t *c = bc_trie_new(free);
- bc_slist_t *t = blogc_source_parse_from_files(c, s, &err);
- assert_null(err);
- assert_null(t);
- assert_int_equal(bc_slist_length(t), 0);
- assert_int_equal(bc_trie_size(c), 0);
- bc_trie_free(c);
- bc_slist_free_full(s, free);
- bc_slist_free_full(t, (bc_free_func_t) bc_trie_free);
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_get_filename),
- cmocka_unit_test(test_template_parse_from_file),
- cmocka_unit_test(test_template_parse_from_file_null),
- cmocka_unit_test(test_source_parse_from_file),
- cmocka_unit_test(test_source_parse_from_file_maxdepth),
- cmocka_unit_test(test_source_parse_from_file_maxdepth2),
- cmocka_unit_test(test_source_parse_from_file_null),
- cmocka_unit_test(test_source_parse_from_files),
- cmocka_unit_test(test_source_parse_from_files_filter_sort),
- cmocka_unit_test(test_source_parse_from_files_filter_reverse),
- cmocka_unit_test(test_source_parse_from_files_filter_sort_reverse),
- cmocka_unit_test(test_source_parse_from_files_filter_by_tag),
- cmocka_unit_test(test_source_parse_from_files_filter_by_page),
- cmocka_unit_test(test_source_parse_from_files_filter_by_page2),
- cmocka_unit_test(test_source_parse_from_files_filter_by_page3),
- cmocka_unit_test(test_source_parse_from_files_filter_sort_and_by_page_and_tag),
- cmocka_unit_test(test_source_parse_from_files_filter_by_page_invalid),
- cmocka_unit_test(test_source_parse_from_files_filter_by_page_invalid2),
- cmocka_unit_test(test_source_parse_from_files_without_all_dates),
- cmocka_unit_test(test_source_parse_from_files_filter_sort_without_all_dates),
- cmocka_unit_test(test_source_parse_from_files_filter_sort_with_wrong_date),
- cmocka_unit_test(test_source_parse_from_files_null),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/blogc/check_renderer.c b/tests/blogc/check_renderer.c
deleted file mode 100644
index 08aed84..0000000
--- a/tests/blogc/check_renderer.c
+++ /dev/null
@@ -1,1435 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include "../../src/common/error.h"
-#include "../../src/common/utils.h"
-#include "../../src/blogc/renderer.h"
-#include "../../src/blogc/source-parser.h"
-#include "../../src/blogc/template-parser.h"
-
-
-static bc_slist_t*
-create_sources(size_t count)
-{
- const char *s[] = {
- "BOLA: asd\n"
- "GUDA: zxc\n"
- "GUDA2: zxc\n"
- "DATE: 2015-01-02 03:04:05\n"
- "DATE_FORMAT: %R\n"
- "TAGS: foo bar baz\n"
- "-----\n"
- "ahahahahahahahaha",
- "BOLA: asd2\n"
- "GUDA: zxc2\n"
- "DATE: 2014-02-03 04:05:06\n"
- "-----\n"
- "ahahahahahahahaha2",
- "BOLA: asd3\n"
- "GUDA: zxc3\n"
- "DATE: 2013-01-02 03:04:05\n"
- "-----\n"
- "ahahahahahahahaha3",
- };
- assert_false(count > 3);
- bc_error_t *err = NULL;
- bc_slist_t *l = NULL;
- for (size_t i = 0; i < count; i++) {
- l = bc_slist_append(l, blogc_source_parse(s[i], strlen(s[i]), -1, &err));
- assert_null(err);
- }
- assert_int_equal(bc_slist_length(l), count);
- return l;
-}
-
-
-static void
-test_render_entry(void **state)
-{
- const char *str =
- "foo\n"
- "{% block listing_once %}fuuu{% endblock %}\n"
- "{% block entry %}\n"
- "{{ DATE }}\n"
- "{% ifdef DATE_FORMATTED %}{{ DATE_FORMATTED }}{% endif %}\n"
- "{% ifdef GUDA %}{{ GUDA }}{% endif %}\n"
- "{% ifdef CHUNDA %}{{ CHUNDA }}{% endif %}\n"
- "{% endblock %}\n"
- "{% block listing %}lol{% endblock %}\n"
- "{% if GUDA == GUDA2 %}gudabola{% endif %}\n"
- "{% if GUDA == \"zxc\" %}LOL{% endif %}\n"
- "{% if GUDA != \"bola\" %}HEHE{% endif %}\n"
- "{% if GUDA < \"zxd\" %}LOL2{% endif %}\n"
- "{% if GUDA > \"zxd\" %}LOL3{% else %}ELSE{% endif %}\n"
- "{% if GUDA <= \"zxc\" %}LOL4{% endif %}\n"
- "{% foreach TAGS %}lol {{ FOREACH_ITEM }} haha {% endforeach %}\n"
- "{% foreach TAGS_ASD %}yay{% endforeach %}\n"
- "{% block listing_empty %}vazio{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- char *out = blogc_render(l, s, NULL, NULL, false);
- assert_string_equal(out,
- "foo\n"
- "\n"
- "\n"
- "2015-01-02 03:04:05\n"
- "03:04\n"
- "zxc\n"
- "\n"
- "\n"
- "\n"
- "gudabola\n"
- "LOL\n"
- "HEHE\n"
- "LOL2\n"
- "ELSE\n"
- "LOL4\n"
- "lol foo haha lol bar haha lol baz haha \n"
- "\n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_listing(void **state)
-{
- const char *str =
- "foo\n"
- "{% block listing_once %}fuuu{% endblock %}\n"
- "{% block entry %}\n"
- "{% ifdef GUDA %}{{ GUDA }}{% endif %}\n"
- "{% ifdef CHUNDA %}{{ CHUNDA }}{% endif %}\n"
- "{% endblock %}\n"
- "{% block listing %}\n"
- "{% ifdef DATE_FORMATTED %}{{ DATE_FORMATTED }}{% endif %}\n"
- "bola: {% ifdef BOLA %}{{ BOLA }}{% endif %}\n"
- "{% foreach TAGS %}lol {{ FOREACH_ITEM }} haha {% endforeach %}\n"
- "{% foreach TAGS_ASD %}yay{% endforeach %}\n"
- "{% endblock %}\n"
- "{% block listing_empty %}vazio{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(3);
- assert_non_null(s);
- char *out = blogc_render(l, s, NULL, NULL, true);
- assert_string_equal(out,
- "foo\n"
- "fuuu\n"
- "\n"
- "\n"
- "03:04\n"
- "bola: asd\n"
- "lol foo haha lol bar haha lol baz haha \n"
- "\n"
- "\n"
- "2014-02-03 04:05:06\n"
- "bola: asd2\n"
- "\n"
- "\n"
- "\n"
- "2013-01-02 03:04:05\n"
- "bola: asd3\n"
- "\n"
- "\n"
- "\n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_listing_entry(void **state)
-{
- const char *str =
- "foo\n"
- "{% block listing_once %}fuuu{% endblock %}\n"
- "{% block entry %}\n"
- "{% ifdef GUDA %}{{ GUDA }}{% endif %}\n"
- "{% ifdef CHUNDA %}{{ CHUNDA }}{% endif %}\n"
- "{% endblock %}\n"
- "{% block listing_entry %}asd{% endblock %}\n"
- "{% block listing %}\n"
- "{% ifdef DATE_FORMATTED %}{{ DATE_FORMATTED }}{% endif %}\n"
- "bola: {% ifdef BOLA %}{{ BOLA }}{% endif %}\n"
- "{% foreach TAGS %}lol {{ FOREACH_ITEM }} haha {% endforeach %}\n"
- "{% foreach TAGS_ASD %}yay{% endforeach %}\n"
- "{% endblock %}\n"
- "{% block listing_empty %}vazio{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(3);
- assert_non_null(s);
- char *out = blogc_render(l, s, NULL, NULL, true);
- assert_string_equal(out,
- "foo\n"
- "fuuu\n"
- "\n"
- "\n"
- "\n"
- "03:04\n"
- "bola: asd\n"
- "lol foo haha lol bar haha lol baz haha \n"
- "\n"
- "\n"
- "2014-02-03 04:05:06\n"
- "bola: asd2\n"
- "\n"
- "\n"
- "\n"
- "2013-01-02 03:04:05\n"
- "bola: asd3\n"
- "\n"
- "\n"
- "\n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_listing_entry2(void **state)
-{
- const char *str =
- "foo\n"
- "{% block listing_once %}fuuu{% endblock %}\n"
- "{% block entry %}\n"
- "{% ifdef GUDA %}{{ GUDA }}{% endif %}\n"
- "{% ifdef CHUNDA %}{{ CHUNDA }}{% endif %}\n"
- "{% endblock %}\n"
- "{% block listing_entry %}{{ FUUUUU }}{% endblock %}\n"
- "{% block listing_entry %}{{ BAAAAA }}{% endblock %}\n"
- "{% block listing %}\n"
- "{% ifdef DATE_FORMATTED %}{{ DATE_FORMATTED }}{% endif %}\n"
- "bola: {% ifdef BOLA %}{{ BOLA }}{% endif %}\n"
- "{% foreach TAGS %}lol {{ FOREACH_ITEM }} haha {% endforeach %}\n"
- "{% foreach TAGS_ASD %}yay{% endforeach %}\n"
- "{% endblock %}\n"
- "{% block listing_empty %}vazio{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(3);
- assert_non_null(s);
- bc_trie_t *entry = bc_trie_new(free);
- bc_trie_insert(entry, "FUUUUU", bc_strdup("XD"));
- bc_trie_insert(entry, "BAAAAA", bc_strdup(":p"));
- bc_slist_t *e = NULL;
- e = bc_slist_append(e, entry);
- char *out = blogc_render(l, s, e, NULL, true);
- bc_slist_free_full(e, (bc_free_func_t) bc_trie_free);
- assert_string_equal(out,
- "foo\n"
- "fuuu\n"
- "\n"
- "XD\n"
- "\n"
- "\n"
- "03:04\n"
- "bola: asd\n"
- "lol foo haha lol bar haha lol baz haha \n"
- "\n"
- "\n"
- "2014-02-03 04:05:06\n"
- "bola: asd2\n"
- "\n"
- "\n"
- "\n"
- "2013-01-02 03:04:05\n"
- "bola: asd3\n"
- "\n"
- "\n"
- "\n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_listing_entry3(void **state)
-{
- const char *str =
- "foo\n"
- "{% block listing_once %}fuuu{% endblock %}\n"
- "{% block entry %}\n"
- "{% ifdef GUDA %}{{ GUDA }}{% endif %}\n"
- "{% ifdef CHUNDA %}{{ CHUNDA }}{% endif %}\n"
- "{% endblock %}\n"
- "{% block listing_entry %}{{ FUUUUU }}{% endblock %}\n"
- "{% block listing_entry %}{{ BAAAAA }}{% endblock %}\n"
- "{% block listing %}\n"
- "{% ifdef DATE_FORMATTED %}{{ DATE_FORMATTED }}{% endif %}\n"
- "bola: {% ifdef BOLA %}{{ BOLA }}{% endif %}\n"
- "{% foreach TAGS %}lol {{ FOREACH_ITEM }} haha {% endforeach %}\n"
- "{% foreach TAGS_ASD %}yay{% endforeach %}\n"
- "{% endblock %}\n"
- "{% block listing_empty %}vazio{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(3);
- assert_non_null(s);
- bc_trie_t *entry = bc_trie_new(free);
- bc_trie_insert(entry, "FUUUUU", bc_strdup("XD"));
- bc_trie_insert(entry, "BAAAAA", bc_strdup(":p"));
- bc_slist_t *e = NULL;
- e = bc_slist_append(e, NULL);
- e = bc_slist_append(e, entry);
- char *out = blogc_render(l, s, e, NULL, true);
- bc_slist_free_full(e, (bc_free_func_t) bc_trie_free);
- assert_string_equal(out,
- "foo\n"
- "fuuu\n"
- "\n"
- "\n"
- ":p\n"
- "\n"
- "03:04\n"
- "bola: asd\n"
- "lol foo haha lol bar haha lol baz haha \n"
- "\n"
- "\n"
- "2014-02-03 04:05:06\n"
- "bola: asd2\n"
- "\n"
- "\n"
- "\n"
- "2013-01-02 03:04:05\n"
- "bola: asd3\n"
- "\n"
- "\n"
- "\n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_listing_entry4(void **state)
-{
- const char *str =
- "foo\n"
- "{% block listing_once %}fuuu{% endblock %}\n"
- "{% block entry %}\n"
- "{% ifdef GUDA %}{{ GUDA }}{% endif %}\n"
- "{% ifdef CHUNDA %}{{ CHUNDA }}{% endif %}\n"
- "{% endblock %}\n"
- "{% block listing_entry %}{{ FUUUUU }}{% endblock %}\n"
- "{% block listing_entry %}{{ DDDDDD }}{% endblock %}\n"
- "{% block listing %}\n"
- "{% ifdef DATE_FORMATTED %}{{ DATE_FORMATTED }}{% endif %}\n"
- "bola: {% ifdef BOLA %}{{ BOLA }}{% endif %}\n"
- "{% foreach TAGS %}lol {{ FOREACH_ITEM }} haha {% endforeach %}\n"
- "{% foreach TAGS_ASD %}yay{% endforeach %}\n"
- "{% endblock %}\n"
- "{% block listing_empty %}vazio{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(3);
- assert_non_null(s);
- bc_trie_t *entry1 = bc_trie_new(free);
- bc_trie_insert(entry1, "FUUUUU", bc_strdup("XD"));
- bc_trie_insert(entry1, "BAAAAA", bc_strdup(":p"));
- bc_trie_t *entry2 = bc_trie_new(free);
- bc_trie_insert(entry2, "CCCCCC", bc_strdup("er"));
- bc_trie_insert(entry2, "DDDDDD", bc_strdup("ty"));
- bc_slist_t *e = NULL;
- e = bc_slist_append(e, entry1);
- e = bc_slist_append(e, entry2);
- char *out = blogc_render(l, s, e, NULL, true);
- bc_slist_free_full(e, (bc_free_func_t) bc_trie_free);
- assert_string_equal(out,
- "foo\n"
- "fuuu\n"
- "\n"
- "XD\n"
- "ty\n"
- "\n"
- "03:04\n"
- "bola: asd\n"
- "lol foo haha lol bar haha lol baz haha \n"
- "\n"
- "\n"
- "2014-02-03 04:05:06\n"
- "bola: asd2\n"
- "\n"
- "\n"
- "\n"
- "2013-01-02 03:04:05\n"
- "bola: asd3\n"
- "\n"
- "\n"
- "\n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_listing_empty(void **state)
-{
- const char *str =
- "foo\n"
- "{% block listing_once %}fuuu{% endblock %}\n"
- "{% block entry %}\n"
- "{% ifdef GUDA %}{{ GUDA }}{% endif %}\n"
- "{% ifdef CHUNDA %}{{ CHUNDA }}{% endif %}\n"
- "{% endblock %}\n"
- "{% block listing %}\n"
- "{% ifdef DATE_FORMATTED %}{{ DATE_FORMATTED }}{% endif %}\n"
- "bola: {% ifdef BOLA %}{{ BOLA }}{% endif %}\n"
- "{% foreach TAGS %}lol {{ FOREACH_ITEM }} haha {% endforeach %}\n"
- "{% endblock %}\n"
- "{% block listing_empty %}vazio{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- char *out = blogc_render(l, NULL, NULL, NULL, true);
- assert_string_equal(out,
- "foo\n"
- "fuuu\n"
- "\n"
- "\n"
- "vazio\n");
- blogc_template_free_ast(l);
- free(out);
-}
-
-
-static void
-test_render_ifdef(void **state)
-{
- const char *str =
- "{% block entry %}\n"
- "{% ifdef CHUNDA %}chunda\n"
- "{% ifdef GUDA %}guda\n"
- "{% ifdef BOLA %}bola\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- char *out = blogc_render(l, s, NULL, NULL, false);
- assert_string_equal(out,
- "\n"
- "\n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_ifdef2(void **state)
-{
- const char *str =
- "{% block entry %}\n"
- "{% ifdef GUDA %}guda\n"
- "{% ifdef CHUNDA %}chunda\n"
- "{% ifdef BOLA %}bola\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- char *out = blogc_render(l, s, NULL, NULL, false);
- assert_string_equal(out,
- "\n"
- "guda\n"
- "\n"
- "\n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_ifdef3(void **state)
-{
- const char *str =
- "{% block entry %}\n"
- "{% ifdef GUDA %}guda\n"
- "{% ifdef BOLA %}bola\n"
- "{% ifdef CHUNDA %}chunda\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- char *out = blogc_render(l, s, NULL, NULL, false);
- assert_string_equal(out,
- "\n"
- "guda\n"
- "bola\n"
- "\n"
- "\n"
- "\n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_ifdef4(void **state)
-{
- const char *str =
- "{% block entry %}\n"
- "{% ifdef GUDA %}guda\n"
- "{% ifdef BOLA %}bola\n"
- "{% ifdef CHUNDA %}chunda\n"
- "{% else %}else\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% else %}lol\n"
- "{% endif %}\n"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- char *out = blogc_render(l, s, NULL, NULL, false);
- assert_string_equal(out,
- "\n"
- "guda\n"
- "bola\n"
- "else\n"
- "\n"
- "\n"
- "\n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_ifdef5(void **state)
-{
- const char *str =
- "{% block entry %}\n"
- "{% ifdef GUDA %}guda\n"
- "{% ifdef CHUNDA %}chunda\n"
- "{% ifdef BOLA %}bola\n"
- "{% endif %}\n"
- "{% else %}else\n"
- "{% endif %}\n"
- "{% else %}lol\n"
- "{% endif %}\n"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- char *out = blogc_render(l, s, NULL, NULL, false);
- assert_string_equal(out,
- "\n"
- "guda\n"
- "else\n"
- "\n"
- "\n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_ifdef6(void **state)
-{
- const char *str =
- "{% block entry %}\n"
- "{% ifdef CHUNDA %}chunda\n"
- "{% ifdef GUDA %}guda\n"
- "{% ifdef BOLA %}bola\n"
- "{% endif %}\n"
- "{% else %}else\n"
- "{% endif %}\n"
- "{% else %}lol\n"
- "{% endif %}\n"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- char *out = blogc_render(l, s, NULL, NULL, false);
- assert_string_equal(out,
- "\n"
- "lol\n"
- "\n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_ifdef7(void **state)
-{
- const char *str =
- "{% block entry %}\n"
- "{% ifdef GUDA %}guda\n"
- "{% ifdef BOLA %}bola\n"
- "{% ifdef CHUNDA %}chunda\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% ifdef CHUNDA %}ch\n"
- "{% else %}else\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- char *out = blogc_render(l, s, NULL, NULL, false);
- assert_string_equal(out,
- "\n"
- "guda\n"
- "bola\n"
- "\n"
- "\n"
- "else\n"
- "\n"
- "\n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_ifndef(void **state)
-{
- const char *str =
- "{% block entry %}\n"
- "{% ifndef CHUNDA %}chunda\n"
- "{% ifdef GUDA %}guda\n"
- "{% ifndef BOLA %}bola\n"
- "{% else %}else\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- char *out = blogc_render(l, s, NULL, NULL, false);
- assert_string_equal(out,
- "\n"
- "chunda\n"
- "guda\n"
- "else\n"
- "\n"
- "\n"
- "\n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_if_eq(void **state)
-{
- const char *str =
- "{% block entry %}\n"
- "{% if GUDA == GUDA2 %}gudabola{% endif %}\n"
- "{% if GUDA == \"zxc\" %}guda\n"
- "{% ifdef BOLA %}bola\n"
- "{% if GUDA > \"zxc\" %}asd\n"
- "{% else %}else\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- char *out = blogc_render(l, s, NULL, NULL, false);
- assert_string_equal(out,
- "\n"
- "gudabola\n"
- "guda\n"
- "bola\n"
- "else\n"
- "\n"
- "\n"
- "\n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_if_neq(void **state)
-{
- const char *str =
- "{% block entry %}\n"
- "{% if GUDA != BOLA %}gudabola{% endif %}\n"
- "{% if GUDA != \"zxa\" %}guda\n"
- "{% ifdef BOLA %}bola\n"
- "{% if GUDA > \"zxc\" %}asd\n"
- "{% else %}else\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- char *out = blogc_render(l, s, NULL, NULL, false);
- assert_string_equal(out,
- "\n"
- "gudabola\n"
- "guda\n"
- "bola\n"
- "else\n"
- "\n"
- "\n"
- "\n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_if_lt(void **state)
-{
- const char *str =
- "{% block entry %}\n"
- "{% if BOLA < GUDA %}gudabola{% endif %}\n"
- "{% if GUDA < \"zxe\" %}guda\n"
- "{% ifdef BOLA %}bola\n"
- "{% if GUDA > \"zxc\" %}asd\n"
- "{% else %}else\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- char *out = blogc_render(l, s, NULL, NULL, false);
- assert_string_equal(out,
- "\n"
- "gudabola\n"
- "guda\n"
- "bola\n"
- "else\n"
- "\n"
- "\n"
- "\n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_if_gt(void **state)
-{
- const char *str =
- "{% block entry %}\n"
- "{% if GUDA > BOLA %}gudabola{% endif %}\n"
- "{% if GUDA > \"zxa\" %}guda\n"
- "{% ifdef BOLA %}bola\n"
- "{% if GUDA > \"zxc\" %}asd\n"
- "{% else %}else\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- char *out = blogc_render(l, s, NULL, NULL, false);
- assert_string_equal(out,
- "\n"
- "gudabola\n"
- "guda\n"
- "bola\n"
- "else\n"
- "\n"
- "\n"
- "\n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_if_lt_eq(void **state)
-{
- const char *str =
- "{% block entry %}\n"
- "{% if BOLA <= GUDA %}gudabola{% endif %}\n"
- "{% if GUDA <= \"zxc\" %}guda\n"
- "{% if GUDA <= \"zxe\" %}guda2\n"
- "{% ifdef BOLA %}bola\n"
- "{% if GUDA > \"zxc\" %}asd\n"
- "{% else %}else\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- char *out = blogc_render(l, s, NULL, NULL, false);
- assert_string_equal(out,
- "\n"
- "gudabola\n"
- "guda\n"
- "guda2\n"
- "bola\n"
- "else\n"
- "\n"
- "\n"
- "\n"
- "\n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_if_gt_eq(void **state)
-{
- const char *str =
- "{% block entry %}\n"
- "{% if GUDA >= BOLA %}gudabola{% endif %}\n"
- "{% if GUDA >= \"zxc\" %}guda\n"
- "{% if GUDA >= \"zxa\" %}guda2\n"
- "{% ifdef BOLA %}bola\n"
- "{% if GUDA > \"zxc\" %}asd\n"
- "{% else %}else\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- char *out = blogc_render(l, s, NULL, NULL, false);
- assert_string_equal(out,
- "\n"
- "gudabola\n"
- "guda\n"
- "guda2\n"
- "bola\n"
- "else\n"
- "\n"
- "\n"
- "\n"
- "\n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_foreach(void **state)
-{
- const char *str =
- "{% block entry %}\n"
- "{% foreach TAGS %} {{ FOREACH_ITEM }} {% endforeach %}\n"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- char *out = blogc_render(l, s, NULL, NULL, false);
- assert_string_equal(out,
- "\n"
- " foo bar baz \n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_foreach_if(void **state)
-{
- const char *str =
- "{% block entry %}\n"
- "{% foreach TAGS %} {% if FOREACH_ITEM == \"bar\" %}{{ FOREACH_ITEM }}"
- "{% endif %} {% endforeach %}\n"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- char *out = blogc_render(l, s, NULL, NULL, false);
- assert_string_equal(out,
- "\n"
- " bar \n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_foreach_if_else(void **state)
-{
- const char *str =
- "{% block entry %}\n"
- "{% foreach TAGS %}{% if FOREACH_ITEM == \"bar\" %}yay"
- "{% else %}{{ FOREACH_ITEM }}"
- "{% endif %} {% endforeach %}\n"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- char *out = blogc_render(l, s, NULL, NULL, false);
- assert_string_equal(out,
- "\n"
- "foo yay baz \n"
- "\n");
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_null(void **state)
-{
- assert_null(blogc_render(NULL, NULL, NULL, NULL, false));
-}
-
-
-static void
-test_render_outside_block(void **state)
-{
- const char *str =
- "{% ifdef GUDA %}bola{% endif %}\n"
- "{{ BOLA }}\n"
- "{% ifndef CHUNDA %}lol{% endif %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- bc_trie_t *c = bc_trie_new(free);
- bc_trie_insert(c, "GUDA", bc_strdup("asd"));
- char *out = blogc_render(l, s, NULL, c, false);
- assert_string_equal(out,
- "bola\n"
- "\n"
- "lol\n");
- bc_trie_free(c);
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_prefer_local_variable(void **state)
-{
- const char *str =
- "{% block entry %}\n"
- "{% ifdef LOL %}{{ LOL }}{% endif %}\n"
- "{% ifndef CHUNDA %}chunda\n"
- "{% ifdef GUDA %}{{ GUDA }}\n"
- "{% ifndef BOLA %}bola\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- bc_trie_t *c = bc_trie_new(free);
- bc_trie_insert(c, "GUDA", bc_strdup("hehe"));
- bc_trie_insert(c, "LOL", bc_strdup("hmm"));
- char *out = blogc_render(l, s, NULL, c, false);
- assert_string_equal(out,
- "\n"
- "hmm\n"
- "chunda\n"
- "zxc\n"
- "\n"
- "\n"
- "\n"
- "\n");
- bc_trie_free(c);
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_respect_variable_scope(void **state)
-{
- const char *str =
- "{{ LOL }}\n"
- "{{ BOLA }}\n"
- "{% block entry %}\n"
- "{% ifdef LOL %}{{ LOL }}{% endif %}\n"
- "{% ifdef BOLA %}{{ BOLA }}{% endif %}\n"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = create_sources(1);
- assert_non_null(s);
- bc_trie_t *c = bc_trie_new(free);
- char *out = blogc_render(l, s, NULL, c, false);
- assert_string_equal(out,
- "\n"
- "\n"
- "\n"
- "\n"
- "asd\n"
- "\n");
- bc_trie_free(c);
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_render_ifcount_bug(void **state)
-{
- const char *str =
- "{% block entry %}\n"
- "{% ifdef TITLE %}<h3>{{ TITLE }}</h3>{% endif %}\n"
- "{% ifdef IS_POST %}\n"
- "{% ifdef ASD %}ASD{% endif %}\n"
- "{% endif %}\n"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
- assert_non_null(l);
- assert_null(err);
- bc_slist_t *s = NULL;
- s = bc_slist_append(s, bc_trie_new(free));
- bc_trie_insert(s->data, "TITLE", bc_strdup("bola"));
- bc_trie_t *c = bc_trie_new(free);
- char *out = blogc_render(l, s, NULL, c, false);
- assert_string_equal(out,
- "\n"
- "<h3>bola</h3>\n"
- "\n"
- "\n");
- bc_trie_free(c);
- blogc_template_free_ast(l);
- bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
- free(out);
-}
-
-
-static void
-test_get_variable(void **state)
-{
- bc_trie_t *g = bc_trie_new(free);
- bc_trie_insert(g, "NAME", bc_strdup("bola"));
- bc_trie_insert(g, "TITLE", bc_strdup("bola2"));
- bc_trie_t *l = bc_trie_new(free);
- bc_trie_insert(l, "NAME", bc_strdup("chunda"));
- bc_trie_insert(l, "TITLE", bc_strdup("chunda2"));
- assert_string_equal(blogc_get_variable("NAME", g, l), "chunda");
- assert_string_equal(blogc_get_variable("TITLE", g, l), "chunda2");
- assert_null(blogc_get_variable("BOLA", g, l));
- bc_trie_free(g);
- bc_trie_free(l);
-}
-
-
-static void
-test_get_variable_only_local(void **state)
-{
- bc_trie_t *g = NULL;
- bc_trie_t *l = bc_trie_new(free);
- bc_trie_insert(l, "NAME", bc_strdup("chunda"));
- bc_trie_insert(l, "TITLE", bc_strdup("chunda2"));
- assert_string_equal(blogc_get_variable("NAME", g, l), "chunda");
- assert_string_equal(blogc_get_variable("TITLE", g, l), "chunda2");
- assert_null(blogc_get_variable("BOLA", g, l));
- bc_trie_free(l);
-}
-
-
-static void
-test_get_variable_only_global(void **state)
-{
- bc_trie_t *g = bc_trie_new(free);
- bc_trie_insert(g, "NAME", bc_strdup("bola"));
- bc_trie_insert(g, "TITLE", bc_strdup("bola2"));
- bc_trie_t *l = NULL;
- assert_string_equal(blogc_get_variable("NAME", g, l), "bola");
- assert_string_equal(blogc_get_variable("TITLE", g, l), "bola2");
- assert_null(blogc_get_variable("BOLA", g, l));
- bc_trie_free(g);
-}
-
-
-static void
-test_format_date(void **state)
-{
- bc_trie_t *g = bc_trie_new(free);
- bc_trie_insert(g, "DATE_FORMAT", bc_strdup("%H -- %M"));
- bc_trie_t *l = bc_trie_new(free);
- bc_trie_insert(l, "DATE_FORMAT", bc_strdup("%R"));
- char *date = blogc_format_date("2015-01-02 03:04:05", g, l);
- assert_string_equal(date, "03:04");
- free(date);
- bc_trie_free(g);
- bc_trie_free(l);
-}
-
-
-static void
-test_format_date_with_global_format(void **state)
-{
- bc_trie_t *g = bc_trie_new(free);
- bc_trie_insert(g, "DATE_FORMAT", bc_strdup("%H -- %M"));
- bc_trie_t *l = bc_trie_new(free);
- char *date = blogc_format_date("2015-01-02 03:04:05", g, l);
- assert_string_equal(date, "03 -- 04");
- free(date);
- bc_trie_free(g);
- bc_trie_free(l);
-}
-
-
-static void
-test_format_date_without_format(void **state)
-{
- bc_trie_t *g = bc_trie_new(free);
- bc_trie_t *l = bc_trie_new(free);
- char *date = blogc_format_date("2015-01-02 03:04:05", g, l);
- assert_string_equal(date, "2015-01-02 03:04:05");
- free(date);
- bc_trie_free(g);
- bc_trie_free(l);
-}
-
-
-static void
-test_format_date_without_date(void **state)
-{
- bc_trie_t *g = bc_trie_new(free);
- bc_trie_t *l = bc_trie_new(free);
- char *date = blogc_format_date(NULL, g, l);
- assert_null(date);
- free(date);
- bc_trie_free(g);
- bc_trie_free(l);
-}
-
-
-static void
-test_format_variable(void **state)
-{
- // FIXME: test warnings
- bc_trie_t *g = bc_trie_new(free);
- bc_trie_insert(g, "NAME", bc_strdup("bola"));
- bc_trie_insert(g, "TITLE", bc_strdup("bola2"));
- bc_trie_t *l = bc_trie_new(free);
- bc_trie_insert(l, "NAME", bc_strdup("chunda"));
- bc_trie_insert(l, "TITLE", bc_strdup("chunda2"));
- bc_trie_insert(l, "SIZE", bc_strdup("1234567890987654321"));
- char *tmp = blogc_format_variable("NAME", g, l, NULL, NULL);
- assert_string_equal(tmp, "chunda");
- free(tmp);
- tmp = blogc_format_variable("TITLE", g, l, NULL, NULL);
- assert_string_equal(tmp, "chunda2");
- free(tmp);
- tmp = blogc_format_variable("TITLE_2", g, l, NULL, NULL);
- assert_string_equal(tmp, "ch");
- free(tmp);
- tmp = blogc_format_variable("SIZE_12", g, l, NULL, NULL);
- assert_string_equal(tmp, "123456789098");
- free(tmp);
- tmp = blogc_format_variable("SIZE_200", g, l, NULL, NULL);
- assert_string_equal(tmp, "1234567890987654321");
- free(tmp);
- assert_null(blogc_format_variable("SIZE_", g, l, NULL, NULL));
- assert_null(blogc_format_variable("BOLA", g, l, NULL, NULL));
- bc_trie_free(g);
- bc_trie_free(l);
-}
-
-
-static void
-test_format_variable_with_date(void **state)
-{
- bc_trie_t *g = bc_trie_new(free);
- bc_trie_insert(g, "DATE", bc_strdup("2010-11-12 13:14:15"));
- bc_trie_insert(g, "DATE_FORMAT", bc_strdup("%R"));
- bc_trie_t *l = bc_trie_new(free);
- bc_trie_insert(l, "DATE", bc_strdup("2011-12-13 14:15:16"));
- char *tmp = blogc_format_variable("DATE_FORMATTED", g, l, NULL, NULL);
- assert_string_equal(tmp, "14:15");
- free(tmp);
- tmp = blogc_format_variable("DATE_FORMATTED_3", g, l, NULL, NULL);
- assert_string_equal(tmp, "14:");
- free(tmp);
- tmp = blogc_format_variable("DATE_FORMATTED_10", g, l, NULL, NULL);
- assert_string_equal(tmp, "14:15");
- free(tmp);
- bc_trie_free(g);
- bc_trie_free(l);
-}
-
-
-static void
-test_format_variable_foreach(void **state)
-{
- bc_slist_t *l = NULL;
- l = bc_slist_append(l, bc_strdup("asd"));
- l = bc_slist_append(l, bc_strdup("qwe"));
- l = bc_slist_append(l, bc_strdup("zxcvbn"));
- char *tmp = blogc_format_variable("FOREACH_ITEM", NULL, NULL, NULL, l->next);
- assert_string_equal(tmp, "qwe");
- free(tmp);
- tmp = blogc_format_variable("FOREACH_ITEM_4", NULL, NULL, NULL, l->next->next);
- assert_string_equal(tmp, "zxcv");
- free(tmp);
- tmp = blogc_format_variable("FOREACH_ITEM_10", NULL, NULL, NULL, l->next->next);
- assert_string_equal(tmp, "zxcvbn");
- free(tmp);
- bc_slist_free_full(l, free);
-}
-
-
-static void
-test_format_variable_foreach_value(void **state)
-{
- bc_trie_t *gl = bc_trie_new(free);
- bc_trie_insert(gl, "FOO_BAR__QWE", bc_strdup("bnm"));
- bc_trie_t *loc = bc_trie_new(free);
- bc_trie_insert(loc, "BAR__ZXCVBN", bc_strdup("dfg"));
- bc_trie_insert(loc, "HUE__ZXCVBN", bc_strdup("xcv"));
- bc_slist_t *l = NULL;
- l = bc_slist_append(l, bc_strdup("asd"));
- l = bc_slist_append(l, bc_strdup("qwe"));
- l = bc_slist_append(l, bc_strdup("zxcvbn"));
- char *tmp = blogc_format_variable("FOREACH_VALUE", gl, loc, "foo-bar", l->next);
- assert_string_equal(tmp, "bnm");
- free(tmp);
- tmp = blogc_format_variable("FOREACH_VALUE_2", gl, loc, "bar", l->next->next);
- assert_string_equal(tmp, "df");
- free(tmp);
- tmp = blogc_format_variable("FOREACH_VALUE_4", gl, loc, "hue", l->next->next);
- assert_string_equal(tmp, "xcv");
- free(tmp);
- bc_trie_free(gl);
- bc_trie_free(loc);
- bc_slist_free_full(l, free);
-}
-
-
-static void
-test_format_variable_foreach_empty(void **state)
-{
- assert_null(blogc_format_variable("FOREACH_ITEM", NULL, NULL, NULL, NULL));
- assert_null(blogc_format_variable("FOREACH_ITEM_4", NULL, NULL, NULL, NULL));
-}
-
-
-static void
-test_split_list_variable(void **state)
-{
- bc_trie_t *g = bc_trie_new(free);
- bc_trie_insert(g, "TAGS", bc_strdup("asd lol hehe"));
- bc_trie_t *l = bc_trie_new(free);
- bc_trie_insert(l, "TAGS", bc_strdup("asd lol XD"));
- bc_slist_t *tmp = blogc_split_list_variable("TAGS", g, l);
- assert_string_equal(tmp->data, "asd");
- assert_string_equal(tmp->next->data, "lol");
- assert_string_equal(tmp->next->next->data, "XD");
- bc_slist_free_full(tmp, free);
- bc_trie_free(g);
- bc_trie_free(l);
-}
-
-
-static void
-test_split_list_variable_not_found(void **state)
-{
- bc_trie_t *g = bc_trie_new(free);
- bc_trie_insert(g, "TAGS", bc_strdup("asd lol hehe"));
- bc_trie_t *l = bc_trie_new(free);
- bc_trie_insert(l, "TAGS", bc_strdup("asd lol XD"));
- bc_slist_t *tmp = blogc_split_list_variable("TAG", g, l);
- assert_null(tmp);
- bc_trie_free(g);
- bc_trie_free(l);
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_render_entry),
- cmocka_unit_test(test_render_listing),
- cmocka_unit_test(test_render_listing_entry),
- cmocka_unit_test(test_render_listing_entry2),
- cmocka_unit_test(test_render_listing_entry3),
- cmocka_unit_test(test_render_listing_entry4),
- cmocka_unit_test(test_render_listing_empty),
- cmocka_unit_test(test_render_ifdef),
- cmocka_unit_test(test_render_ifdef2),
- cmocka_unit_test(test_render_ifdef3),
- cmocka_unit_test(test_render_ifdef4),
- cmocka_unit_test(test_render_ifdef5),
- cmocka_unit_test(test_render_ifdef6),
- cmocka_unit_test(test_render_ifdef7),
- cmocka_unit_test(test_render_ifndef),
- cmocka_unit_test(test_render_if_eq),
- cmocka_unit_test(test_render_if_neq),
- cmocka_unit_test(test_render_if_lt),
- cmocka_unit_test(test_render_if_gt),
- cmocka_unit_test(test_render_if_lt_eq),
- cmocka_unit_test(test_render_if_gt_eq),
- cmocka_unit_test(test_render_foreach),
- cmocka_unit_test(test_render_foreach_if),
- cmocka_unit_test(test_render_foreach_if_else),
- cmocka_unit_test(test_render_null),
- cmocka_unit_test(test_render_outside_block),
- cmocka_unit_test(test_render_prefer_local_variable),
- cmocka_unit_test(test_render_respect_variable_scope),
- cmocka_unit_test(test_render_ifcount_bug),
- cmocka_unit_test(test_get_variable),
- cmocka_unit_test(test_get_variable_only_local),
- cmocka_unit_test(test_get_variable_only_global),
- cmocka_unit_test(test_format_date),
- cmocka_unit_test(test_format_date_with_global_format),
- cmocka_unit_test(test_format_date_without_format),
- cmocka_unit_test(test_format_date_without_date),
- cmocka_unit_test(test_format_variable),
- cmocka_unit_test(test_format_variable_with_date),
- cmocka_unit_test(test_format_variable_foreach),
- cmocka_unit_test(test_format_variable_foreach_value),
- cmocka_unit_test(test_format_variable_foreach_empty),
- cmocka_unit_test(test_split_list_variable),
- cmocka_unit_test(test_split_list_variable_not_found),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/blogc/check_rusage.c b/tests/blogc/check_rusage.c
deleted file mode 100644
index c332991..0000000
--- a/tests/blogc/check_rusage.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include "../../src/common/utils.h"
-#include "../../src/blogc/rusage.h"
-
-
-int
-__wrap_getrusage(int who, struct rusage *usage)
-{
- assert_int_equal(who, RUSAGE_SELF);
- int rv = mock_type(int);
- if (rv == 0) {
- usage->ru_utime.tv_sec = 1;
- usage->ru_utime.tv_usec = 2;
- usage->ru_stime.tv_sec = 3;
- usage->ru_stime.tv_usec = 4;
- usage->ru_maxrss = 10250;
- }
- return rv;
-}
-
-
-static void
-test_rusage_get(void **state)
-{
- will_return(__wrap_getrusage, -1);
- assert_null(blogc_rusage_get());
-
- will_return(__wrap_getrusage, 0);
- blogc_rusage_t *r = blogc_rusage_get();
- assert_non_null(r);
- assert_int_equal(r->cpu_time, 4000006);
- assert_int_equal(r->memory, 10250);
- free(r);
-}
-
-
-static void
-test_rusage_format_cpu_time(void **state)
-{
- char *f = blogc_rusage_format_cpu_time(0);
- assert_string_equal(f, "0us");
- free(f);
-
- f = blogc_rusage_format_cpu_time(123);
- assert_string_equal(f, "123us");
- free(f);
-
- f = blogc_rusage_format_cpu_time(1234);
- assert_string_equal(f, "1.234ms");
- free(f);
-
- f = blogc_rusage_format_cpu_time(3000);
- assert_string_equal(f, "3ms");
- free(f);
-
- f = blogc_rusage_format_cpu_time(12345678);
- assert_string_equal(f, "12.346s");
- free(f);
-}
-
-
-static void
-test_rusage_format_memory(void **state)
-{
- char *f = blogc_rusage_format_memory(0);
- assert_string_equal(f, "0KB");
- free(f);
-
- f = blogc_rusage_format_memory(123);
- assert_string_equal(f, "123KB");
- free(f);
-
- f = blogc_rusage_format_memory(1234);
- assert_string_equal(f, "1.205MB");
- free(f);
-
- f = blogc_rusage_format_memory(12345678);
- assert_string_equal(f, "11.774GB");
- free(f);
-}
-
-
-static void
-test_rusage_inject(void **state)
-{
- bc_trie_t *t = bc_trie_new(free);
-
- will_return(__wrap_getrusage, -1);
- blogc_rusage_inject(t);
- assert_int_equal(bc_trie_size(t), 0);
-
- will_return(__wrap_getrusage, 0);
- blogc_rusage_inject(t);
- assert_int_equal(bc_trie_size(t), 2);
- assert_string_equal(bc_trie_lookup(t, "BLOGC_RUSAGE_CPU_TIME"), "4.000s");
- assert_string_equal(bc_trie_lookup(t, "BLOGC_RUSAGE_MEMORY"), "10.010MB");
- bc_trie_free(t);
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_rusage_get),
- cmocka_unit_test(test_rusage_format_cpu_time),
- cmocka_unit_test(test_rusage_format_memory),
- cmocka_unit_test(test_rusage_inject),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/blogc/check_source_parser.c b/tests/blogc/check_source_parser.c
deleted file mode 100644
index 822133c..0000000
--- a/tests/blogc/check_source_parser.c
+++ /dev/null
@@ -1,761 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#include <string.h>
-#include "../../src/common/error.h"
-#include "../../src/common/utils.h"
-#include "../../src/blogc/source-parser.h"
-
-
-static void
-test_source_parse(void **state)
-{
- const char *a =
- "VAR1: asd asd\n"
- "VAR2: 123chunda\n"
- "----------\n"
- "# This is a test\n"
- "\n"
- "bola\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_null(err);
- assert_non_null(source);
- assert_int_equal(bc_trie_size(source), 7);
- assert_string_equal(bc_trie_lookup(source, "VAR1"), "asd asd");
- assert_string_equal(bc_trie_lookup(source, "VAR2"), "123chunda");
- assert_string_equal(bc_trie_lookup(source, "EXCERPT"),
- "<h1 id=\"this-is-a-test\">This is a test</h1>\n"
- "<p>bola</p>\n");
- assert_string_equal(bc_trie_lookup(source, "CONTENT"),
- "<h1 id=\"this-is-a-test\">This is a test</h1>\n"
- "<p>bola</p>\n");
- assert_string_equal(bc_trie_lookup(source, "RAW_CONTENT"),
- "# This is a test\n"
- "\n"
- "bola\n");
- assert_string_equal(bc_trie_lookup(source, "FIRST_HEADER"), "This is a test");
- assert_string_equal(bc_trie_lookup(source, "DESCRIPTION"), "bola");
- assert_null(bc_trie_lookup(source, "TOCTREE"));
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_crlf(void **state)
-{
- const char *a =
- "VAR1: asd asd\r\n"
- "VAR2: 123chunda\r\n"
- "----------\r\n"
- "# This is a test\r\n"
- "\r\n"
- "bola\r\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 1, &err);
- assert_null(err);
- assert_non_null(source);
- assert_int_equal(bc_trie_size(source), 8);
- assert_string_equal(bc_trie_lookup(source, "VAR1"), "asd asd");
- assert_string_equal(bc_trie_lookup(source, "VAR2"), "123chunda");
- assert_string_equal(bc_trie_lookup(source, "EXCERPT"),
- "<h1 id=\"this-is-a-test\">This is a test</h1>\r\n"
- "<p>bola</p>\r\n");
- assert_string_equal(bc_trie_lookup(source, "CONTENT"),
- "<h1 id=\"this-is-a-test\">This is a test</h1>\r\n"
- "<p>bola</p>\r\n");
- assert_string_equal(bc_trie_lookup(source, "RAW_CONTENT"),
- "# This is a test\r\n"
- "\r\n"
- "bola\r\n");
- assert_string_equal(bc_trie_lookup(source, "FIRST_HEADER"), "This is a test");
- assert_string_equal(bc_trie_lookup(source, "DESCRIPTION"), "bola");
- assert_string_equal(bc_trie_lookup(source, "TOCTREE"),
- "<ul>\r\n"
- " <li><a href=\"#this-is-a-test\">This is a test</a></li>\r\n"
- "</ul>\r\n");
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_with_spaces(void **state)
-{
- const char *a =
- "\n \n"
- "VAR1: chunda \t \n"
- "\n\n"
- "BOLA: guda\n"
- "----------\n"
- "# This is a test\n"
- "\n"
- "bola\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), -1, &err);
- assert_null(err);
- assert_non_null(source);
- assert_int_equal(bc_trie_size(source), 8);
- assert_string_equal(bc_trie_lookup(source, "VAR1"), "chunda");
- assert_string_equal(bc_trie_lookup(source, "BOLA"), "guda");
- assert_string_equal(bc_trie_lookup(source, "EXCERPT"),
- "<h1 id=\"this-is-a-test\">This is a test</h1>\n"
- "<p>bola</p>\n");
- assert_string_equal(bc_trie_lookup(source, "CONTENT"),
- "<h1 id=\"this-is-a-test\">This is a test</h1>\n"
- "<p>bola</p>\n");
- assert_string_equal(bc_trie_lookup(source, "RAW_CONTENT"),
- "# This is a test\n"
- "\n"
- "bola\n");
- assert_string_equal(bc_trie_lookup(source, "FIRST_HEADER"), "This is a test");
- assert_string_equal(bc_trie_lookup(source, "DESCRIPTION"), "bola");
- assert_string_equal(bc_trie_lookup(source, "TOCTREE"),
- "<ul>\n"
- " <li><a href=\"#this-is-a-test\">This is a test</a></li>\n"
- "</ul>\n");
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_with_excerpt(void **state)
-{
- const char *a =
- "VAR1: asd asd\n"
- "VAR2: 123chunda\n"
- "----------\n"
- "# This is a test\n"
- "\n"
- "bola\n"
- "\n"
- "...\n"
- "\n"
- "guda\n"
- "yay";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_null(err);
- assert_non_null(source);
- assert_int_equal(bc_trie_size(source), 7);
- assert_string_equal(bc_trie_lookup(source, "VAR1"), "asd asd");
- assert_string_equal(bc_trie_lookup(source, "VAR2"), "123chunda");
- assert_string_equal(bc_trie_lookup(source, "EXCERPT"),
- "<h1 id=\"this-is-a-test\">This is a test</h1>\n"
- "<p>bola</p>\n");
- assert_string_equal(bc_trie_lookup(source, "CONTENT"),
- "<h1 id=\"this-is-a-test\">This is a test</h1>\n"
- "<p>bola</p>\n"
- "<p>guda\n"
- "yay</p>\n");
- assert_string_equal(bc_trie_lookup(source, "RAW_CONTENT"),
- "# This is a test\n"
- "\n"
- "bola\n"
- "\n"
- "...\n"
- "\n"
- "guda\n"
- "yay");
- assert_string_equal(bc_trie_lookup(source, "FIRST_HEADER"), "This is a test");
- assert_string_equal(bc_trie_lookup(source, "DESCRIPTION"), "bola");
- assert_null(bc_trie_lookup(source, "TOCTREE"));
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_with_first_header(void **state)
-{
- const char *a =
- "VAR1: asd asd\n"
- "VAR2: 123chunda\n"
- "FIRST_HEADER: THIS IS CHUNDA!\n"
- "----------\n"
- "# This is a test\n"
- "\n"
- "bola\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_null(err);
- assert_non_null(source);
- assert_int_equal(bc_trie_size(source), 7);
- assert_string_equal(bc_trie_lookup(source, "VAR1"), "asd asd");
- assert_string_equal(bc_trie_lookup(source, "VAR2"), "123chunda");
- assert_string_equal(bc_trie_lookup(source, "EXCERPT"),
- "<h1 id=\"this-is-a-test\">This is a test</h1>\n"
- "<p>bola</p>\n");
- assert_string_equal(bc_trie_lookup(source, "CONTENT"),
- "<h1 id=\"this-is-a-test\">This is a test</h1>\n"
- "<p>bola</p>\n");
- assert_string_equal(bc_trie_lookup(source, "RAW_CONTENT"),
- "# This is a test\n"
- "\n"
- "bola\n");
- assert_string_equal(bc_trie_lookup(source, "FIRST_HEADER"), "THIS IS CHUNDA!");
- assert_string_equal(bc_trie_lookup(source, "DESCRIPTION"), "bola");
- assert_null(bc_trie_lookup(source, "TOCTREE"));
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_with_description(void **state)
-{
- const char *a =
- "VAR1: asd asd\n"
- "VAR2: 123chunda\n"
- "DESCRIPTION: huehuehuebrbr\n"
- "----------\n"
- "# This is a test\n"
- "\n"
- "bola\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_null(err);
- assert_non_null(source);
- assert_int_equal(bc_trie_size(source), 7);
- assert_string_equal(bc_trie_lookup(source, "VAR1"), "asd asd");
- assert_string_equal(bc_trie_lookup(source, "VAR2"), "123chunda");
- assert_string_equal(bc_trie_lookup(source, "EXCERPT"),
- "<h1 id=\"this-is-a-test\">This is a test</h1>\n"
- "<p>bola</p>\n");
- assert_string_equal(bc_trie_lookup(source, "CONTENT"),
- "<h1 id=\"this-is-a-test\">This is a test</h1>\n"
- "<p>bola</p>\n");
- assert_string_equal(bc_trie_lookup(source, "RAW_CONTENT"),
- "# This is a test\n"
- "\n"
- "bola\n");
- assert_string_equal(bc_trie_lookup(source, "FIRST_HEADER"), "This is a test");
- assert_string_equal(bc_trie_lookup(source, "DESCRIPTION"), "huehuehuebrbr");
- assert_null(bc_trie_lookup(source, "TOCTREE"));
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_with_toctree(void **state)
-{
- const char *a =
- "VAR1: asd asd\n"
- "VAR2: 123chunda\n"
- "----------\n"
- "### asd\n"
- "### qwe\n"
- "## zxc\n"
- "### rty\n"
- "#### bnm\n"
- "### asd\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), -1, &err);
- assert_null(err);
- assert_non_null(source);
- assert_int_equal(bc_trie_size(source), 7);
- assert_string_equal(bc_trie_lookup(source, "VAR1"), "asd asd");
- assert_string_equal(bc_trie_lookup(source, "VAR2"), "123chunda");
- assert_string_equal(bc_trie_lookup(source, "EXCERPT"),
- "<h3 id=\"asd\">asd</h3>\n"
- "<h3 id=\"qwe\">qwe</h3>\n"
- "<h2 id=\"zxc\">zxc</h2>\n"
- "<h3 id=\"rty\">rty</h3>\n"
- "<h4 id=\"bnm\">bnm</h4>\n"
- "<h3 id=\"asd\">asd</h3>\n");
- assert_string_equal(bc_trie_lookup(source, "CONTENT"),
- "<h3 id=\"asd\">asd</h3>\n"
- "<h3 id=\"qwe\">qwe</h3>\n"
- "<h2 id=\"zxc\">zxc</h2>\n"
- "<h3 id=\"rty\">rty</h3>\n"
- "<h4 id=\"bnm\">bnm</h4>\n"
- "<h3 id=\"asd\">asd</h3>\n");
- assert_string_equal(bc_trie_lookup(source, "RAW_CONTENT"),
- "### asd\n"
- "### qwe\n"
- "## zxc\n"
- "### rty\n"
- "#### bnm\n"
- "### asd\n");
- assert_string_equal(bc_trie_lookup(source, "FIRST_HEADER"), "asd");
- assert_string_equal(bc_trie_lookup(source, "TOCTREE"),
- "<ul>\n"
- " <ul>\n"
- " <li><a href=\"#asd\">asd</a></li>\n"
- " <li><a href=\"#qwe\">qwe</a></li>\n"
- " </ul>\n"
- " <li><a href=\"#zxc\">zxc</a></li>\n"
- " <ul>\n"
- " <li><a href=\"#rty\">rty</a></li>\n"
- " <ul>\n"
- " <li><a href=\"#bnm\">bnm</a></li>\n"
- " </ul>\n"
- " <li><a href=\"#asd\">asd</a></li>\n"
- " </ul>\n"
- "</ul>\n");
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_with_toctree_noheader(void **state)
-{
- const char *a =
- "VAR1: asd asd\n"
- "VAR2: 123chunda\n"
- "----------\n"
- "asd\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), -1, &err);
- assert_null(err);
- assert_non_null(source);
- assert_int_equal(bc_trie_size(source), 6);
- assert_string_equal(bc_trie_lookup(source, "VAR1"), "asd asd");
- assert_string_equal(bc_trie_lookup(source, "VAR2"), "123chunda");
- assert_string_equal(bc_trie_lookup(source, "EXCERPT"),
- "<p>asd</p>\n");
- assert_string_equal(bc_trie_lookup(source, "CONTENT"),
- "<p>asd</p>\n");
- assert_string_equal(bc_trie_lookup(source, "RAW_CONTENT"),
- "asd\n");
- assert_null(bc_trie_lookup(source, "FIRST_HEADER"));
- assert_null(bc_trie_lookup(source, "TOCTREE"));
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_with_toctree_maxdepth1(void **state)
-{
- const char *a =
- "VAR1: asd asd\n"
- "VAR2: 123chunda\n"
- "----------\n"
- "### asd\n"
- "### qwe\n"
- "## zxc\n"
- "### rty\n"
- "#### bnm\n"
- "### asd\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 1, &err);
- assert_null(err);
- assert_non_null(source);
- assert_int_equal(bc_trie_size(source), 7);
- assert_string_equal(bc_trie_lookup(source, "VAR1"), "asd asd");
- assert_string_equal(bc_trie_lookup(source, "VAR2"), "123chunda");
- assert_string_equal(bc_trie_lookup(source, "EXCERPT"),
- "<h3 id=\"asd\">asd</h3>\n"
- "<h3 id=\"qwe\">qwe</h3>\n"
- "<h2 id=\"zxc\">zxc</h2>\n"
- "<h3 id=\"rty\">rty</h3>\n"
- "<h4 id=\"bnm\">bnm</h4>\n"
- "<h3 id=\"asd\">asd</h3>\n");
- assert_string_equal(bc_trie_lookup(source, "CONTENT"),
- "<h3 id=\"asd\">asd</h3>\n"
- "<h3 id=\"qwe\">qwe</h3>\n"
- "<h2 id=\"zxc\">zxc</h2>\n"
- "<h3 id=\"rty\">rty</h3>\n"
- "<h4 id=\"bnm\">bnm</h4>\n"
- "<h3 id=\"asd\">asd</h3>\n");
- assert_string_equal(bc_trie_lookup(source, "RAW_CONTENT"),
- "### asd\n"
- "### qwe\n"
- "## zxc\n"
- "### rty\n"
- "#### bnm\n"
- "### asd\n");
- assert_string_equal(bc_trie_lookup(source, "FIRST_HEADER"), "asd");
- assert_string_equal(bc_trie_lookup(source, "TOCTREE"),
- "<ul>\n"
- " <li><a href=\"#zxc\">zxc</a></li>\n"
- "</ul>\n");
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_with_toctree_maxdepth_invalid(void **state)
-{
- const char *a =
- "VAR1: asd asd\n"
- "VAR2: 123chunda\n"
- "TOCTREE_MAXDEPTH: bola\n"
- "----------\n"
- "### asd\n"
- "### qwe\n"
- "## zxc\n"
- "### rty\n"
- "#### bnm\n"
- "### asd\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 1, &err);
- assert_non_null(err);
- assert_null(source);
- assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
- assert_string_equal(err->msg,
- "Invalid value for 'TOCTREE_MAXDEPTH' variable: bola.\n"
- "Error occurred near line 10, position 8: ### asd");
- bc_error_free(err);
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_config_empty(void **state)
-{
- const char *a = "";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_null(source);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
- assert_string_equal(err->msg, "Your source file is empty.");
- bc_error_free(err);
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_config_invalid_key(void **state)
-{
- const char *a = "bola: guda";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
- assert_string_equal(err->msg,
- "Can't find a configuration key or the content separator.\n"
- "Error occurred near line 1, position 1: bola: guda");
- bc_error_free(err);
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_config_no_key(void **state)
-{
- const char *a = "BOLa";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
- assert_string_equal(err->msg,
- "Invalid configuration key.\n"
- "Error occurred near line 1, position 4: BOLa");
- bc_error_free(err);
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_config_no_key2(void **state)
-{
- const char *a = "BOLA";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
- assert_string_equal(err->msg,
- "Your last configuration key is missing ':' and the value\n"
- "Error occurred near line 1, position 5: BOLA");
- bc_error_free(err);
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_config_no_value(void **state)
-{
- // this is a special case, not an error
- const char *a = "BOLA:\r\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_non_null(source);
- assert_null(err);
- assert_string_equal(bc_trie_lookup(source, "BOLA"), "");
- assert_null(bc_trie_lookup(source, "TOCTREE"));
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_config_no_value2(void **state)
-{
- const char *a = "BOLA:";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_null(source);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
- assert_string_equal(err->msg,
- "Configuration value not provided for 'BOLA'.\n"
- "Error occurred near line 1, position 6: BOLA:");
- bc_error_free(err);
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_config_reserved_name(void **state)
-{
- const char *a = "FILENAME: asd\r\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_null(source);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
- assert_string_equal(err->msg,
- "'FILENAME' variable is forbidden in source files. It will be set "
- "for you by the compiler.");
- bc_error_free(err);
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_config_reserved_name2(void **state)
-{
- const char *a = "CONTENT: asd\r\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_null(source);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
- assert_string_equal(err->msg,
- "'CONTENT' variable is forbidden in source files. It will be set "
- "for you by the compiler.");
- bc_error_free(err);
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_config_reserved_name3(void **state)
-{
- const char *a = "DATE_FORMATTED: asd\r\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_null(source);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
- assert_string_equal(err->msg,
- "'DATE_FORMATTED' variable is forbidden in source files. It will be set "
- "for you by the compiler.");
- bc_error_free(err);
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_config_reserved_name4(void **state)
-{
- const char *a = "DATE_FIRST_FORMATTED: asd\r\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_null(source);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
- assert_string_equal(err->msg,
- "'DATE_FIRST_FORMATTED' variable is forbidden in source files. It will be set "
- "for you by the compiler.");
- bc_error_free(err);
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_config_reserved_name5(void **state)
-{
- const char *a = "DATE_LAST_FORMATTED: asd\r\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_null(source);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
- assert_string_equal(err->msg,
- "'DATE_LAST_FORMATTED' variable is forbidden in source files. It will be set "
- "for you by the compiler.");
- bc_error_free(err);
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_config_reserved_name6(void **state)
-{
- const char *a = "PAGE_FIRST: asd\r\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_null(source);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
- assert_string_equal(err->msg,
- "'PAGE_FIRST' variable is forbidden in source files. It will be set "
- "for you by the compiler.");
- bc_error_free(err);
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_config_reserved_name7(void **state)
-{
- const char *a = "PAGE_PREVIOUS: asd\r\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_null(source);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
- assert_string_equal(err->msg,
- "'PAGE_PREVIOUS' variable is forbidden in source files. It will be set "
- "for you by the compiler.");
- bc_error_free(err);
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_config_reserved_name8(void **state)
-{
- const char *a = "PAGE_CURRENT: asd\r\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_null(source);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
- assert_string_equal(err->msg,
- "'PAGE_CURRENT' variable is forbidden in source files. It will be set "
- "for you by the compiler.");
- bc_error_free(err);
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_config_reserved_name9(void **state)
-{
- const char *a = "PAGE_NEXT: asd\r\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_null(source);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
- assert_string_equal(err->msg,
- "'PAGE_NEXT' variable is forbidden in source files. It will be set "
- "for you by the compiler.");
- bc_error_free(err);
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_config_reserved_name10(void **state)
-{
- const char *a = "PAGE_LAST: asd\r\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_null(source);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
- assert_string_equal(err->msg,
- "'PAGE_LAST' variable is forbidden in source files. It will be set "
- "for you by the compiler.");
- bc_error_free(err);
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_config_reserved_name11(void **state)
-{
- const char *a = "BLOGC_VERSION: 1.0\r\n";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_null(source);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
- assert_string_equal(err->msg,
- "'BLOGC_VERSION' variable is forbidden in source files. It will be set "
- "for you by the compiler.");
- bc_error_free(err);
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_config_value_no_line_ending(void **state)
-{
- const char *a = "BOLA: asd";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_null(source);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
- assert_string_equal(err->msg,
- "No line ending after the configuration value for 'BOLA'.\n"
- "Error occurred near line 1, position 10: BOLA: asd");
- bc_error_free(err);
- bc_trie_free(source);
-}
-
-
-static void
-test_source_parse_invalid_separator(void **state)
-{
- const char *a = "BOLA: asd\n---#";
- bc_error_t *err = NULL;
- bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err);
- assert_null(source);
- assert_non_null(err);
- assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
- assert_string_equal(err->msg,
- "Invalid content separator. Must be more than one '-' characters.\n"
- "Error occurred near line 2, position 4: ---#");
- bc_error_free(err);
- bc_trie_free(source);
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_source_parse),
- cmocka_unit_test(test_source_parse_crlf),
- cmocka_unit_test(test_source_parse_with_spaces),
- cmocka_unit_test(test_source_parse_with_excerpt),
- cmocka_unit_test(test_source_parse_with_first_header),
- cmocka_unit_test(test_source_parse_with_description),
- cmocka_unit_test(test_source_parse_with_toctree),
- cmocka_unit_test(test_source_parse_with_toctree_noheader),
- cmocka_unit_test(test_source_parse_with_toctree_maxdepth1),
- cmocka_unit_test(test_source_parse_with_toctree_maxdepth_invalid),
- cmocka_unit_test(test_source_parse_config_empty),
- cmocka_unit_test(test_source_parse_config_invalid_key),
- cmocka_unit_test(test_source_parse_config_no_key),
- cmocka_unit_test(test_source_parse_config_no_key2),
- cmocka_unit_test(test_source_parse_config_no_value),
- cmocka_unit_test(test_source_parse_config_no_value2),
- cmocka_unit_test(test_source_parse_config_reserved_name),
- cmocka_unit_test(test_source_parse_config_reserved_name2),
- cmocka_unit_test(test_source_parse_config_reserved_name3),
- cmocka_unit_test(test_source_parse_config_reserved_name4),
- cmocka_unit_test(test_source_parse_config_reserved_name5),
- cmocka_unit_test(test_source_parse_config_reserved_name6),
- cmocka_unit_test(test_source_parse_config_reserved_name7),
- cmocka_unit_test(test_source_parse_config_reserved_name8),
- cmocka_unit_test(test_source_parse_config_reserved_name9),
- cmocka_unit_test(test_source_parse_config_reserved_name10),
- cmocka_unit_test(test_source_parse_config_reserved_name11),
- cmocka_unit_test(test_source_parse_config_value_no_line_ending),
- cmocka_unit_test(test_source_parse_invalid_separator),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/blogc/check_sysinfo.c b/tests/blogc/check_sysinfo.c
deleted file mode 100644
index 197092c..0000000
--- a/tests/blogc/check_sysinfo.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include "../../src/common/error.h"
-#include "../../src/common/utils.h"
-#include "../../src/blogc/sysinfo.h"
-
-#ifdef HAVE_SYSINFO_DATETIME
-#include <time.h>
-#endif
-
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-
-static struct hostent h = {
- .h_name = "bola.example.com",
-};
-
-struct hostent*
-__wrap_gethostbyname(const char *name)
-{
- if (0 == strcmp(name, "bola"))
- return &h;
- return NULL;
-}
-#endif
-
-
-#ifdef HAVE_SYSINFO_HOSTNAME
-int
-__wrap_gethostname(char *name, size_t len)
-{
- assert_int_equal(len, 1024);
- const char *f = mock_type(const char*);
- if (f != NULL)
- strcpy(name, f);
- return mock_type(int);
-}
-#endif
-
-
-char*
-__wrap_getenv(const char *name)
-{
- return mock_type(char*);
-}
-
-
-#ifdef HAVE_SYSINFO_DATETIME
-time_t
-__wrap_time(time_t *tloc)
-{
- *tloc = mock_type(time_t);
- return *tloc;
-}
-
-
-static struct tm tm = {
- .tm_sec = 1,
- .tm_min = 2,
- .tm_hour = 3,
- .tm_mday = 4,
- .tm_mon = 5,
- .tm_year = 6,
- .tm_wday = 6,
- .tm_yday = 7,
- .tm_isdst = 0,
-};
-
-struct tm*
-__wrap_gmtime(const time_t *timep)
-{
- if (*timep == 2)
- return NULL;
- return &tm;
-}
-#endif
-
-
-char*
-__wrap_bc_file_get_contents(const char *path, bool utf8, size_t *len, bc_error_t **err)
-{
- assert_string_equal(path, "/proc/1/cgroup");
- assert_false(utf8);
- char *rv = mock_type(char*);
- *len = strlen(rv);
- return rv;
-}
-
-
-static void
-test_sysinfo_get_hostname(void **state)
-{
- will_return(__wrap_gethostname, NULL);
- will_return(__wrap_gethostname, -1);
- char *f = blogc_sysinfo_get_hostname();
- assert_null(f);
-
- will_return(__wrap_gethostname, "bola");
- will_return(__wrap_gethostname, 0);
- f = blogc_sysinfo_get_hostname();
- assert_non_null(f);
- assert_string_equal(f, "bola.example.com");
- free(f);
-
- will_return(__wrap_gethostname, "guda");
- will_return(__wrap_gethostname, 0);
- f = blogc_sysinfo_get_hostname();
- assert_non_null(f);
- assert_string_equal(f, "guda");
- free(f);
-}
-
-
-static void
-test_sysinfo_inject_hostname(void **state)
-{
- bc_trie_t *t = bc_trie_new(free);
-
- will_return(__wrap_gethostname, NULL);
- will_return(__wrap_gethostname, -1);
- blogc_sysinfo_inject_hostname(t);
- assert_int_equal(bc_trie_size(t), 0);
-
- will_return(__wrap_gethostname, "bola");
- will_return(__wrap_gethostname, 0);
- blogc_sysinfo_inject_hostname(t);
- assert_int_equal(bc_trie_size(t), 1);
- assert_string_equal(bc_trie_lookup(t, "BLOGC_SYSINFO_HOSTNAME"), "bola.example.com");
- bc_trie_free(t);
-
- t = bc_trie_new(free);
- will_return(__wrap_gethostname, "guda");
- will_return(__wrap_gethostname, 0);
- blogc_sysinfo_inject_hostname(t);
- assert_int_equal(bc_trie_size(t), 1);
- assert_string_equal(bc_trie_lookup(t, "BLOGC_SYSINFO_HOSTNAME"), "guda");
- bc_trie_free(t);
-}
-
-
-static void
-test_sysinfo_get_username(void **state)
-{
- will_return(__wrap_getenv, NULL);
- char *f = blogc_sysinfo_get_username();
- assert_null(f);
-
- will_return(__wrap_getenv, "bola");
- f = blogc_sysinfo_get_username();
- assert_non_null(f);
- assert_string_equal(f, "bola");
- free(f);
-}
-
-
-static void
-test_sysinfo_inject_username(void **state)
-{
- bc_trie_t *t = bc_trie_new(free);
-
- will_return(__wrap_getenv, NULL);
- blogc_sysinfo_inject_username(t);
- assert_int_equal(bc_trie_size(t), 0);
-
- will_return(__wrap_getenv, "bola");
- blogc_sysinfo_inject_username(t);
- assert_int_equal(bc_trie_size(t), 1);
- assert_string_equal(bc_trie_lookup(t, "BLOGC_SYSINFO_USERNAME"), "bola");
- bc_trie_free(t);
-}
-
-
-static void
-test_sysinfo_get_datetime(void **state)
-{
- will_return(__wrap_time, -1);
- char *f = blogc_sysinfo_get_datetime();
- assert_null(f);
-
- will_return(__wrap_time, 2);
- f = blogc_sysinfo_get_datetime();
- assert_null(f);
-
- will_return(__wrap_time, 1);
- f = blogc_sysinfo_get_datetime();
- assert_non_null(f);
- assert_string_equal(f, "1906-06-04 03:02:01");
- free(f);
-}
-
-
-static void
-test_sysinfo_inject_datetime(void **state)
-{
- bc_trie_t *t = bc_trie_new(free);
-
- will_return(__wrap_time, -1);
- blogc_sysinfo_inject_datetime(t);
- assert_int_equal(bc_trie_size(t), 0);
-
- will_return(__wrap_time, 2);
- blogc_sysinfo_inject_datetime(t);
- assert_int_equal(bc_trie_size(t), 0);
-
- will_return(__wrap_time, 1);
- blogc_sysinfo_inject_datetime(t);
- assert_int_equal(bc_trie_size(t), 1);
- assert_string_equal(bc_trie_lookup(t, "BLOGC_SYSINFO_DATETIME"), "1906-06-04 03:02:01");
- bc_trie_free(t);
-}
-
-
-static void
-test_sysinfo_get_inside_docker(void **state)
-{
- // the "positive" case was already tested in check_funcvars. this is done
- // this way because this function caches the results in a global variable.
- will_return(__wrap_bc_file_get_contents, bc_strdup("bola"));
- assert_false(blogc_sysinfo_get_inside_docker());
-}
-
-
-// the blogc_sysinfo_inject_inside_docker() function was already indirectly
-// tested in check_funcvars.c
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
-
-#ifdef HAVE_SYSINFO_HOSTNAME
- cmocka_unit_test(test_sysinfo_get_hostname),
- cmocka_unit_test(test_sysinfo_inject_hostname),
-#endif
-
- cmocka_unit_test(test_sysinfo_get_username),
- cmocka_unit_test(test_sysinfo_inject_username),
-
-#ifdef HAVE_SYSINFO_DATETIME
- cmocka_unit_test(test_sysinfo_get_datetime),
- cmocka_unit_test(test_sysinfo_inject_datetime),
-#endif
-
- cmocka_unit_test(test_sysinfo_get_inside_docker),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/blogc/check_sysinfo2.c b/tests/blogc/check_sysinfo2.c
deleted file mode 100644
index 7dd440d..0000000
--- a/tests/blogc/check_sysinfo2.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include "../../src/common/error.h"
-#include "../../src/common/utils.h"
-#include "../../src/blogc/sysinfo.h"
-
-// this test exists because we can't test more than one return values for
-// blogc_sysinfo_get_inside_docker() in the same binary, because the results
-// are cached globally for performance.
-
-
-char*
-__wrap_bc_file_get_contents(const char *path, bool utf8, size_t *len, bc_error_t **err)
-{
- assert_string_equal(path, "/proc/1/cgroup");
- assert_false(utf8);
- *err = bc_error_new(0, "");
- return NULL;
-}
-
-
-static void
-test_sysinfo_get_inside_docker(void **state)
-{
- assert_false(blogc_sysinfo_get_inside_docker());
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_sysinfo_get_inside_docker),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/blogc/check_template_parser.c b/tests/blogc/check_template_parser.c
deleted file mode 100644
index ace8ac4..0000000
--- a/tests/blogc/check_template_parser.c
+++ /dev/null
@@ -1,1331 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#include <string.h>
-#include "../../src/common/error.h"
-#include "../../src/common/utils.h"
-#include "../../src/blogc/template-parser.h"
-
-
-static void
-blogc_assert_template_node(bc_slist_t *l, const char *data,
- const blogc_template_node_type_t type)
-{
- blogc_template_node_t *node = l->data;
- if (data == NULL)
- assert_null(node->data[0]);
- else
- assert_string_equal(node->data[0], data);
- assert_int_equal(node->type, type);
-}
-
-
-static void
-blogc_assert_template_if_node(bc_slist_t *l, const char *variable,
- blogc_template_operator_t operator, const char *operand)
-{
- blogc_template_node_t *node = l->data;
- assert_string_equal(node->data[0], variable);
- assert_int_equal(node->op, operator);
- assert_string_equal(node->data[1], operand);
- assert_int_equal(node->type, BLOGC_TEMPLATE_NODE_IF);
-}
-
-
-static void
-test_template_parse(void **state)
-{
- const char *a =
- "Test\n"
- "\n"
- " {%- block entry -%}\n"
- "{% ifdef CHUNDA %}\n"
- "bola\n"
- "{% endif %}\n"
- "{% ifndef BOLA %}\n"
- "bolao\n"
- "{%- endif %}\n"
- "{% endblock %}\n"
- "{% block listing %}{{ BOLA }}{% endblock %}\n"
- "{% block listing_once %}asd{% endblock %}\n"
- "{%- foreach BOLA %}hahaha{% endforeach %}\n"
- "{% if BOLA == \"1\\\"0\" %}aee{% else %}fffuuuuuuu{% endif %}\n"
- "{% block listing_entry %}lol{% endblock %}\n"
- "{% block listing_empty %}empty{% endblock %}";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_null(err);
- assert_non_null(ast);
- blogc_assert_template_node(ast, "Test",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(ast->next, "entry",
- BLOGC_TEMPLATE_NODE_BLOCK);
- blogc_assert_template_node(ast->next->next, "",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(ast->next->next->next, "CHUNDA",
- BLOGC_TEMPLATE_NODE_IFDEF);
- blogc_assert_template_node(ast->next->next->next->next, "\nbola\n",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(ast->next->next->next->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ENDIF);
- blogc_assert_template_node(ast->next->next->next->next->next->next, "\n",
- BLOGC_TEMPLATE_NODE_CONTENT);
- bc_slist_t *tmp = ast->next->next->next->next->next->next->next;
- blogc_assert_template_node(tmp, "BOLA", BLOGC_TEMPLATE_NODE_IFNDEF);
- blogc_assert_template_node(tmp->next, "\nbolao", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next, NULL, BLOGC_TEMPLATE_NODE_ENDIF);
- blogc_assert_template_node(tmp->next->next->next, "\n",
- BLOGC_TEMPLATE_NODE_CONTENT);
- tmp = tmp->next->next->next->next;
- blogc_assert_template_node(tmp, NULL, BLOGC_TEMPLATE_NODE_ENDBLOCK);
- blogc_assert_template_node(tmp->next, "\n", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next, "listing",
- BLOGC_TEMPLATE_NODE_BLOCK);
- blogc_assert_template_node(tmp->next->next->next, "BOLA",
- BLOGC_TEMPLATE_NODE_VARIABLE);
- blogc_assert_template_node(tmp->next->next->next->next,
- NULL, BLOGC_TEMPLATE_NODE_ENDBLOCK);
- blogc_assert_template_node(tmp->next->next->next->next->next, "\n",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next->next,
- "listing_once", BLOGC_TEMPLATE_NODE_BLOCK);
- blogc_assert_template_node(tmp->next->next->next->next->next->next->next,
- "asd", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next->next->next->next,
- NULL, BLOGC_TEMPLATE_NODE_ENDBLOCK);
- blogc_assert_template_node(tmp->next->next->next->next->next->next->next->next->next,
- "", BLOGC_TEMPLATE_NODE_CONTENT);
- tmp = tmp->next->next->next->next->next->next->next->next->next->next;
- blogc_assert_template_node(tmp, "BOLA", BLOGC_TEMPLATE_NODE_FOREACH);
- blogc_assert_template_node(tmp->next, "hahaha",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ENDFOREACH);
- blogc_assert_template_node(tmp->next->next->next, "\n",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_if_node(tmp->next->next->next->next, "BOLA",
- BLOGC_TEMPLATE_OP_EQ, "\"1\\\"0\"");
- blogc_assert_template_node(tmp->next->next->next->next->next, "aee",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ELSE);
- blogc_assert_template_node(tmp->next->next->next->next->next->next->next,
- "fffuuuuuuu", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next->next->next->next,
- NULL, BLOGC_TEMPLATE_NODE_ENDIF);
- tmp = tmp->next->next->next->next->next->next->next->next->next;
- blogc_assert_template_node(tmp, "\n", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next, "listing_entry", BLOGC_TEMPLATE_NODE_BLOCK);
- blogc_assert_template_node(tmp->next->next, "lol", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ENDBLOCK);
- blogc_assert_template_node(tmp->next->next->next->next, "\n",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next, "listing_empty",
- BLOGC_TEMPLATE_NODE_BLOCK);
- blogc_assert_template_node(tmp->next->next->next->next->next->next, "empty",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ENDBLOCK);
- assert_null(tmp->next->next->next->next->next->next->next->next);
- blogc_template_free_ast(ast);
-}
-
-
-static void
-test_template_parse_crlf(void **state)
-{
- const char *a =
- "Test\r\n"
- "\r\n"
- " {%- block entry -%}\r\n"
- "{% ifdef CHUNDA %}\r\n"
- "bola\r\n"
- "{% endif %}\r\n"
- "{% ifndef BOLA %}\r\n"
- "bolao\r\n"
- "{%- endif %}\r\n"
- "{% endblock %}\r\n"
- "{% block listing %}{{ BOLA }}{% endblock %}\r\n"
- "{% block listing_once %}asd{% endblock %}\r\n"
- "{%- foreach BOLA %}hahaha{% endforeach %}\r\n"
- "{% if BOLA == \"1\\\"0\" %}aee{% else %}fffuuuuuuu{% endif %}";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_null(err);
- assert_non_null(ast);
- blogc_assert_template_node(ast, "Test",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(ast->next, "entry",
- BLOGC_TEMPLATE_NODE_BLOCK);
- blogc_assert_template_node(ast->next->next, "",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(ast->next->next->next, "CHUNDA",
- BLOGC_TEMPLATE_NODE_IFDEF);
- blogc_assert_template_node(ast->next->next->next->next, "\r\nbola\r\n",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(ast->next->next->next->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ENDIF);
- blogc_assert_template_node(ast->next->next->next->next->next->next, "\r\n",
- BLOGC_TEMPLATE_NODE_CONTENT);
- bc_slist_t *tmp = ast->next->next->next->next->next->next->next;
- blogc_assert_template_node(tmp, "BOLA", BLOGC_TEMPLATE_NODE_IFNDEF);
- blogc_assert_template_node(tmp->next, "\r\nbolao", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next, NULL, BLOGC_TEMPLATE_NODE_ENDIF);
- blogc_assert_template_node(tmp->next->next->next, "\r\n",
- BLOGC_TEMPLATE_NODE_CONTENT);
- tmp = tmp->next->next->next->next;
- blogc_assert_template_node(tmp, NULL, BLOGC_TEMPLATE_NODE_ENDBLOCK);
- blogc_assert_template_node(tmp->next, "\r\n", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next, "listing",
- BLOGC_TEMPLATE_NODE_BLOCK);
- blogc_assert_template_node(tmp->next->next->next, "BOLA",
- BLOGC_TEMPLATE_NODE_VARIABLE);
- blogc_assert_template_node(tmp->next->next->next->next,
- NULL, BLOGC_TEMPLATE_NODE_ENDBLOCK);
- blogc_assert_template_node(tmp->next->next->next->next->next, "\r\n",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next->next,
- "listing_once", BLOGC_TEMPLATE_NODE_BLOCK);
- blogc_assert_template_node(tmp->next->next->next->next->next->next->next,
- "asd", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next->next->next->next,
- NULL, BLOGC_TEMPLATE_NODE_ENDBLOCK);
- blogc_assert_template_node(tmp->next->next->next->next->next->next->next->next->next,
- "", BLOGC_TEMPLATE_NODE_CONTENT);
- tmp = tmp->next->next->next->next->next->next->next->next->next->next;
- blogc_assert_template_node(tmp, "BOLA", BLOGC_TEMPLATE_NODE_FOREACH);
- blogc_assert_template_node(tmp->next, "hahaha",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ENDFOREACH);
- blogc_assert_template_node(tmp->next->next->next, "\r\n",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_if_node(tmp->next->next->next->next, "BOLA",
- BLOGC_TEMPLATE_OP_EQ, "\"1\\\"0\"");
- blogc_assert_template_node(tmp->next->next->next->next->next, "aee",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ELSE);
- blogc_assert_template_node(tmp->next->next->next->next->next->next->next,
- "fffuuuuuuu", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next->next->next->next,
- NULL, BLOGC_TEMPLATE_NODE_ENDIF);
- assert_null(tmp->next->next->next->next->next->next->next->next->next);
- blogc_template_free_ast(ast);
-}
-
-
-static void
-test_template_parse_html(void **state)
-{
- const char *a =
- "<html>\n"
- " <head>\n"
- " {% block entry %}\n"
- " <title>My cool blog >> {{ TITLE }}</title>\n"
- " {% endblock %}\n"
- " {% block listing_once %}\n"
- " <title>My cool blog - Main page</title>\n"
- " {% endblock %}\n"
- " </head>\n"
- " <body>\n"
- " <h1>My cool blog</h1>\n"
- " {% block entry %}\n"
- " <h2>{{ TITLE }}</h2>\n"
- " {% ifdef DATE %}<h4>Published in: {{ DATE }}</h4>{% endif %}\n"
- " <pre>{{ CONTENT }}</pre>\n"
- " {% endblock %}\n"
- " {% block listing_once %}<ul>{% endblock %}\n"
- " {% block listing %}<p><a href=\"{{ FILENAME }}.html\">"
- "{{ TITLE }}</a>{% ifdef DATE %} - {{ DATE }}{% endif %}</p>{% endblock %}\n"
- " {% block listing_once %}</ul>{% endblock %}\n"
- " </body>\n"
- "</html>\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_null(err);
- assert_non_null(ast);
- blogc_assert_template_node(ast, "<html>\n <head>\n ",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(ast->next, "entry",
- BLOGC_TEMPLATE_NODE_BLOCK);
- blogc_assert_template_node(ast->next->next,
- "\n <title>My cool blog >> ", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(ast->next->next->next, "TITLE",
- BLOGC_TEMPLATE_NODE_VARIABLE);
- blogc_assert_template_node(ast->next->next->next->next,
- "</title>\n ", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(ast->next->next->next->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ENDBLOCK);
- blogc_assert_template_node(ast->next->next->next->next->next->next,
- "\n ", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(ast->next->next->next->next->next->next->next,
- "listing_once", BLOGC_TEMPLATE_NODE_BLOCK);
- bc_slist_t *tmp = ast->next->next->next->next->next->next->next->next;
- blogc_assert_template_node(tmp,
- "\n <title>My cool blog - Main page</title>\n ",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next, NULL, BLOGC_TEMPLATE_NODE_ENDBLOCK);
- blogc_assert_template_node(tmp->next->next,
- "\n </head>\n <body>\n <h1>My cool blog</h1>\n ",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next, "entry",
- BLOGC_TEMPLATE_NODE_BLOCK);
- blogc_assert_template_node(tmp->next->next->next->next,
- "\n <h2>", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next,
- "TITLE", BLOGC_TEMPLATE_NODE_VARIABLE);
- blogc_assert_template_node(tmp->next->next->next->next->next->next,
- "</h2>\n ", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next->next->next,
- "DATE", BLOGC_TEMPLATE_NODE_IFDEF);
- tmp = tmp->next->next->next->next->next->next->next->next;
- blogc_assert_template_node(tmp, "<h4>Published in: ",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next, "DATE", BLOGC_TEMPLATE_NODE_VARIABLE);
- blogc_assert_template_node(tmp->next->next, "</h4>",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ENDIF);
- blogc_assert_template_node(tmp->next->next->next->next, "\n <pre>",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next,
- "CONTENT", BLOGC_TEMPLATE_NODE_VARIABLE);
- blogc_assert_template_node(tmp->next->next->next->next->next->next,
- "</pre>\n ", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next->next->next,
- NULL, BLOGC_TEMPLATE_NODE_ENDBLOCK);
- tmp = tmp->next->next->next->next->next->next->next->next;
- blogc_assert_template_node(tmp, "\n ", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next, "listing_once",
- BLOGC_TEMPLATE_NODE_BLOCK);
- blogc_assert_template_node(tmp->next->next, "<ul>",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ENDBLOCK);
- blogc_assert_template_node(tmp->next->next->next->next, "\n ",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next,
- "listing", BLOGC_TEMPLATE_NODE_BLOCK);
- blogc_assert_template_node(tmp->next->next->next->next->next->next,
- "<p><a href=\"", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next->next->next,
- "FILENAME", BLOGC_TEMPLATE_NODE_VARIABLE);
- tmp = tmp->next->next->next->next->next->next->next->next;
- blogc_assert_template_node(tmp, ".html\">", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next, "TITLE",
- BLOGC_TEMPLATE_NODE_VARIABLE);
- blogc_assert_template_node(tmp->next->next, "</a>",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next, "DATE",
- BLOGC_TEMPLATE_NODE_IFDEF);
- blogc_assert_template_node(tmp->next->next->next->next, " - ",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next, "DATE",
- BLOGC_TEMPLATE_NODE_VARIABLE);
- blogc_assert_template_node(tmp->next->next->next->next->next->next,
- NULL, BLOGC_TEMPLATE_NODE_ENDIF);
- blogc_assert_template_node(tmp->next->next->next->next->next->next->next,
- "</p>", BLOGC_TEMPLATE_NODE_CONTENT);
- tmp = tmp->next->next->next->next->next->next->next->next;
- blogc_assert_template_node(tmp, NULL, BLOGC_TEMPLATE_NODE_ENDBLOCK);
- blogc_assert_template_node(tmp->next, "\n ",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next, "listing_once",
- BLOGC_TEMPLATE_NODE_BLOCK);
- blogc_assert_template_node(tmp->next->next->next, "</ul>",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ENDBLOCK);
- blogc_assert_template_node(tmp->next->next->next->next->next,
- "\n </body>\n</html>\n", BLOGC_TEMPLATE_NODE_CONTENT);
- assert_null(tmp->next->next->next->next->next->next);
- blogc_template_free_ast(ast);
-}
-
-
-static void
-test_template_parse_html_whitespace(void **state)
-{
- const char *a =
- "<html>\n"
- " <head>\n"
- " {%\n block entry\n%}\n"
- " <title>My cool blog >> {{ TITLE }}</title>\n"
- " {% \vendblock\v %}\n"
- " {% \r\nblock listing_once\n%}\n"
- " <title>My cool blog - Main page</title>\n"
- " {%\t endblock\t%}\n"
- " </head>\n"
- " <body>\n"
- " <h1>My cool blog</h1>\n"
- " {%\t\t\tblock entry\n%}\n"
- " <h2>{{\tTITLE\n}}</h2>\n"
- " {%\nifdef DATE\v%}<h4>Published in: {{\tDATE\t}}</h4>{%\fendif\f%}\n"
- " <pre>{{\tCONTENT\n}}</pre>\n"
- " {%\n\n \nendblock\f\f\n\t%}\n"
- " {%\nblock\n\nlisting_once\t%}<ul>{%\tendblock\f\f%}\n"
- " {%\n\nblock\t\tlisting\f\t%}<p><a href=\"{{\t\fFILENAME\t\t}}.html\">"
- "{{ TITLE }}</a>{%\f\tifdef\v\vDATE\f%} - {{\fDATE\f}}{%\tendif\f%}</p>{%\tendblock\t%}\n"
- " {%\tblock\tlisting_once\t%}</ul>{%\nendblock\n%}\n"
- " </body>\n"
- "</html>\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_null(err);
- assert_non_null(ast);
- blogc_assert_template_node(ast, "<html>\n <head>\n ",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(ast->next, "entry",
- BLOGC_TEMPLATE_NODE_BLOCK);
- blogc_assert_template_node(ast->next->next,
- "\n <title>My cool blog >> ", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(ast->next->next->next, "TITLE",
- BLOGC_TEMPLATE_NODE_VARIABLE);
- blogc_assert_template_node(ast->next->next->next->next,
- "</title>\n ", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(ast->next->next->next->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ENDBLOCK);
- blogc_assert_template_node(ast->next->next->next->next->next->next,
- "\n ", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(ast->next->next->next->next->next->next->next,
- "listing_once", BLOGC_TEMPLATE_NODE_BLOCK);
- bc_slist_t *tmp = ast->next->next->next->next->next->next->next->next;
- blogc_assert_template_node(tmp,
- "\n <title>My cool blog - Main page</title>\n ",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next, NULL, BLOGC_TEMPLATE_NODE_ENDBLOCK);
- blogc_assert_template_node(tmp->next->next,
- "\n </head>\n <body>\n <h1>My cool blog</h1>\n ",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next, "entry",
- BLOGC_TEMPLATE_NODE_BLOCK);
- blogc_assert_template_node(tmp->next->next->next->next,
- "\n <h2>", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next,
- "TITLE", BLOGC_TEMPLATE_NODE_VARIABLE);
- blogc_assert_template_node(tmp->next->next->next->next->next->next,
- "</h2>\n ", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next->next->next,
- "DATE", BLOGC_TEMPLATE_NODE_IFDEF);
- tmp = tmp->next->next->next->next->next->next->next->next;
- blogc_assert_template_node(tmp, "<h4>Published in: ",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next, "DATE", BLOGC_TEMPLATE_NODE_VARIABLE);
- blogc_assert_template_node(tmp->next->next, "</h4>",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ENDIF);
- blogc_assert_template_node(tmp->next->next->next->next, "\n <pre>",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next,
- "CONTENT", BLOGC_TEMPLATE_NODE_VARIABLE);
- blogc_assert_template_node(tmp->next->next->next->next->next->next,
- "</pre>\n ", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next->next->next,
- NULL, BLOGC_TEMPLATE_NODE_ENDBLOCK);
- tmp = tmp->next->next->next->next->next->next->next->next;
- blogc_assert_template_node(tmp, "\n ", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next, "listing_once",
- BLOGC_TEMPLATE_NODE_BLOCK);
- blogc_assert_template_node(tmp->next->next, "<ul>",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ENDBLOCK);
- blogc_assert_template_node(tmp->next->next->next->next, "\n ",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next,
- "listing", BLOGC_TEMPLATE_NODE_BLOCK);
- blogc_assert_template_node(tmp->next->next->next->next->next->next,
- "<p><a href=\"", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next->next->next,
- "FILENAME", BLOGC_TEMPLATE_NODE_VARIABLE);
- tmp = tmp->next->next->next->next->next->next->next->next;
- blogc_assert_template_node(tmp, ".html\">", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next, "TITLE",
- BLOGC_TEMPLATE_NODE_VARIABLE);
- blogc_assert_template_node(tmp->next->next, "</a>",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next, "DATE",
- BLOGC_TEMPLATE_NODE_IFDEF);
- blogc_assert_template_node(tmp->next->next->next->next, " - ",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next, "DATE",
- BLOGC_TEMPLATE_NODE_VARIABLE);
- blogc_assert_template_node(tmp->next->next->next->next->next->next,
- NULL, BLOGC_TEMPLATE_NODE_ENDIF);
- blogc_assert_template_node(tmp->next->next->next->next->next->next->next,
- "</p>", BLOGC_TEMPLATE_NODE_CONTENT);
- tmp = tmp->next->next->next->next->next->next->next->next;
- blogc_assert_template_node(tmp, NULL, BLOGC_TEMPLATE_NODE_ENDBLOCK);
- blogc_assert_template_node(tmp->next, "\n ",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next, "listing_once",
- BLOGC_TEMPLATE_NODE_BLOCK);
- blogc_assert_template_node(tmp->next->next->next, "</ul>",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ENDBLOCK);
- blogc_assert_template_node(tmp->next->next->next->next->next,
- "\n </body>\n</html>\n", BLOGC_TEMPLATE_NODE_CONTENT);
- assert_null(tmp->next->next->next->next->next->next);
- blogc_template_free_ast(ast);
-}
-
-
-static void
-test_template_parse_ifdef_and_var_outside_block(void **state)
-{
- const char *a =
- "{% ifdef GUDA %}bola{% endif %}\n"
- "{{ BOLA }}\n"
- "{% ifndef CHUNDA %}{{ CHUNDA }}{% endif %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_null(err);
- assert_non_null(ast);
- blogc_assert_template_node(ast, "GUDA", BLOGC_TEMPLATE_NODE_IFDEF);
- blogc_assert_template_node(ast->next, "bola",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(ast->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ENDIF);
- blogc_assert_template_node(ast->next->next->next, "\n",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(ast->next->next->next->next, "BOLA",
- BLOGC_TEMPLATE_NODE_VARIABLE);
- blogc_assert_template_node(ast->next->next->next->next->next, "\n",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(ast->next->next->next->next->next->next,
- "CHUNDA", BLOGC_TEMPLATE_NODE_IFNDEF);
- bc_slist_t *tmp = ast->next->next->next->next->next->next->next;
- blogc_assert_template_node(tmp, "CHUNDA", BLOGC_TEMPLATE_NODE_VARIABLE);
- blogc_assert_template_node(tmp->next, NULL, BLOGC_TEMPLATE_NODE_ENDIF);
- blogc_assert_template_node(tmp->next->next, "\n",
- BLOGC_TEMPLATE_NODE_CONTENT);
- assert_null(tmp->next->next->next);
- blogc_template_free_ast(ast);
-}
-
-
-static void
-test_template_parse_nested_else(void **state)
-{
- const char *a =
- "{% ifdef GUDA %}\n"
- "{% ifdef BOLA %}\n"
- "asd\n"
- "{% else %}\n"
- "{% ifdef CHUNDA %}\n"
- "qwe\n"
- "{% else %}\n"
- "rty\n"
- "{% endif %}\n"
- "{% endif %}\n"
- "{% ifdef LOL %}\n"
- "zxc\n"
- "{% else %}\n"
- "bnm\n"
- "{% endif %}\n"
- "{% endif %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_null(err);
- assert_non_null(ast);
- blogc_assert_template_node(ast, "GUDA", BLOGC_TEMPLATE_NODE_IFDEF);
- blogc_assert_template_node(ast->next, "\n", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(ast->next->next, "BOLA", BLOGC_TEMPLATE_NODE_IFDEF);
- blogc_assert_template_node(ast->next->next->next, "\nasd\n",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(ast->next->next->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ELSE);
- blogc_assert_template_node(ast->next->next->next->next->next, "\n",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(ast->next->next->next->next->next->next,
- "CHUNDA", BLOGC_TEMPLATE_NODE_IFDEF);
- blogc_assert_template_node(ast->next->next->next->next->next->next->next,
- "\nqwe\n", BLOGC_TEMPLATE_NODE_CONTENT);
- bc_slist_t *tmp = ast->next->next->next->next->next->next->next->next;
- blogc_assert_template_node(tmp, NULL, BLOGC_TEMPLATE_NODE_ELSE);
- blogc_assert_template_node(tmp->next, "\nrty\n", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ENDIF);
- blogc_assert_template_node(tmp->next->next->next, "\n",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ENDIF);
- blogc_assert_template_node(tmp->next->next->next->next->next, "\n",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next->next->next,
- "LOL", BLOGC_TEMPLATE_NODE_IFDEF);
- blogc_assert_template_node(tmp->next->next->next->next->next->next->next,
- "\nzxc\n", BLOGC_TEMPLATE_NODE_CONTENT);
- tmp = tmp->next->next->next->next->next->next->next->next;
- blogc_assert_template_node(tmp, NULL, BLOGC_TEMPLATE_NODE_ELSE);
- blogc_assert_template_node(tmp->next, "\nbnm\n", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ENDIF);
- blogc_assert_template_node(tmp->next->next->next, "\n",
- BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next->next, NULL,
- BLOGC_TEMPLATE_NODE_ENDIF);
- blogc_assert_template_node(tmp->next->next->next->next->next, "\n",
- BLOGC_TEMPLATE_NODE_CONTENT);
- assert_null(tmp->next->next->next->next->next->next);
- blogc_template_free_ast(ast);
-}
-
-
-static void
-test_template_parse_invalid_block_start(void **state)
-{
- const char *a = "{% ASD %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid statement syntax. Must begin with lowercase letter.\n"
- "Error occurred near line 1, position 4: {% ASD %}");
- bc_error_free(err);
- a = "{%-- block entry %}\n";
- err = NULL;
- ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid statement syntax. Duplicated whitespace cleaner before statement.\n"
- "Error occurred near line 1, position 4: {%-- block entry %}");
- bc_error_free(err);
- a = "{% block entry --%}\n";
- err = NULL;
- ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid statement syntax. Duplicated whitespace cleaner after statement.\n"
- "Error occurred near line 1, position 17: {% block entry --%}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_block_nested(void **state)
-{
- const char *a =
- "{% block entry %}\n"
- "{% block listing %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Blocks can't be nested.\n"
- "Error occurred near line 2, position 9: {% block listing %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_foreach_nested(void **state)
-{
- const char *a =
- "{% foreach A %}\n"
- "{% foreach B %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "'foreach' statements can't be nested.\n"
- "Error occurred near line 2, position 11: {% foreach B %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_block_not_open(void **state)
-{
- const char *a = "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "'endblock' statement without an open 'block' statement.\n"
- "Error occurred near line 1, position 12: {% endblock %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_endif_not_open(void **state)
-{
- const char *a = "{% block listing %}{% endif %}{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "'endif' statement without an open 'if', 'ifdef' or 'ifndef' statement.\n"
- "Error occurred near line 1, position 28: "
- "{% block listing %}{% endif %}{% endblock %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_endif_not_open_inside_block(void **state)
-{
- const char *a = "{% ifdef BOLA %}{% block listing %}{% endif %}{% endblock %}";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "'endif' statement without an open 'if', 'ifdef' or 'ifndef' statement.\n"
- "Error occurred near line 1, position 44: {% ifdef BOLA %}{% block "
- "listing %}{% endif %}{% endblock %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_else_not_open_inside_block(void **state)
-{
- const char *a = "{% ifdef BOLA %}{% block listing %}{% else %}{% endif %}{% endblock %}";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "'else' statement without an open 'if', 'ifdef' or 'ifndef' statement.\n"
- "Error occurred near line 1, position 43: {% ifdef BOLA %}"
- "{% block listing %}{% else %}{% endif %}{% endblock %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_endforeach_not_open(void **state)
-{
- const char *a = "{% endforeach %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "'endforeach' statement without an open 'foreach' statement.\n"
- "Error occurred near line 1, position 14: {% endforeach %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_endforeach_not_open_inside_block(void **state)
-{
- const char *a = "{% foreach TAGS %}{% block entry %}{% endforeach %}"
- "{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "'endforeach' statement without an open 'foreach' statement.\n"
- "Error occurred near line 1, position 49: {% foreach TAGS %}"
- "{% block entry %}{% endforeach %}{% endblock %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_endforeach_not_open_inside_block2(void **state)
-{
- const char *a = "{% block entry %}{% foreach TAGS %}"
- "{% endforeach %}{% endforeach %}{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "'endforeach' statement without an open 'foreach' statement.\n"
- "Error occurred near line 1, position 65: {% block entry %}"
- "{% foreach TAGS %}{% endforeach %}{% endforeach %}{% endblock %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_endforeach_not_closed_inside_block(void **state)
-{
- const char *a = "{% block entry %}{% foreach TAGS %}{% endblock %}"
- "{% endforeach %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "An open 'foreach' statement was not closed inside a 'entry' block!");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_endforeach_not_closed_inside_block2(void **state)
-{
- const char *a = "{% block entry %}{% foreach TAGS %}{% endforeach %}"
- "{% foreach TAGS %}{% endblock %}{% endforeach %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "An open 'foreach' statement was not closed inside a 'entry' block!");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_block_name(void **state)
-{
- const char *a = "{% chunda %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid statement type: Allowed types are: 'block', 'endblock', 'if', "
- "'ifdef', 'ifndef', 'else', 'endif', 'foreach' and 'endforeach'.\n"
- "Error occurred near line 1, position 10: {% chunda %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_block_type_start(void **state)
-{
- const char *a = "{% block ENTRY %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid block syntax. Must begin with lowercase letter.\n"
- "Error occurred near line 1, position 10: {% block ENTRY %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_block_type(void **state)
-{
- const char *a = "{% block chunda %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid block type. Allowed types are: 'entry', 'listing', 'listing_once', "
- "'listing_empty' and 'listing_entry'.\n"
- "Error occurred near line 1, position 16: {% block chunda %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_ifdef_start(void **state)
-{
- const char *a = "{% block entry %}{% ifdef guda %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid variable name. Must begin with uppercase letter.\n"
- "Error occurred near line 1, position 27: "
- "{% block entry %}{% ifdef guda %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_foreach_start(void **state)
-{
- const char *a = "{% block entry %}{% foreach guda %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid foreach variable name. Must begin with uppercase letter.\n"
- "Error occurred near line 1, position 29: "
- "{% block entry %}{% foreach guda %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_ifdef_variable(void **state)
-{
- const char *a = "{% block entry %}{% ifdef BoLA %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid variable name. Must be uppercase letter, number or '_'.\n"
- "Error occurred near line 1, position 28: "
- "{% block entry %}{% ifdef BoLA %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_ifdef_variable2(void **state)
-{
- const char *a = "{% block entry %}{% ifdef 0123 %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid variable name. Must begin with uppercase letter.\n"
- "Error occurred near line 1, position 27: "
- "{% block entry %}{% ifdef 0123 %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_foreach_variable(void **state)
-{
- const char *a = "{% block entry %}{% foreach BoLA %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid foreach variable name. Must be uppercase letter, number or '_'.\n"
- "Error occurred near line 1, position 30: "
- "{% block entry %}{% foreach BoLA %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_foreach_variable2(void **state)
-{
- const char *a = "{% block entry %}{% foreach 0123 %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid foreach variable name. Must begin with uppercase letter.\n"
- "Error occurred near line 1, position 29: {% block entry %}"
- "{% foreach 0123 %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_if_operator(void **state)
-{
- const char *a = "{% block entry %}{% if BOLA = \"asd\" %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid 'if' operator. Must be '<', '>', '<=', '>=', '==' or '!='.\n"
- "Error occurred near line 1, position 29: "
- "{% block entry %}{% if BOLA = \"asd\" %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_if_operand(void **state)
-{
- const char *a = "{% block entry %}{% if BOLA == asd %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid 'if' operand. Must be double-quoted static string or variable.\n"
- "Error occurred near line 1, position 32: "
- "{% block entry %}{% if BOLA == asd %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_if_operand2(void **state)
-{
- const char *a = "{% block entry %}{% if BOLA == \"asd %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Found an open double-quoted string.\n"
- "Error occurred near line 1, position 32: "
- "{% block entry %}{% if BOLA == \"asd %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_if_operand3(void **state)
-{
- const char *a = "{% block entry %}{% if BOLA == 0123 %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid 'if' operand. Must be double-quoted static string or variable.\n"
- "Error occurred near line 1, position 32: "
- "{% block entry %}{% if BOLA == 0123 %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_else1(void **state)
-{
- const char *a = "{% else %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "'else' statement without an open 'if', 'ifdef' or 'ifndef' statement.\n"
- "Error occurred near line 1, position 8: {% else %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_else2(void **state)
-{
- const char *a = "{% if BOLA == \"123\" %}{% if GUDA == \"1\" %}{% else %}{% else %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "More than one 'else' statement for an open 'if', 'ifdef' or 'ifndef' "
- "statement.\nError occurred near line 1, position 60: {% if BOLA == \"123\" "
- "%}{% if GUDA == \"1\" %}{% else %}{% else %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_else3(void **state)
-{
- const char *a =
- "{% if BOLA == \"123\" %}\n"
- "{% if GUDA == \"1\" %}\n"
- "{% else %}\n"
- "asd\n"
- "{% endif %}\n"
- "{% else %}\n"
- "{% else %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "More than one 'else' statement for an open 'if', 'ifdef' or 'ifndef' "
- "statement.\nError occurred near line 7, position 8: {% else %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_block_end(void **state)
-{
- const char *a = "{% block entry }}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid statement syntax. Must end with '%}'.\n"
- "Error occurred near line 1, position 16: {% block entry }}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_variable_name(void **state)
-{
- const char *a = "{% block entry %}{{ bola }}{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid variable name. Must begin with uppercase letter.\n"
- "Error occurred near line 1, position 21: "
- "{% block entry %}{{ bola }}{% endblock %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_variable_name2(void **state)
-{
- const char *a = "{% block entry %}{{ Bola }}{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid variable name. Must be uppercase letter, number or '_'.\n"
- "Error occurred near line 1, position 22: "
- "{% block entry %}{{ Bola }}{% endblock %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_variable_name3(void **state)
-{
- const char *a = "{% block entry %}{{ 0123 }}{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid variable name. Must begin with uppercase letter.\n"
- "Error occurred near line 1, position 21: {% block entry %}{{ 0123 }}"
- "{% endblock %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_variable_end(void **state)
-{
- const char *a = "{% block entry %}{{ BOLA %}{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid statement syntax. Must end with '}}'.\n"
- "Error occurred near line 1, position 26: "
- "{% block entry %}{{ BOLA %}{% endblock %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_close(void **state)
-{
- const char *a = "{% block entry %%\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid statement syntax. Must end with '}'.\n"
- "Error occurred near line 1, position 17: {% block entry %%");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_close2(void **state)
-{
- const char *a = "{% block entry %}{{ BOLA }%{% endblock %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "Invalid statement syntax. Must end with '}'.\n"
- "Error occurred near line 1, position 27: "
- "{% block entry %}{{ BOLA }%{% endblock %}");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_endif_not_closed(void **state)
-{
- const char *a = "{% block entry %}{% endblock %}{% ifdef BOLA %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg, "1 open 'if', 'ifdef' and/or 'ifndef' statements "
- "were not closed!");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_endif_not_closed_inside_block(void **state)
-{
- const char *a = "{% block listing %}{% ifdef BOLA %}{% endblock %}{% endif %}";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "1 open 'if', 'ifdef' and/or 'ifndef' statements were not closed inside "
- "a 'listing' block!");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_else_not_closed_inside_block(void **state)
-{
- const char *a = "{% block listing %}{% ifdef BOLA %}{% else %}{% endblock %}{% endif %}";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg,
- "1 open 'if', 'ifdef' and/or 'ifndef' statements were not closed inside "
- "a 'listing' block!");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_block_not_closed(void **state)
-{
- const char *a = "{% block entry %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg, "An open block was not closed!");
- bc_error_free(err);
-}
-
-
-static void
-test_template_parse_invalid_foreach_not_closed(void **state)
-{
- const char *a = "{% foreach ASD %}\n";
- bc_error_t *err = NULL;
- bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
- assert_non_null(err);
- assert_null(ast);
- assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
- assert_string_equal(err->msg, "An open 'foreach' statement was not closed!");
- bc_error_free(err);
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_template_parse),
- cmocka_unit_test(test_template_parse_crlf),
- cmocka_unit_test(test_template_parse_html),
- cmocka_unit_test(test_template_parse_html_whitespace),
- cmocka_unit_test(test_template_parse_ifdef_and_var_outside_block),
- cmocka_unit_test(test_template_parse_nested_else),
- cmocka_unit_test(test_template_parse_invalid_block_start),
- cmocka_unit_test(test_template_parse_invalid_block_nested),
- cmocka_unit_test(test_template_parse_invalid_foreach_nested),
- cmocka_unit_test(test_template_parse_invalid_block_not_open),
- cmocka_unit_test(test_template_parse_invalid_endif_not_open),
- cmocka_unit_test(test_template_parse_invalid_endif_not_open_inside_block),
- cmocka_unit_test(test_template_parse_invalid_else_not_open_inside_block),
- cmocka_unit_test(test_template_parse_invalid_endforeach_not_open),
- cmocka_unit_test(test_template_parse_invalid_endforeach_not_open_inside_block),
- cmocka_unit_test(test_template_parse_invalid_endforeach_not_open_inside_block2),
- cmocka_unit_test(test_template_parse_invalid_endforeach_not_closed_inside_block),
- cmocka_unit_test(test_template_parse_invalid_endforeach_not_closed_inside_block2),
- cmocka_unit_test(test_template_parse_invalid_block_name),
- cmocka_unit_test(test_template_parse_invalid_block_type_start),
- cmocka_unit_test(test_template_parse_invalid_block_type),
- cmocka_unit_test(test_template_parse_invalid_ifdef_start),
- cmocka_unit_test(test_template_parse_invalid_foreach_start),
- cmocka_unit_test(test_template_parse_invalid_ifdef_variable),
- cmocka_unit_test(test_template_parse_invalid_ifdef_variable2),
- cmocka_unit_test(test_template_parse_invalid_foreach_variable),
- cmocka_unit_test(test_template_parse_invalid_foreach_variable2),
- cmocka_unit_test(test_template_parse_invalid_if_operator),
- cmocka_unit_test(test_template_parse_invalid_if_operand),
- cmocka_unit_test(test_template_parse_invalid_if_operand2),
- cmocka_unit_test(test_template_parse_invalid_if_operand3),
- cmocka_unit_test(test_template_parse_invalid_else1),
- cmocka_unit_test(test_template_parse_invalid_else2),
- cmocka_unit_test(test_template_parse_invalid_else3),
- cmocka_unit_test(test_template_parse_invalid_block_end),
- cmocka_unit_test(test_template_parse_invalid_variable_name),
- cmocka_unit_test(test_template_parse_invalid_variable_name2),
- cmocka_unit_test(test_template_parse_invalid_variable_name3),
- cmocka_unit_test(test_template_parse_invalid_variable_end),
- cmocka_unit_test(test_template_parse_invalid_close),
- cmocka_unit_test(test_template_parse_invalid_close2),
- cmocka_unit_test(test_template_parse_invalid_endif_not_closed),
- cmocka_unit_test(test_template_parse_invalid_endif_not_closed_inside_block),
- cmocka_unit_test(test_template_parse_invalid_else_not_closed_inside_block),
- cmocka_unit_test(test_template_parse_invalid_block_not_closed),
- cmocka_unit_test(test_template_parse_invalid_foreach_not_closed),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/blogc/check_toctree.c b/tests/blogc/check_toctree.c
deleted file mode 100644
index 05cc008..0000000
--- a/tests/blogc/check_toctree.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include "../../src/common/utils.h"
-#include "../../src/blogc/toctree.h"
-
-
-static void
-test_toctree_append(void **state)
-{
- bc_slist_t *l = NULL;
-
- l = blogc_toctree_append(l, 0, "", "");
- assert_null(l);
-
- l = blogc_toctree_append(l, 1, "f1", "bola");
- assert_non_null(l);
- assert_int_equal(((blogc_toctree_header_t*) l->data)->level, 1);
- assert_string_equal(((blogc_toctree_header_t*) l->data)->slug, "f1");
- assert_string_equal(((blogc_toctree_header_t*) l->data)->text, "bola");
- assert_null(l->next);
-
- l = blogc_toctree_append(l, 2, "f2", "guda");
- assert_non_null(l);
- assert_int_equal(((blogc_toctree_header_t*) l->data)->level, 1);
- assert_string_equal(((blogc_toctree_header_t*) l->data)->slug, "f1");
- assert_string_equal(((blogc_toctree_header_t*) l->data)->text, "bola");
- assert_non_null(l->next);
- assert_int_equal(((blogc_toctree_header_t*) l->next->data)->level, 2);
- assert_string_equal(((blogc_toctree_header_t*) l->next->data)->slug, "f2");
- assert_string_equal(((blogc_toctree_header_t*) l->next->data)->text, "guda");
- assert_null(l->next->next);
-
- l = blogc_toctree_append(l, 0, "", "");
- assert_non_null(l);
- assert_int_equal(((blogc_toctree_header_t*) l->data)->level, 1);
- assert_string_equal(((blogc_toctree_header_t*) l->data)->slug, "f1");
- assert_string_equal(((blogc_toctree_header_t*) l->data)->text, "bola");
- assert_non_null(l->next);
- assert_int_equal(((blogc_toctree_header_t*) l->next->data)->level, 2);
- assert_string_equal(((blogc_toctree_header_t*) l->next->data)->slug, "f2");
- assert_string_equal(((blogc_toctree_header_t*) l->next->data)->text, "guda");
- assert_null(l->next->next);
-
- blogc_toctree_free(l);
-}
-
-
-static void
-test_toctree_render(void **state)
-{
- bc_slist_t *l = NULL;
- assert_null(blogc_toctree_render(l, 6, NULL));
-
- l = blogc_toctree_append(l, 1, "f1", "bola");
- l = blogc_toctree_append(l, 1, "f2", "guda");
- l = blogc_toctree_append(l, 2, "f3", "asd");
- l = blogc_toctree_append(l, 3, NULL, "foo");
- l = blogc_toctree_append(l, 1, "f5", NULL);
- l = blogc_toctree_append(l, 5, NULL, NULL);
- char *o = blogc_toctree_render(l, -2, NULL);
- assert_string_equal(o,
- "<ul>\n"
- " <li><a href=\"#f1\">bola</a></li>\n"
- " <li><a href=\"#f2\">guda</a></li>\n"
- " <ul>\n"
- " <li><a href=\"#f3\">asd</a></li>\n"
- " <ul>\n"
- " <li>foo</li>\n"
- " </ul>\n"
- " </ul>\n"
- " <li><a href=\"#f5\"></a></li>\n"
- " <ul>\n"
- " <ul>\n"
- " <ul>\n"
- " <ul>\n"
- " <li></li>\n"
- " </ul>\n"
- " </ul>\n"
- " </ul>\n"
- " </ul>\n"
- "</ul>\n");
- free(o);
-
- o = blogc_toctree_render(l, -1, "\n");
- assert_string_equal(o,
- "<ul>\n"
- " <li><a href=\"#f1\">bola</a></li>\n"
- " <li><a href=\"#f2\">guda</a></li>\n"
- " <ul>\n"
- " <li><a href=\"#f3\">asd</a></li>\n"
- " <ul>\n"
- " <li>foo</li>\n"
- " </ul>\n"
- " </ul>\n"
- " <li><a href=\"#f5\"></a></li>\n"
- " <ul>\n"
- " <ul>\n"
- " <ul>\n"
- " <ul>\n"
- " <li></li>\n"
- " </ul>\n"
- " </ul>\n"
- " </ul>\n"
- " </ul>\n"
- "</ul>\n");
- free(o);
-
- o = blogc_toctree_render(l, 6, "\r\n");
- assert_string_equal(o,
- "<ul>\r\n"
- " <li><a href=\"#f1\">bola</a></li>\r\n"
- " <li><a href=\"#f2\">guda</a></li>\r\n"
- " <ul>\r\n"
- " <li><a href=\"#f3\">asd</a></li>\r\n"
- " <ul>\r\n"
- " <li>foo</li>\r\n"
- " </ul>\r\n"
- " </ul>\r\n"
- " <li><a href=\"#f5\"></a></li>\r\n"
- " <ul>\r\n"
- " <ul>\r\n"
- " <ul>\r\n"
- " <ul>\r\n"
- " <li></li>\r\n"
- " </ul>\r\n"
- " </ul>\r\n"
- " </ul>\r\n"
- " </ul>\r\n"
- "</ul>\r\n");
- free(o);
-
- o = blogc_toctree_render(l, 5, NULL);
- assert_string_equal(o,
- "<ul>\n"
- " <li><a href=\"#f1\">bola</a></li>\n"
- " <li><a href=\"#f2\">guda</a></li>\n"
- " <ul>\n"
- " <li><a href=\"#f3\">asd</a></li>\n"
- " <ul>\n"
- " <li>foo</li>\n"
- " </ul>\n"
- " </ul>\n"
- " <li><a href=\"#f5\"></a></li>\n"
- " <ul>\n"
- " <ul>\n"
- " <ul>\n"
- " <ul>\n"
- " <li></li>\n"
- " </ul>\n"
- " </ul>\n"
- " </ul>\n"
- " </ul>\n"
- "</ul>\n");
- free(o);
-
- o = blogc_toctree_render(l, 4, "\n");
- assert_string_equal(o,
- "<ul>\n"
- " <li><a href=\"#f1\">bola</a></li>\n"
- " <li><a href=\"#f2\">guda</a></li>\n"
- " <ul>\n"
- " <li><a href=\"#f3\">asd</a></li>\n"
- " <ul>\n"
- " <li>foo</li>\n"
- " </ul>\n"
- " </ul>\n"
- " <li><a href=\"#f5\"></a></li>\n"
- "</ul>\n");
- free(o);
-
- o = blogc_toctree_render(l, 3, "\r\n");
- assert_string_equal(o,
- "<ul>\r\n"
- " <li><a href=\"#f1\">bola</a></li>\r\n"
- " <li><a href=\"#f2\">guda</a></li>\r\n"
- " <ul>\r\n"
- " <li><a href=\"#f3\">asd</a></li>\r\n"
- " <ul>\r\n"
- " <li>foo</li>\r\n"
- " </ul>\r\n"
- " </ul>\r\n"
- " <li><a href=\"#f5\"></a></li>\r\n"
- "</ul>\r\n");
- free(o);
-
- o = blogc_toctree_render(l, 2, NULL);
- assert_string_equal(o,
- "<ul>\n"
- " <li><a href=\"#f1\">bola</a></li>\n"
- " <li><a href=\"#f2\">guda</a></li>\n"
- " <ul>\n"
- " <li><a href=\"#f3\">asd</a></li>\n"
- " </ul>\n"
- " <li><a href=\"#f5\"></a></li>\n"
- "</ul>\n");
- free(o);
-
- o = blogc_toctree_render(l, 1, NULL);
- assert_string_equal(o,
- "<ul>\n"
- " <li><a href=\"#f1\">bola</a></li>\n"
- " <li><a href=\"#f2\">guda</a></li>\n"
- " <li><a href=\"#f5\"></a></li>\n"
- "</ul>\n");
- free(o);
-
- assert_null(blogc_toctree_render(l, 0, NULL));
-
- blogc_toctree_free(l);
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_toctree_append),
- cmocka_unit_test(test_toctree_render),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/blogc/check_content_parser.c b/tests/check_content_parser.c
index 71f1680..fb43201 100644
--- a/tests/blogc/check_content_parser.c
+++ b/tests/check_content_parser.c
@@ -1,6 +1,6 @@
/*
* blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
*
* This program can be distributed under the terms of the BSD License.
* See the file LICENSE.
@@ -11,8 +11,7 @@
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
-#include "../../src/blogc/toctree.h"
-#include "../../src/blogc/content-parser.h"
+#include "../src/content-parser.h"
static void
@@ -123,11 +122,8 @@ test_is_ordered_list_item(void **state)
static void
test_content_parse(void **state)
{
- size_t l = 0;
- char *t = NULL;
+ char *l = NULL;
char *d = NULL;
- char *n = NULL;
- bc_slist_t *h = NULL;
char *html = blogc_content_parse(
"# um\n"
"## dois\n"
@@ -169,17 +165,11 @@ test_content_parse(void **state)
"\n"
"-- asd\n"
"\n"
- "--- lol\n", &l, &t, &d, &n, &h);
+ "--- lol\n", &l, &d);
assert_non_null(html);
- assert_int_equal(l, 0);
- assert_non_null(t);
- assert_string_equal(t, "um");
+ assert_null(l);
assert_non_null(d);
assert_string_equal(d, "bola chunda");
- assert_non_null(n);
- assert_string_equal(n, "\n");
- assert_non_null(h);
- assert_int_equal(bc_slist_length(h), 6);
assert_string_equal(html,
"<h1 id=\"um\">um</h1>\n"
"<h2 id=\"dois\">dois</h2>\n"
@@ -217,21 +207,15 @@ test_content_parse(void **state)
"<p>&ndash; asd</p>\n"
"<p>&mdash; lol</p>\n");
free(html);
- free(t);
free(d);
- free(n);
- blogc_toctree_free(h);
}
static void
test_content_parse_crlf(void **state)
{
- size_t l = 0;
- char *t = NULL;
+ char *l = NULL;
char *d = NULL;
- char *n = NULL;
- bc_slist_t *h = NULL;
char *html = blogc_content_parse(
"# um\r\n"
"## dois\r\n"
@@ -273,17 +257,11 @@ test_content_parse_crlf(void **state)
"\r\n"
"-- asd\r\n"
"\r\n"
- "--- lol\r\n", &l, &t, &d, &n, &h);
+ "--- lol\r\n", &l, &d);
assert_non_null(html);
- assert_int_equal(l, 0);
- assert_non_null(t);
- assert_string_equal(t, "um");
+ assert_null(l);
assert_non_null(d);
assert_string_equal(d, "bola chunda");
- assert_non_null(n);
- assert_string_equal(n, "\r\n");
- assert_non_null(h);
- assert_int_equal(bc_slist_length(h), 6);
assert_string_equal(html,
"<h1 id=\"um\">um</h1>\r\n"
"<h2 id=\"dois\">dois</h2>\r\n"
@@ -321,21 +299,15 @@ test_content_parse_crlf(void **state)
"<p>&ndash; asd</p>\r\n"
"<p>&mdash; lol</p>\r\n");
free(html);
- free(t);
free(d);
- free(n);
- blogc_toctree_free(h);
}
static void
test_content_parse_with_excerpt(void **state)
{
- size_t l = 0;
- char *t = NULL;
+ char *l = NULL;
char *d = NULL;
- char *n = NULL;
- bc_slist_t *h = NULL;
char *html = blogc_content_parse(
"# test\n"
"\n"
@@ -344,32 +316,24 @@ test_content_parse_with_excerpt(void **state)
"..\n"
"\n"
"guda\n"
- "lol", &l, &t, &d, &n, &h);
+ "lol", &l, &d);
assert_non_null(html);
- assert_int_equal(l, 38);
- assert_non_null(t);
- assert_string_equal(t, "test");
+ assert_non_null(l);
+ assert_string_equal(l,
+ "<h1 id=\"test\">test</h1>\n"
+ "<p>chunda</p>\n");
assert_non_null(d);
assert_string_equal(d, "chunda");
- assert_non_null(n);
- assert_string_equal(n, "\n");
- assert_non_null(h);
- assert_int_equal(bc_slist_length(h), 1);
assert_string_equal(html,
"<h1 id=\"test\">test</h1>\n"
"<p>chunda</p>\n"
"<p>guda\n"
"lol</p>\n");
free(html);
- l = 0;
- free(t);
+ free(l);
+ l = NULL;
free(d);
- free(n);
- blogc_toctree_free(h);
- t = NULL;
d = NULL;
- n = NULL;
- h = NULL;
html = blogc_content_parse(
"# test\n"
"\n"
@@ -378,38 +342,30 @@ test_content_parse_with_excerpt(void **state)
"...\n"
"\n"
"guda\n"
- "lol", &l, &t, &d, &n, &h);
+ "lol", &l, &d);
assert_non_null(html);
- assert_int_equal(l, 38);
- assert_non_null(t);
- assert_string_equal(t, "test");
+ assert_non_null(l);
+ assert_string_equal(l,
+ "<h1 id=\"test\">test</h1>\n"
+ "<p>chunda</p>\n");
assert_non_null(d);
assert_string_equal(d, "chunda");
- assert_non_null(n);
- assert_string_equal(n, "\n");
- assert_non_null(h);
- assert_int_equal(bc_slist_length(h), 1);
assert_string_equal(html,
"<h1 id=\"test\">test</h1>\n"
"<p>chunda</p>\n"
"<p>guda\n"
"lol</p>\n");
free(html);
- free(t);
+ free(l);
free(d);
- free(n);
- blogc_toctree_free(h);
}
static void
test_content_parse_with_excerpt_crlf(void **state)
{
- size_t l = 0;
- char *t = NULL;
+ char *l = NULL;
char *d = NULL;
- char *n = NULL;
- bc_slist_t *h = NULL;
char *html = blogc_content_parse(
"# test\r\n"
"\r\n"
@@ -418,32 +374,24 @@ test_content_parse_with_excerpt_crlf(void **state)
"..\r\n"
"\r\n"
"guda\r\n"
- "lol", &l, &t, &d, &n, &h);
+ "lol", &l, &d);
assert_non_null(html);
- assert_int_equal(l, 40);
- assert_non_null(t);
- assert_string_equal(t, "test");
+ assert_non_null(l);
+ assert_string_equal(l,
+ "<h1 id=\"test\">test</h1>\r\n"
+ "<p>chunda</p>\r\n");
assert_non_null(d);
assert_string_equal(d, "chunda");
- assert_non_null(n);
- assert_string_equal(n, "\r\n");
- assert_non_null(h);
- assert_int_equal(bc_slist_length(h), 1);
assert_string_equal(html,
"<h1 id=\"test\">test</h1>\r\n"
"<p>chunda</p>\r\n"
"<p>guda\r\n"
"lol</p>\r\n");
free(html);
- l = 0;
- free(t);
+ free(l);
+ l = NULL;
free(d);
- free(n);
- blogc_toctree_free(h);
- t = NULL;
d = NULL;
- n = NULL;
- h = NULL;
html = blogc_content_parse(
"# test\r\n"
"\r\n"
@@ -452,38 +400,33 @@ test_content_parse_with_excerpt_crlf(void **state)
"...\r\n"
"\r\n"
"guda\r\n"
- "lol", &l, &t, &d, &n, &h);
+ "lol", &l, &d);
assert_non_null(html);
- assert_int_equal(l, 40);
- assert_non_null(t);
- assert_string_equal(t, "test");
+ assert_non_null(l);
+ assert_string_equal(l,
+ "<h1 id=\"test\">test</h1>\r\n"
+ "<p>chunda</p>\r\n");
assert_non_null(d);
assert_string_equal(d, "chunda");
- assert_non_null(n);
- assert_string_equal(n, "\r\n");
- assert_non_null(h);
- assert_int_equal(bc_slist_length(h), 1);
assert_string_equal(html,
"<h1 id=\"test\">test</h1>\r\n"
"<p>chunda</p>\r\n"
"<p>guda\r\n"
"lol</p>\r\n");
free(html);
- free(t);
+ free(l);
free(d);
- free(n);
- blogc_toctree_free(h);
}
static void
test_content_parse_header(void **state)
{
- char *html = blogc_content_parse("## bola", NULL, NULL, NULL, NULL, NULL);
+ char *html = blogc_content_parse("## bola", NULL, NULL);
assert_non_null(html);
assert_string_equal(html, "<h2 id=\"bola\">bola</h2>\n");
free(html);
- html = blogc_content_parse("## bola\n", NULL, NULL, NULL, NULL, NULL);
+ html = blogc_content_parse("## bola\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html, "<h2 id=\"bola\">bola</h2>\n");
free(html);
@@ -492,7 +435,7 @@ test_content_parse_header(void **state)
"\n"
"## bola\n"
"\n"
- "guda\n", NULL, NULL, NULL, NULL, NULL);
+ "guda\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola</p>\n"
@@ -505,11 +448,11 @@ test_content_parse_header(void **state)
static void
test_content_parse_header_crlf(void **state)
{
- char *html = blogc_content_parse("## bola", NULL, NULL, NULL, NULL, NULL);
+ char *html = blogc_content_parse("## bola", NULL, NULL);
assert_non_null(html);
assert_string_equal(html, "<h2 id=\"bola\">bola</h2>\n");
free(html);
- html = blogc_content_parse("## bola\r\n", NULL, NULL, NULL, NULL, NULL);
+ html = blogc_content_parse("## bola\r\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html, "<h2 id=\"bola\">bola</h2>\r\n");
free(html);
@@ -518,7 +461,7 @@ test_content_parse_header_crlf(void **state)
"\r\n"
"## bola\r\n"
"\r\n"
- "guda\r\n", NULL, NULL, NULL, NULL, NULL);
+ "guda\r\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola</p>\r\n"
@@ -531,11 +474,11 @@ test_content_parse_header_crlf(void **state)
static void
test_content_parse_html(void **state)
{
- char *html = blogc_content_parse("<div>\n</div>", NULL, NULL, NULL, NULL, NULL);
+ char *html = blogc_content_parse("<div>\n</div>", NULL, NULL);
assert_non_null(html);
assert_string_equal(html, "<div>\n</div>\n");
free(html);
- html = blogc_content_parse("<div>\n</div>\n", NULL, NULL, NULL, NULL, NULL);
+ html = blogc_content_parse("<div>\n</div>\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html, "<div>\n</div>\n");
free(html);
@@ -545,7 +488,7 @@ test_content_parse_html(void **state)
"<div>\n"
"</div>\n"
"\n"
- "chunda\n", NULL, NULL, NULL, NULL, NULL);
+ "chunda\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola</p>\n"
@@ -558,11 +501,11 @@ test_content_parse_html(void **state)
static void
test_content_parse_html_crlf(void **state)
{
- char *html = blogc_content_parse("<div>\r\n</div>", NULL, NULL, NULL, NULL, NULL);
+ char *html = blogc_content_parse("<div>\r\n</div>", NULL, NULL);
assert_non_null(html);
assert_string_equal(html, "<div>\r\n</div>\r\n");
free(html);
- html = blogc_content_parse("<div>\r\n</div>\r\n", NULL, NULL, NULL, NULL, NULL);
+ html = blogc_content_parse("<div>\r\n</div>\r\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html, "<div>\r\n</div>\r\n");
free(html);
@@ -572,7 +515,7 @@ test_content_parse_html_crlf(void **state)
"<div>\r\n"
"</div>\r\n"
"\r\n"
- "chunda\r\n", NULL, NULL, NULL, NULL, NULL);
+ "chunda\r\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola</p>\r\n"
@@ -585,14 +528,14 @@ test_content_parse_html_crlf(void **state)
static void
test_content_parse_blockquote(void **state)
{
- char *html = blogc_content_parse("> bola\n> guda", NULL, NULL, NULL, NULL, NULL);
+ char *html = blogc_content_parse("> bola\n> guda", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<blockquote><p>bola\n"
"guda</p>\n"
"</blockquote>\n");
free(html);
- html = blogc_content_parse("> bola\n> guda\n", NULL, NULL, NULL, NULL, NULL);
+ html = blogc_content_parse("> bola\n> guda\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<blockquote><p>bola\n"
@@ -604,7 +547,7 @@ test_content_parse_blockquote(void **state)
"\n"
"> bola\n"
"\n"
- "chunda\n", NULL, NULL, NULL, NULL, NULL);
+ "chunda\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola</p>\n"
@@ -618,7 +561,7 @@ test_content_parse_blockquote(void **state)
"> bola\n"
"> guda\n"
"\n"
- "chunda\n", NULL, NULL, NULL, NULL, NULL);
+ "chunda\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola</p>\n"
@@ -633,14 +576,14 @@ test_content_parse_blockquote(void **state)
static void
test_content_parse_blockquote_crlf(void **state)
{
- char *html = blogc_content_parse("> bola\r\n> guda", NULL, NULL, NULL, NULL, NULL);
+ char *html = blogc_content_parse("> bola\r\n> guda", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<blockquote><p>bola\r\n"
"guda</p>\r\n"
"</blockquote>\r\n");
free(html);
- html = blogc_content_parse("> bola\r\n> guda\r\n", NULL, NULL, NULL, NULL, NULL);
+ html = blogc_content_parse("> bola\r\n> guda\r\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<blockquote><p>bola\r\n"
@@ -652,7 +595,7 @@ test_content_parse_blockquote_crlf(void **state)
"\r\n"
"> bola\r\n"
"\r\n"
- "chunda\r\n", NULL, NULL, NULL, NULL, NULL);
+ "chunda\r\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola</p>\r\n"
@@ -666,7 +609,7 @@ test_content_parse_blockquote_crlf(void **state)
"> bola\r\n"
"> guda\r\n"
"\r\n"
- "chunda\r\n", NULL, NULL, NULL, NULL, NULL);
+ "chunda\r\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola</p>\r\n"
@@ -681,13 +624,13 @@ test_content_parse_blockquote_crlf(void **state)
static void
test_content_parse_code(void **state)
{
- char *html = blogc_content_parse(" bola\n guda", NULL, NULL, NULL, NULL, NULL);
+ char *html = blogc_content_parse(" bola\n guda", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<pre><code>bola\n"
"guda</code></pre>\n");
free(html);
- html = blogc_content_parse(" bola\n guda\n", NULL, NULL, NULL, NULL, NULL);
+ html = blogc_content_parse(" bola\n guda\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<pre><code>bola\n"
@@ -699,7 +642,7 @@ test_content_parse_code(void **state)
" bola\n"
" guda\n"
"\n"
- "chunda\n", NULL, NULL, NULL, NULL, NULL);
+ "chunda\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola</p>\n"
@@ -713,13 +656,13 @@ test_content_parse_code(void **state)
static void
test_content_parse_code_crlf(void **state)
{
- char *html = blogc_content_parse(" bola\r\n guda", NULL, NULL, NULL, NULL, NULL);
+ char *html = blogc_content_parse(" bola\r\n guda", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<pre><code>bola\r\n"
"guda</code></pre>\r\n");
free(html);
- html = blogc_content_parse(" bola\r\n guda\r\n", NULL, NULL, NULL, NULL, NULL);
+ html = blogc_content_parse(" bola\r\n guda\r\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<pre><code>bola\r\n"
@@ -731,7 +674,7 @@ test_content_parse_code_crlf(void **state)
" bola\r\n"
" guda\r\n"
"\r\n"
- "chunda\r\n", NULL, NULL, NULL, NULL, NULL);
+ "chunda\r\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola</p>\r\n"
@@ -745,28 +688,28 @@ test_content_parse_code_crlf(void **state)
static void
test_content_parse_horizontal_rule(void **state)
{
- char *html = blogc_content_parse("bola\nguda\n\n***", NULL, NULL, NULL, NULL, NULL);
+ char *html = blogc_content_parse("bola\nguda\n\n**", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola\n"
"guda</p>\n"
"<hr />\n");
free(html);
- html = blogc_content_parse("bola\nguda\n\n++++", NULL, NULL, NULL, NULL, NULL);
+ html = blogc_content_parse("bola\nguda\n\n++++", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola\n"
"guda</p>\n"
"<hr />\n");
free(html);
- html = blogc_content_parse("bola\nguda\n\n---\n", NULL, NULL, NULL, NULL, NULL);
+ html = blogc_content_parse("bola\nguda\n\n--\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola\n"
"guda</p>\n"
"<hr />\n");
free(html);
- html = blogc_content_parse("bola\nguda\n\n****\n", NULL, NULL, NULL, NULL, NULL);
+ html = blogc_content_parse("bola\nguda\n\n****\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola\n"
@@ -776,9 +719,9 @@ test_content_parse_horizontal_rule(void **state)
html = blogc_content_parse(
"bola\n"
"\n"
- "***\n"
+ "**\n"
"\n"
- "chunda\n", NULL, NULL, NULL, NULL, NULL);
+ "chunda\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola</p>\n"
@@ -790,7 +733,7 @@ test_content_parse_horizontal_rule(void **state)
"\n"
"----\n"
"\n"
- "chunda\n", NULL, NULL, NULL, NULL, NULL);
+ "chunda\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola</p>\n"
@@ -803,28 +746,28 @@ test_content_parse_horizontal_rule(void **state)
static void
test_content_parse_horizontal_rule_crlf(void **state)
{
- char *html = blogc_content_parse("bola\r\nguda\r\n\r\n***", NULL, NULL, NULL, NULL, NULL);
+ char *html = blogc_content_parse("bola\r\nguda\r\n\r\n**", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola\r\n"
"guda</p>\r\n"
"<hr />\r\n");
free(html);
- html = blogc_content_parse("bola\r\nguda\r\n\r\n++++", NULL, NULL, NULL, NULL, NULL);
+ html = blogc_content_parse("bola\r\nguda\r\n\r\n++++", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola\r\n"
"guda</p>\r\n"
"<hr />\r\n");
free(html);
- html = blogc_content_parse("bola\r\nguda\r\n\r\n---\r\n", NULL, NULL, NULL, NULL, NULL);
+ html = blogc_content_parse("bola\r\nguda\r\n\r\n--\r\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola\r\n"
"guda</p>\r\n"
"<hr />\r\n");
free(html);
- html = blogc_content_parse("bola\r\nguda\r\n\r\n****\r\n", NULL, NULL, NULL, NULL, NULL);
+ html = blogc_content_parse("bola\r\nguda\r\n\r\n****\r\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola\r\n"
@@ -834,9 +777,9 @@ test_content_parse_horizontal_rule_crlf(void **state)
html = blogc_content_parse(
"bola\r\n"
"\r\n"
- "***\r\n"
+ "**\r\n"
"\r\n"
- "chunda\r\n", NULL, NULL, NULL, NULL, NULL);
+ "chunda\r\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola</p>\r\n"
@@ -848,7 +791,7 @@ test_content_parse_horizontal_rule_crlf(void **state)
"\r\n"
"----\r\n"
"\r\n"
- "chunda\r\n", NULL, NULL, NULL, NULL, NULL);
+ "chunda\r\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>bola</p>\r\n"
@@ -866,7 +809,7 @@ test_content_parse_unordered_list(void **state)
"\n"
"* asd\n"
"* qwe\n"
- "* zxc", NULL, NULL, NULL, NULL, NULL);
+ "* zxc", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>lol</p>\n"
@@ -881,7 +824,7 @@ test_content_parse_unordered_list(void **state)
"\n"
"* asd\n"
"* qwe\n"
- "* zxc\n", NULL, NULL, NULL, NULL, NULL);
+ "* zxc\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>lol</p>\n"
@@ -898,7 +841,7 @@ test_content_parse_unordered_list(void **state)
"* qwe\n"
"* zxc\n"
"\n"
- "fuuuu\n", NULL, NULL, NULL, NULL, NULL);
+ "fuuuu\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>lol</p>\n"
@@ -918,7 +861,7 @@ test_content_parse_unordered_list(void **state)
"* zxc\n"
" 1234\n"
"\n"
- "fuuuu\n", NULL, NULL, NULL, NULL, NULL);
+ "fuuuu\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>lol</p>\n"
@@ -934,7 +877,7 @@ test_content_parse_unordered_list(void **state)
html = blogc_content_parse(
"* asd\n"
"* qwe\n"
- "* zxc", NULL, NULL, NULL, NULL, NULL);
+ "* zxc", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<ul>\n"
@@ -954,7 +897,7 @@ test_content_parse_unordered_list_crlf(void **state)
"\r\n"
"* asd\r\n"
"* qwe\r\n"
- "* zxc", NULL, NULL, NULL, NULL, NULL);
+ "* zxc", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>lol</p>\r\n"
@@ -969,7 +912,7 @@ test_content_parse_unordered_list_crlf(void **state)
"\r\n"
"* asd\r\n"
"* qwe\r\n"
- "* zxc\r\n", NULL, NULL, NULL, NULL, NULL);
+ "* zxc\r\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>lol</p>\r\n"
@@ -986,7 +929,7 @@ test_content_parse_unordered_list_crlf(void **state)
"* qwe\r\n"
"* zxc\r\n"
"\r\n"
- "fuuuu\r\n", NULL, NULL, NULL, NULL, NULL);
+ "fuuuu\r\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>lol</p>\r\n"
@@ -1006,7 +949,7 @@ test_content_parse_unordered_list_crlf(void **state)
"* zxc\r\n"
" 1234\r\n"
"\r\n"
- "fuuuu\r\n", NULL, NULL, NULL, NULL, NULL);
+ "fuuuu\r\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>lol</p>\r\n"
@@ -1022,7 +965,7 @@ test_content_parse_unordered_list_crlf(void **state)
html = blogc_content_parse(
"* asd\r\n"
"* qwe\r\n"
- "* zxc", NULL, NULL, NULL, NULL, NULL);
+ "* zxc", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<ul>\r\n"
@@ -1042,7 +985,7 @@ test_content_parse_ordered_list(void **state)
"\n"
"1. asd\n"
"2. qwe\n"
- "3. zxc", NULL, NULL, NULL, NULL, NULL);
+ "3. zxc", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>lol</p>\n"
@@ -1057,7 +1000,7 @@ test_content_parse_ordered_list(void **state)
"\n"
"1. asd\n"
"2. qwe\n"
- "3. zxc\n", NULL, NULL, NULL, NULL, NULL);
+ "3. zxc\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>lol</p>\n"
@@ -1074,7 +1017,7 @@ test_content_parse_ordered_list(void **state)
"2. qwe\n"
"3. zxc\n"
"\n"
- "fuuuu\n", NULL, NULL, NULL, NULL, NULL);
+ "fuuuu\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>lol</p>\n"
@@ -1094,7 +1037,7 @@ test_content_parse_ordered_list(void **state)
"3. zxc\n"
" 1234\n"
"\n"
- "fuuuu\n", NULL, NULL, NULL, NULL, NULL);
+ "fuuuu\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>lol</p>\n"
@@ -1110,7 +1053,7 @@ test_content_parse_ordered_list(void **state)
html = blogc_content_parse(
"1. asd\n"
"2. qwe\n"
- "3. zxc", NULL, NULL, NULL, NULL, NULL);
+ "3. zxc", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<ol>\n"
@@ -1130,7 +1073,7 @@ test_content_parse_ordered_list_crlf(void **state)
"\r\n"
"1. asd\r\n"
"2. qwe\r\n"
- "3. zxc", NULL, NULL, NULL, NULL, NULL);
+ "3. zxc", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>lol</p>\r\n"
@@ -1145,7 +1088,7 @@ test_content_parse_ordered_list_crlf(void **state)
"\r\n"
"1. asd\r\n"
"2. qwe\r\n"
- "3. zxc\r\n", NULL, NULL, NULL, NULL, NULL);
+ "3. zxc\r\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>lol</p>\r\n"
@@ -1162,7 +1105,7 @@ test_content_parse_ordered_list_crlf(void **state)
"2. qwe\r\n"
"3. zxc\r\n"
"\r\n"
- "fuuuu\r\n", NULL, NULL, NULL, NULL, NULL);
+ "fuuuu\r\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>lol</p>\r\n"
@@ -1182,7 +1125,7 @@ test_content_parse_ordered_list_crlf(void **state)
"3. zxc\r\n"
" 1234\r\n"
"\r\n"
- "fuuuu\r\n", NULL, NULL, NULL, NULL, NULL);
+ "fuuuu\r\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>lol</p>\r\n"
@@ -1198,7 +1141,7 @@ test_content_parse_ordered_list_crlf(void **state)
html = blogc_content_parse(
"1. asd\r\n"
"2. qwe\r\n"
- "3. zxc", NULL, NULL, NULL, NULL, NULL);
+ "3. zxc", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<ol>\r\n"
@@ -1211,406 +1154,13 @@ test_content_parse_ordered_list_crlf(void **state)
static void
-test_content_parse_first_header(void **state)
-{
- char *t = NULL;
- char *html = blogc_content_parse("# foo", NULL, &t, NULL, NULL, NULL);
- assert_non_null(html);
- assert_string_equal(html, "<h1 id=\"foo\">foo</h1>\n");
- assert_non_null(t);
- assert_string_equal(t, "foo");
- free(html);
- free(t);
- t = NULL;
- html = blogc_content_parse("# foo\n", NULL, &t, NULL, NULL, NULL);
- assert_non_null(html);
- assert_string_equal(html, "<h1 id=\"foo\">foo</h1>\n");
- assert_non_null(t);
- assert_string_equal(t, "foo");
- free(html);
- free(t);
- t = NULL;
- html = blogc_content_parse(
- "# foo\n"
- "## bar\n"
- "### baz", NULL, &t, NULL, NULL, NULL);
- assert_non_null(html);
- assert_string_equal(html,
- "<h1 id=\"foo\">foo</h1>\n"
- "<h2 id=\"bar\">bar</h2>\n"
- "<h3 id=\"baz\">baz</h3>\n");
- assert_non_null(t);
- assert_string_equal(t, "foo");
- free(html);
- free(t);
- t = NULL;
- html = blogc_content_parse(
- "# foo\n"
- "## bar\n"
- "### baz\n", NULL, &t, NULL, NULL, NULL);
- assert_non_null(html);
- assert_string_equal(html,
- "<h1 id=\"foo\">foo</h1>\n"
- "<h2 id=\"bar\">bar</h2>\n"
- "<h3 id=\"baz\">baz</h3>\n");
- assert_non_null(t);
- assert_string_equal(t, "foo");
- free(html);
- free(t);
- t = NULL;
- html = blogc_content_parse(
- "## bar\n"
- "# foo\n"
- "### baz", NULL, &t, NULL, NULL, NULL);
- assert_non_null(html);
- assert_string_equal(html,
- "<h2 id=\"bar\">bar</h2>\n"
- "<h1 id=\"foo\">foo</h1>\n"
- "<h3 id=\"baz\">baz</h3>\n");
- assert_non_null(t);
- assert_string_equal(t, "bar");
- free(html);
- free(t);
- t = NULL;
- html = blogc_content_parse(
- "## bar\n"
- "# foo\n"
- "### baz\n", NULL, &t, NULL, NULL, NULL);
- assert_non_null(html);
- assert_string_equal(html,
- "<h2 id=\"bar\">bar</h2>\n"
- "<h1 id=\"foo\">foo</h1>\n"
- "<h3 id=\"baz\">baz</h3>\n");
- assert_non_null(t);
- assert_string_equal(t, "bar");
- free(html);
- free(t);
-}
-
-
-static void
-test_content_parse_first_header_crlf(void **state)
-{
- char *t = NULL;
- char *html = blogc_content_parse("# foo\r\n", NULL, &t, NULL, NULL, NULL);
- assert_non_null(html);
- assert_string_equal(html, "<h1 id=\"foo\">foo</h1>\r\n");
- assert_non_null(t);
- assert_string_equal(t, "foo");
- free(html);
- free(t);
- t = NULL;
- html = blogc_content_parse(
- "# foo\r\n"
- "## bar\r\n"
- "### baz", NULL, &t, NULL, NULL, NULL);
- assert_non_null(html);
- assert_string_equal(html,
- "<h1 id=\"foo\">foo</h1>\r\n"
- "<h2 id=\"bar\">bar</h2>\r\n"
- "<h3 id=\"baz\">baz</h3>\r\n");
- assert_non_null(t);
- assert_string_equal(t, "foo");
- free(html);
- free(t);
- t = NULL;
- html = blogc_content_parse(
- "# foo\r\n"
- "## bar\r\n"
- "### baz\r\n", NULL, &t, NULL, NULL, NULL);
- assert_non_null(html);
- assert_string_equal(html,
- "<h1 id=\"foo\">foo</h1>\r\n"
- "<h2 id=\"bar\">bar</h2>\r\n"
- "<h3 id=\"baz\">baz</h3>\r\n");
- assert_non_null(t);
- assert_string_equal(t, "foo");
- free(html);
- free(t);
- t = NULL;
- html = blogc_content_parse(
- "## bar\r\n"
- "# foo\r\n"
- "### baz", NULL, &t, NULL, NULL, NULL);
- assert_non_null(html);
- assert_string_equal(html,
- "<h2 id=\"bar\">bar</h2>\r\n"
- "<h1 id=\"foo\">foo</h1>\r\n"
- "<h3 id=\"baz\">baz</h3>\r\n");
- assert_non_null(t);
- assert_string_equal(t, "bar");
- free(html);
- free(t);
- t = NULL;
- html = blogc_content_parse(
- "## bar\r\n"
- "# foo\r\n"
- "### baz\r\n", NULL, &t, NULL, NULL, NULL);
- assert_non_null(html);
- assert_string_equal(html,
- "<h2 id=\"bar\">bar</h2>\r\n"
- "<h1 id=\"foo\">foo</h1>\r\n"
- "<h3 id=\"baz\">baz</h3>\r\n");
- assert_non_null(t);
- assert_string_equal(t, "bar");
- free(html);
- free(t);
-}
-
-
-static void
-test_content_parse_headers(void **state)
-{
- bc_slist_t *h = NULL;
- char *html = blogc_content_parse("# foo", NULL, NULL, NULL, NULL, &h);
- assert_non_null(html);
- assert_string_equal(html, "<h1 id=\"foo\">foo</h1>\n");
- assert_non_null(h);
- assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 1);
- assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "foo");
- assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "foo");
- assert_null(h->next);
- blogc_toctree_free(h);
- h = NULL;
- free(html);
- html = blogc_content_parse("# foo\n", NULL, NULL, NULL, NULL, &h);
- assert_non_null(html);
- assert_string_equal(html, "<h1 id=\"foo\">foo</h1>\n");
- assert_non_null(h);
- assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 1);
- assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "foo");
- assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "foo");
- assert_null(h->next);
- blogc_toctree_free(h);
- h = NULL;
- free(html);
- html = blogc_content_parse(
- "# foo\n"
- "## bar\n"
- "### baz", NULL, NULL, NULL, NULL, &h);
- assert_non_null(html);
- assert_string_equal(html,
- "<h1 id=\"foo\">foo</h1>\n"
- "<h2 id=\"bar\">bar</h2>\n"
- "<h3 id=\"baz\">baz</h3>\n");
- assert_non_null(h);
- assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 1);
- assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "foo");
- assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "foo");
- assert_non_null(h->next);
- assert_int_equal(((blogc_toctree_header_t*) h->next->data)->level, 2);
- assert_string_equal(((blogc_toctree_header_t*) h->next->data)->slug, "bar");
- assert_string_equal(((blogc_toctree_header_t*) h->next->data)->text, "bar");
- assert_non_null(h);
- assert_int_equal(((blogc_toctree_header_t*) h->next->next->data)->level, 3);
- assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->slug, "baz");
- assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->text, "baz");
- assert_null(h->next->next->next);
- blogc_toctree_free(h);
- h = NULL;
- free(html);
- html = blogc_content_parse(
- "# foo\n"
- "## bar\n"
- "### baz\n", NULL, NULL, NULL, NULL, &h);
- assert_non_null(html);
- assert_string_equal(html,
- "<h1 id=\"foo\">foo</h1>\n"
- "<h2 id=\"bar\">bar</h2>\n"
- "<h3 id=\"baz\">baz</h3>\n");
- assert_non_null(h);
- assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 1);
- assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "foo");
- assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "foo");
- assert_non_null(h->next);
- assert_int_equal(((blogc_toctree_header_t*) h->next->data)->level, 2);
- assert_string_equal(((blogc_toctree_header_t*) h->next->data)->slug, "bar");
- assert_string_equal(((blogc_toctree_header_t*) h->next->data)->text, "bar");
- assert_non_null(h);
- assert_int_equal(((blogc_toctree_header_t*) h->next->next->data)->level, 3);
- assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->slug, "baz");
- assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->text, "baz");
- assert_null(h->next->next->next);
- blogc_toctree_free(h);
- h = NULL;
- free(html);
- html = blogc_content_parse(
- "## bar\n"
- "# foo\n"
- "### baz", NULL, NULL, NULL, NULL, &h);
- assert_non_null(html);
- assert_string_equal(html,
- "<h2 id=\"bar\">bar</h2>\n"
- "<h1 id=\"foo\">foo</h1>\n"
- "<h3 id=\"baz\">baz</h3>\n");
- assert_non_null(h);
- assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 2);
- assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "bar");
- assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "bar");
- assert_non_null(h->next);
- assert_int_equal(((blogc_toctree_header_t*) h->next->data)->level, 1);
- assert_string_equal(((blogc_toctree_header_t*) h->next->data)->slug, "foo");
- assert_string_equal(((blogc_toctree_header_t*) h->next->data)->text, "foo");
- assert_non_null(h);
- assert_int_equal(((blogc_toctree_header_t*) h->next->next->data)->level, 3);
- assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->slug, "baz");
- assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->text, "baz");
- assert_null(h->next->next->next);
- blogc_toctree_free(h);
- h = NULL;
- free(html);
- html = blogc_content_parse(
- "## bar\n"
- "# foo\n"
- "### baz\n", NULL, NULL, NULL, NULL, &h);
- assert_non_null(html);
- assert_string_equal(html,
- "<h2 id=\"bar\">bar</h2>\n"
- "<h1 id=\"foo\">foo</h1>\n"
- "<h3 id=\"baz\">baz</h3>\n");
- assert_non_null(h);
- assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 2);
- assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "bar");
- assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "bar");
- assert_non_null(h->next);
- assert_int_equal(((blogc_toctree_header_t*) h->next->data)->level, 1);
- assert_string_equal(((blogc_toctree_header_t*) h->next->data)->slug, "foo");
- assert_string_equal(((blogc_toctree_header_t*) h->next->data)->text, "foo");
- assert_non_null(h);
- assert_int_equal(((blogc_toctree_header_t*) h->next->next->data)->level, 3);
- assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->slug, "baz");
- assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->text, "baz");
- assert_null(h->next->next->next);
- blogc_toctree_free(h);
- free(html);
-}
-
-
-static void
-test_content_parse_headers_crlf(void **state)
-{
- bc_slist_t *h = NULL;
- char *html = blogc_content_parse("# foo\r\n", NULL, NULL, NULL, NULL, &h);
- assert_non_null(html);
- assert_string_equal(html, "<h1 id=\"foo\">foo</h1>\r\n");
- assert_non_null(h);
- assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 1);
- assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "foo");
- assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "foo");
- assert_null(h->next);
- blogc_toctree_free(h);
- h = NULL;
- free(html);
- html = blogc_content_parse(
- "# foo\r\n"
- "## bar\r\n"
- "### baz", NULL, NULL, NULL, NULL, &h);
- assert_non_null(html);
- assert_string_equal(html,
- "<h1 id=\"foo\">foo</h1>\r\n"
- "<h2 id=\"bar\">bar</h2>\r\n"
- "<h3 id=\"baz\">baz</h3>\r\n");
- assert_non_null(h);
- assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 1);
- assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "foo");
- assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "foo");
- assert_non_null(h->next);
- assert_int_equal(((blogc_toctree_header_t*) h->next->data)->level, 2);
- assert_string_equal(((blogc_toctree_header_t*) h->next->data)->slug, "bar");
- assert_string_equal(((blogc_toctree_header_t*) h->next->data)->text, "bar");
- assert_non_null(h);
- assert_int_equal(((blogc_toctree_header_t*) h->next->next->data)->level, 3);
- assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->slug, "baz");
- assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->text, "baz");
- assert_null(h->next->next->next);
- blogc_toctree_free(h);
- h = NULL;
- free(html);
- html = blogc_content_parse(
- "# foo\r\n"
- "## bar\r\n"
- "### baz\r\n", NULL, NULL, NULL, NULL, &h);
- assert_non_null(html);
- assert_string_equal(html,
- "<h1 id=\"foo\">foo</h1>\r\n"
- "<h2 id=\"bar\">bar</h2>\r\n"
- "<h3 id=\"baz\">baz</h3>\r\n");
- assert_non_null(h);
- assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 1);
- assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "foo");
- assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "foo");
- assert_non_null(h->next);
- assert_int_equal(((blogc_toctree_header_t*) h->next->data)->level, 2);
- assert_string_equal(((blogc_toctree_header_t*) h->next->data)->slug, "bar");
- assert_string_equal(((blogc_toctree_header_t*) h->next->data)->text, "bar");
- assert_non_null(h);
- assert_int_equal(((blogc_toctree_header_t*) h->next->next->data)->level, 3);
- assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->slug, "baz");
- assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->text, "baz");
- assert_null(h->next->next->next);
- blogc_toctree_free(h);
- h = NULL;
- free(html);
- html = blogc_content_parse(
- "## bar\r\n"
- "# foo\r\n"
- "### baz", NULL, NULL, NULL, NULL, &h);
- assert_non_null(html);
- assert_string_equal(html,
- "<h2 id=\"bar\">bar</h2>\r\n"
- "<h1 id=\"foo\">foo</h1>\r\n"
- "<h3 id=\"baz\">baz</h3>\r\n");
- assert_non_null(h);
- assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 2);
- assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "bar");
- assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "bar");
- assert_non_null(h->next);
- assert_int_equal(((blogc_toctree_header_t*) h->next->data)->level, 1);
- assert_string_equal(((blogc_toctree_header_t*) h->next->data)->slug, "foo");
- assert_string_equal(((blogc_toctree_header_t*) h->next->data)->text, "foo");
- assert_non_null(h);
- assert_int_equal(((blogc_toctree_header_t*) h->next->next->data)->level, 3);
- assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->slug, "baz");
- assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->text, "baz");
- assert_null(h->next->next->next);
- blogc_toctree_free(h);
- h = NULL;
- free(html);
- html = blogc_content_parse(
- "## bar\r\n"
- "# foo\r\n"
- "### baz\r\n", NULL, NULL, NULL, NULL, &h);
- assert_non_null(html);
- assert_string_equal(html,
- "<h2 id=\"bar\">bar</h2>\r\n"
- "<h1 id=\"foo\">foo</h1>\r\n"
- "<h3 id=\"baz\">baz</h3>\r\n");
- assert_non_null(h);
- assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 2);
- assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "bar");
- assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "bar");
- assert_non_null(h->next);
- assert_int_equal(((blogc_toctree_header_t*) h->next->data)->level, 1);
- assert_string_equal(((blogc_toctree_header_t*) h->next->data)->slug, "foo");
- assert_string_equal(((blogc_toctree_header_t*) h->next->data)->text, "foo");
- assert_non_null(h);
- assert_int_equal(((blogc_toctree_header_t*) h->next->next->data)->level, 3);
- assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->slug, "baz");
- assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->text, "baz");
- assert_null(h->next->next->next);
- blogc_toctree_free(h);
- free(html);
-}
-
-
-static void
test_content_parse_description(void **state)
{
char *d = NULL;
char *html = blogc_content_parse(
"# foo\n"
"\n"
- "bar", NULL, NULL, &d, NULL, NULL);
+ "bar", NULL, &d);
assert_non_null(html);
assert_string_equal(html,
"<h1 id=\"foo\">foo</h1>\n"
@@ -1623,7 +1173,7 @@ test_content_parse_description(void **state)
html = blogc_content_parse(
"# foo\n"
"\n"
- "bar\n", NULL, NULL, &d, NULL, NULL);
+ "bar\n", NULL, &d);
assert_non_null(html);
assert_string_equal(html,
"<h1 id=\"foo\">foo</h1>\n"
@@ -1637,7 +1187,7 @@ test_content_parse_description(void **state)
"# foo\n"
"\n"
"qwe\n"
- "bar\n", NULL, NULL, &d, NULL, NULL);
+ "bar\n", NULL, &d);
assert_non_null(html);
assert_string_equal(html,
"<h1 id=\"foo\">foo</h1>\n"
@@ -1653,7 +1203,7 @@ test_content_parse_description(void **state)
"\n"
"> qwe\n"
"\n"
- "bar\n", NULL, NULL, &d, NULL, NULL);
+ "bar\n", NULL, &d);
assert_non_null(html);
assert_string_equal(html,
"<h1 id=\"foo\">foo</h1>\n"
@@ -1671,7 +1221,7 @@ test_content_parse_description(void **state)
"> qwe\n"
"> zxc\n"
"\n"
- "bar\n", NULL, NULL, &d, NULL, NULL);
+ "bar\n", NULL, &d);
assert_non_null(html);
assert_string_equal(html,
"<h1 id=\"foo\">foo</h1>\n"
@@ -1693,7 +1243,7 @@ test_content_parse_description_crlf(void **state)
char *html = blogc_content_parse(
"# foo\r\n"
"\r\n"
- "bar", NULL, NULL, &d, NULL, NULL);
+ "bar", NULL, &d);
assert_non_null(html);
assert_string_equal(html,
"<h1 id=\"foo\">foo</h1>\r\n"
@@ -1706,7 +1256,7 @@ test_content_parse_description_crlf(void **state)
html = blogc_content_parse(
"# foo\r\n"
"\r\n"
- "bar\r\n", NULL, NULL, &d, NULL, NULL);
+ "bar\r\n", NULL, &d);
assert_non_null(html);
assert_string_equal(html,
"<h1 id=\"foo\">foo</h1>\r\n"
@@ -1720,7 +1270,7 @@ test_content_parse_description_crlf(void **state)
"# foo\r\n"
"\r\n"
"qwe\r\n"
- "bar\r\n", NULL, NULL, &d, NULL, NULL);
+ "bar\r\n", NULL, &d);
assert_non_null(html);
assert_string_equal(html,
"<h1 id=\"foo\">foo</h1>\r\n"
@@ -1736,7 +1286,7 @@ test_content_parse_description_crlf(void **state)
"\r\n"
"> qwe\r\n"
"\r\n"
- "bar\r\n", NULL, NULL, &d, NULL, NULL);
+ "bar\r\n", NULL, &d);
assert_non_null(html);
assert_string_equal(html,
"<h1 id=\"foo\">foo</h1>\r\n"
@@ -1754,7 +1304,7 @@ test_content_parse_description_crlf(void **state)
"> qwe\r\n"
"> zxc\r\n"
"\r\n"
- "bar\r\n", NULL, NULL, &d, NULL, NULL);
+ "bar\r\n", NULL, &d);
assert_non_null(html);
assert_string_equal(html,
"<h1 id=\"foo\">foo</h1>\r\n"
@@ -1770,110 +1320,9 @@ test_content_parse_description_crlf(void **state)
static void
-test_content_parse_endl(void **state)
-{
- char *n = NULL;
- char *html = blogc_content_parse("# test", NULL, NULL, NULL, &n, NULL);
- assert_non_null(html);
- assert_non_null(n);
- assert_string_equal(n, "\n");
- free(html);
- free(n);
- n = "\n";
- html = blogc_content_parse("# test", NULL, NULL, NULL, &n, NULL);
- assert_non_null(html);
- assert_non_null(n);
- assert_string_equal(n, "\n");
- free(html);
- n = NULL;
- html = blogc_content_parse(
- "# test\n", NULL, NULL, NULL, &n, NULL);
- assert_non_null(html);
- assert_non_null(n);
- assert_string_equal(n, "\n");
- free(html);
- free(n);
- n = NULL;
- html = blogc_content_parse(
- "# test\n"
- "foo", NULL, NULL, NULL, &n, NULL);
- assert_non_null(html);
- assert_non_null(n);
- assert_string_equal(n, "\n");
- free(html);
- free(n);
- n = NULL;
- html = blogc_content_parse(
- "# test\n"
- "foo\n", NULL, NULL, NULL, &n, NULL);
- assert_non_null(html);
- assert_non_null(n);
- assert_string_equal(n, "\n");
- free(html);
- free(n);
- n = NULL;
- html = blogc_content_parse(
- "# test\n"
- "foo\r\n", NULL, NULL, NULL, &n, NULL);
- assert_non_null(html);
- assert_non_null(n);
- assert_string_equal(n, "\n");
- free(html);
- free(n);
-}
-
-
-static void
-test_content_parse_endl_crlf(void **state)
-{
- char *n = "\r\n";
- char *html = blogc_content_parse("# test", NULL, NULL, NULL, &n, NULL);
- assert_non_null(html);
- assert_non_null(n);
- assert_string_equal(n, "\r\n");
- free(html);
- n = NULL;
- html = blogc_content_parse(
- "# test\r\n", NULL, NULL, NULL, &n, NULL);
- assert_non_null(html);
- assert_non_null(n);
- assert_string_equal(n, "\r\n");
- free(html);
- free(n);
- n = NULL;
- html = blogc_content_parse(
- "# test\r\n"
- "foo", NULL, NULL, NULL, &n, NULL);
- assert_non_null(html);
- assert_non_null(n);
- assert_string_equal(n, "\r\n");
- free(html);
- free(n);
- n = NULL;
- html = blogc_content_parse(
- "# test\r\n"
- "foo\r\n", NULL, NULL, NULL, &n, NULL);
- assert_non_null(html);
- assert_non_null(n);
- assert_string_equal(n, "\r\n");
- free(html);
- free(n);
- n = NULL;
- html = blogc_content_parse(
- "# test\r\n"
- "foo\n", NULL, NULL, NULL, &n, NULL);
- assert_non_null(html);
- assert_non_null(n);
- assert_string_equal(n, "\r\n");
- free(html);
- free(n);
-}
-
-
-static void
test_content_parse_invalid_excerpt(void **state)
{
- size_t l = 0;
+ char *l = NULL;
char *d = NULL;
char *html = blogc_content_parse(
"# test\n"
@@ -1882,9 +1331,9 @@ test_content_parse_invalid_excerpt(void **state)
"..\n"
"\n"
"guda\n"
- "lol", &l, NULL, &d, NULL, NULL);
+ "lol", &l, &d);
assert_non_null(html);
- assert_int_equal(l, 0);
+ assert_null(l);
assert_non_null(d);
assert_string_equal(d, "chunda ..");
assert_string_equal(html,
@@ -1894,7 +1343,6 @@ test_content_parse_invalid_excerpt(void **state)
"<p>guda\n"
"lol</p>\n");
free(html);
- l = 0;
free(d);
d = NULL;
html = blogc_content_parse(
@@ -1904,9 +1352,9 @@ test_content_parse_invalid_excerpt(void **state)
"\n"
"...\n"
"guda\n"
- "lol", &l, NULL, &d, NULL, NULL);
+ "lol", &l, &d);
assert_non_null(html);
- assert_int_equal(l, 0);
+ assert_null(l);
assert_non_null(d);
assert_string_equal(d, "chunda");
assert_string_equal(html,
@@ -1916,7 +1364,6 @@ test_content_parse_invalid_excerpt(void **state)
"guda\n"
"lol</p>\n");
free(html);
- l = 0;
free(d);
d = NULL;
html = blogc_content_parse(
@@ -1925,9 +1372,9 @@ test_content_parse_invalid_excerpt(void **state)
"chunda..\n"
"\n"
"guda\n"
- "lol", &l, NULL, &d, NULL, NULL);
+ "lol", &l, &d);
assert_non_null(html);
- assert_int_equal(l, 0);
+ assert_null(l);
assert_non_null(d);
assert_string_equal(d, "chunda..");
assert_string_equal(html,
@@ -1936,7 +1383,6 @@ test_content_parse_invalid_excerpt(void **state)
"<p>guda\n"
"lol</p>\n");
free(html);
- l = 0;
free(d);
d = NULL;
html = blogc_content_parse(
@@ -1945,9 +1391,9 @@ test_content_parse_invalid_excerpt(void **state)
"chunda\n"
"\n"
"...guda\n"
- "lol", &l, NULL, &d, NULL, NULL);
+ "lol", &l, &d);
assert_non_null(html);
- assert_int_equal(l, 0);
+ assert_null(l);
assert_non_null(d);
assert_string_equal(d, "chunda");
assert_string_equal(html,
@@ -1966,7 +1412,7 @@ test_content_parse_invalid_header(void **state)
char *html = blogc_content_parse(
"asd\n"
"\n"
- "##bola\n", NULL, NULL, NULL, NULL, NULL);
+ "##bola\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>asd</p>\n"
@@ -1983,7 +1429,7 @@ test_content_parse_invalid_header_empty(void **state)
"\n"
"##\n"
"\n"
- "qwe\n", NULL, NULL, NULL, NULL, NULL);
+ "qwe\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>asd</p>\n"
@@ -2000,7 +1446,7 @@ test_content_parse_invalid_blockquote(void **state)
char *html = blogc_content_parse(
"> asd\n"
"> bola\n"
- "> foo\n", NULL, NULL, NULL, NULL, NULL);
+ "> foo\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>&gt; asd\n"
@@ -2009,7 +1455,7 @@ test_content_parse_invalid_blockquote(void **state)
free(html);
html = blogc_content_parse(
"> asd\n"
- "> bola", NULL, NULL, NULL, NULL, NULL);
+ "> bola", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>&gt; asd\n"
@@ -2024,7 +1470,7 @@ test_content_parse_invalid_code(void **state)
char *html = blogc_content_parse(
" asd\n"
" bola\n"
- " foo\n", NULL, NULL, NULL, NULL, NULL);
+ " foo\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p> asd\n"
@@ -2034,7 +1480,7 @@ test_content_parse_invalid_code(void **state)
html = blogc_content_parse(
" asd\n"
" bola\n"
- " foo", NULL, NULL, NULL, NULL, NULL);
+ " foo", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p> asd\n"
@@ -2047,11 +1493,11 @@ test_content_parse_invalid_code(void **state)
static void
test_content_parse_invalid_horizontal_rule(void **state)
{
- char *html = blogc_content_parse("** asd", NULL, NULL, NULL, NULL, NULL);
+ char *html = blogc_content_parse("** asd", NULL, NULL);
assert_non_null(html);
assert_string_equal(html, "<p>** asd</p>\n");
free(html);
- html = blogc_content_parse("** asd\n", NULL, NULL, NULL, NULL, NULL);
+ html = blogc_content_parse("** asd\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html, "<p>** asd</p>\n");
free(html);
@@ -2063,7 +1509,7 @@ test_content_parse_invalid_unordered_list(void **state)
{
char *html = blogc_content_parse(
"* asd\n"
- "1. qwe", NULL, NULL, NULL, NULL, NULL);
+ "1. qwe", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>* asd\n"
@@ -2072,7 +1518,7 @@ test_content_parse_invalid_unordered_list(void **state)
html = blogc_content_parse(
"* asd\n"
"1. qwe\n"
- "\n", NULL, NULL, NULL, NULL, NULL);
+ "\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>* asd\n"
@@ -2080,7 +1526,7 @@ test_content_parse_invalid_unordered_list(void **state)
free(html);
html = blogc_content_parse(
"* asd\n"
- "1. qwe\n", NULL, NULL, NULL, NULL, NULL);
+ "1. qwe\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>* asd\n"
@@ -2089,7 +1535,7 @@ test_content_parse_invalid_unordered_list(void **state)
free(html);
html = blogc_content_parse(
"* asd\n"
- "1. qwe\n", NULL, NULL, NULL, NULL, NULL);
+ "1. qwe\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>* asd\n"
@@ -2102,7 +1548,7 @@ test_content_parse_invalid_unordered_list(void **state)
"* asd\n"
"1. qwe\n"
"\n"
- "poi\n", NULL, NULL, NULL, NULL, NULL);
+ "poi\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>chunda</p>\n"
@@ -2118,7 +1564,7 @@ test_content_parse_invalid_ordered_list(void **state)
{
char *html = blogc_content_parse(
"1. asd\n"
- "* qwe", NULL, NULL, NULL, NULL, NULL);
+ "* qwe", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>1. asd\n"
@@ -2127,7 +1573,7 @@ test_content_parse_invalid_ordered_list(void **state)
html = blogc_content_parse(
"1. asd\n"
"* qwe\n"
- "\n", NULL, NULL, NULL, NULL, NULL);
+ "\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>1. asd\n"
@@ -2135,7 +1581,7 @@ test_content_parse_invalid_ordered_list(void **state)
free(html);
html = blogc_content_parse(
"1. asd\n"
- "* qwe\n", NULL, NULL, NULL, NULL, NULL);
+ "* qwe\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>1. asd\n"
@@ -2144,7 +1590,7 @@ test_content_parse_invalid_ordered_list(void **state)
free(html);
html = blogc_content_parse(
"1. asd\n"
- "* qwe\n", NULL, NULL, NULL, NULL, NULL);
+ "* qwe\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>1. asd\n"
@@ -2157,7 +1603,7 @@ test_content_parse_invalid_ordered_list(void **state)
"1. asd\n"
"* qwe\n"
"\n"
- "poi\n", NULL, NULL, NULL, NULL, NULL);
+ "poi\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>chunda</p>\n"
@@ -2167,7 +1613,7 @@ test_content_parse_invalid_ordered_list(void **state)
free(html);
html = blogc_content_parse(
"1 asd\n"
- "* qwe\n", NULL, NULL, NULL, NULL, NULL);
+ "* qwe\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>1 asd\n"
@@ -2175,7 +1621,7 @@ test_content_parse_invalid_ordered_list(void **state)
free(html);
html = blogc_content_parse(
"a. asd\n"
- "2. qwe\n", NULL, NULL, NULL, NULL, NULL);
+ "2. qwe\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>a. asd\n"
@@ -2183,18 +1629,18 @@ test_content_parse_invalid_ordered_list(void **state)
free(html);
html = blogc_content_parse(
"1.\nasd\n"
- "2. qwe\n", NULL, NULL, NULL, NULL, NULL);
+ "2. qwe\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html,
"<p>1.\n"
"asd\n"
"2. qwe</p>\n");
free(html);
- html = blogc_content_parse("1.\n", NULL, NULL, NULL, NULL, NULL);
+ html = blogc_content_parse("1.\n", NULL, NULL);
assert_non_null(html);
assert_string_equal(html, "<p>1.</p>\n");
free(html);
- html = blogc_content_parse("1 ", NULL, NULL, NULL, NULL, NULL);
+ html = blogc_content_parse("1 ", NULL, NULL);
assert_non_null(html);
assert_string_equal(html, "<p>1 </p>\n");
free(html);
@@ -2346,15 +1792,11 @@ test_content_parse_inline_code(void **state)
free(html);
html = blogc_content_parse_inline("`bo\\`\\`la`\n");
assert_non_null(html);
- assert_string_equal(html, "<code>bo\\`\\`la</code>\n");
+ assert_string_equal(html, "<code>bo``la</code>\n");
free(html);
html = blogc_content_parse_inline("``bo\\`\\`la``\n");
assert_non_null(html);
- assert_string_equal(html, "<code>bo\\`\\`la</code>\n");
- free(html);
- html = blogc_content_parse_inline("``bo`la``\n");
- assert_non_null(html);
- assert_string_equal(html, "<code>bo`la</code>\n");
+ assert_string_equal(html, "<code>bo``la</code>\n");
free(html);
html = blogc_content_parse_inline("``bola\n");
assert_non_null(html);
@@ -2408,11 +1850,7 @@ test_content_parse_inline_link(void **state)
free(html);
html = blogc_content_parse_inline("[``bola(2)[3]**!\\```](http://example.org/)\n");
assert_non_null(html);
- assert_string_equal(html, "<a href=\"http://example.org/\"><code>bola(2)[3]**!\\`</code></a>\n");
- free(html);
- html = blogc_content_parse_inline("[``bola(2)[3]**!```](http://example.org/)\n");
- assert_non_null(html);
- assert_string_equal(html, "<a href=\"http://example.org/\"><code>bola(2)[3]**!</code>`</a>\n");
+ assert_string_equal(html, "<a href=\"http://example.org/\"><code>bola(2)[3]**!`</code></a>\n");
free(html);
html = blogc_content_parse_inline("test suite!)\n"
"depends on [cmocka](http://cmocka.org/), though.\n");
@@ -2735,55 +2173,49 @@ test_content_parse_inline_endash_emdash(void **state)
int
main(void)
{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_slugify),
- cmocka_unit_test(test_htmlentities),
- cmocka_unit_test(test_fix_description),
- cmocka_unit_test(test_is_ordered_list_item),
- cmocka_unit_test(test_content_parse),
- cmocka_unit_test(test_content_parse_crlf),
- cmocka_unit_test(test_content_parse_with_excerpt),
- cmocka_unit_test(test_content_parse_with_excerpt_crlf),
- cmocka_unit_test(test_content_parse_header),
- cmocka_unit_test(test_content_parse_header_crlf),
- cmocka_unit_test(test_content_parse_html),
- cmocka_unit_test(test_content_parse_html_crlf),
- cmocka_unit_test(test_content_parse_blockquote),
- cmocka_unit_test(test_content_parse_blockquote_crlf),
- cmocka_unit_test(test_content_parse_code),
- cmocka_unit_test(test_content_parse_code_crlf),
- cmocka_unit_test(test_content_parse_horizontal_rule),
- cmocka_unit_test(test_content_parse_horizontal_rule_crlf),
- cmocka_unit_test(test_content_parse_unordered_list),
- cmocka_unit_test(test_content_parse_unordered_list_crlf),
- cmocka_unit_test(test_content_parse_ordered_list),
- cmocka_unit_test(test_content_parse_ordered_list_crlf),
- cmocka_unit_test(test_content_parse_first_header),
- cmocka_unit_test(test_content_parse_first_header_crlf),
- cmocka_unit_test(test_content_parse_headers),
- cmocka_unit_test(test_content_parse_headers_crlf),
- cmocka_unit_test(test_content_parse_description),
- cmocka_unit_test(test_content_parse_description_crlf),
- cmocka_unit_test(test_content_parse_endl),
- cmocka_unit_test(test_content_parse_endl_crlf),
- cmocka_unit_test(test_content_parse_invalid_excerpt),
- cmocka_unit_test(test_content_parse_invalid_header),
- cmocka_unit_test(test_content_parse_invalid_header_empty),
- cmocka_unit_test(test_content_parse_invalid_blockquote),
- cmocka_unit_test(test_content_parse_invalid_code),
- cmocka_unit_test(test_content_parse_invalid_horizontal_rule),
- cmocka_unit_test(test_content_parse_invalid_unordered_list),
- cmocka_unit_test(test_content_parse_invalid_ordered_list),
- cmocka_unit_test(test_content_parse_inline),
- cmocka_unit_test(test_content_parse_inline_em),
- cmocka_unit_test(test_content_parse_inline_strong),
- cmocka_unit_test(test_content_parse_inline_code),
- cmocka_unit_test(test_content_parse_inline_link),
- cmocka_unit_test(test_content_parse_inline_link_auto),
- cmocka_unit_test(test_content_parse_inline_image),
- cmocka_unit_test(test_content_parse_inline_line_break),
- cmocka_unit_test(test_content_parse_inline_line_break_crlf),
- cmocka_unit_test(test_content_parse_inline_endash_emdash),
+ const UnitTest tests[] = {
+ unit_test(test_slugify),
+ unit_test(test_htmlentities),
+ unit_test(test_fix_description),
+ unit_test(test_is_ordered_list_item),
+ unit_test(test_content_parse),
+ unit_test(test_content_parse_crlf),
+ unit_test(test_content_parse_with_excerpt),
+ unit_test(test_content_parse_with_excerpt_crlf),
+ unit_test(test_content_parse_header),
+ unit_test(test_content_parse_header_crlf),
+ unit_test(test_content_parse_html),
+ unit_test(test_content_parse_html_crlf),
+ unit_test(test_content_parse_blockquote),
+ unit_test(test_content_parse_blockquote_crlf),
+ unit_test(test_content_parse_code),
+ unit_test(test_content_parse_code_crlf),
+ unit_test(test_content_parse_horizontal_rule),
+ unit_test(test_content_parse_horizontal_rule_crlf),
+ unit_test(test_content_parse_unordered_list),
+ unit_test(test_content_parse_unordered_list_crlf),
+ unit_test(test_content_parse_ordered_list),
+ unit_test(test_content_parse_ordered_list_crlf),
+ unit_test(test_content_parse_description),
+ unit_test(test_content_parse_description_crlf),
+ unit_test(test_content_parse_invalid_excerpt),
+ unit_test(test_content_parse_invalid_header),
+ unit_test(test_content_parse_invalid_header_empty),
+ unit_test(test_content_parse_invalid_blockquote),
+ unit_test(test_content_parse_invalid_code),
+ unit_test(test_content_parse_invalid_horizontal_rule),
+ unit_test(test_content_parse_invalid_unordered_list),
+ unit_test(test_content_parse_invalid_ordered_list),
+ unit_test(test_content_parse_inline),
+ unit_test(test_content_parse_inline_em),
+ unit_test(test_content_parse_inline_strong),
+ unit_test(test_content_parse_inline_code),
+ unit_test(test_content_parse_inline_link),
+ unit_test(test_content_parse_inline_link_auto),
+ unit_test(test_content_parse_inline_image),
+ unit_test(test_content_parse_inline_line_break),
+ unit_test(test_content_parse_inline_line_break_crlf),
+ unit_test(test_content_parse_inline_endash_emdash),
};
- return cmocka_run_group_tests(tests, NULL, NULL);
+ return run_tests(tests);
}
diff --git a/tests/blogc/check_datetime_parser.c b/tests/check_datetime_parser.c
index fe0ddd8..03f5a9a 100644
--- a/tests/blogc/check_datetime_parser.c
+++ b/tests/check_datetime_parser.c
@@ -1,6 +1,6 @@
/*
* blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
*
* This program can be distributed under the terms of the BSD License.
* See the file LICENSE.
@@ -12,14 +12,14 @@
#include <cmocka.h>
#include <stdlib.h>
#include <locale.h>
-#include "../../src/common/error.h"
-#include "../../src/blogc/datetime-parser.h"
+#include "../src/error.h"
+#include "../src/datetime-parser.h"
static void
test_convert_datetime(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-11-30 12:13:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(err);
@@ -31,7 +31,7 @@ test_convert_datetime(void **state)
static void
test_convert_datetime_implicit_seconds(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-11-30 12:13",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(err);
@@ -43,7 +43,7 @@ test_convert_datetime_implicit_seconds(void **state)
static void
test_convert_datetime_implicit_minutes(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-11-30 12",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(err);
@@ -55,7 +55,7 @@ test_convert_datetime_implicit_minutes(void **state)
static void
test_convert_datetime_implicit_hours(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-11-30",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(err);
@@ -67,7 +67,7 @@ test_convert_datetime_implicit_hours(void **state)
static void
test_convert_datetime_invalid_formats(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("", "%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
assert_non_null(err);
@@ -76,7 +76,7 @@ test_convert_datetime_invalid_formats(void **state)
"Invalid datetime string. Found '', formats allowed are: "
"'yyyy-mm-dd hh:mm:ss', 'yyyy-mm-dd hh:ss', 'yyyy-mm-dd hh' and "
"'yyyy-mm-dd'.");
- bc_error_free(err);
+ blogc_error_free(err);
err = NULL;
dt = blogc_convert_datetime("2", "%b %d, %Y, %I:%M:%S %p GMT", &err);
@@ -87,7 +87,7 @@ test_convert_datetime_invalid_formats(void **state)
"Invalid datetime string. Found '2', formats allowed are: "
"'yyyy-mm-dd hh:mm:ss', 'yyyy-mm-dd hh:ss', 'yyyy-mm-dd hh' and "
"'yyyy-mm-dd'.");
- bc_error_free(err);
+ blogc_error_free(err);
err = NULL;
dt = blogc_convert_datetime("20", "%b %d, %Y, %I:%M:%S %p GMT", &err);
@@ -98,7 +98,7 @@ test_convert_datetime_invalid_formats(void **state)
"Invalid datetime string. Found '20', formats allowed are: "
"'yyyy-mm-dd hh:mm:ss', 'yyyy-mm-dd hh:ss', 'yyyy-mm-dd hh' and "
"'yyyy-mm-dd'.");
- bc_error_free(err);
+ blogc_error_free(err);
err = NULL;
dt = blogc_convert_datetime("201", "%b %d, %Y, %I:%M:%S %p GMT", &err);
@@ -109,7 +109,7 @@ test_convert_datetime_invalid_formats(void **state)
"Invalid datetime string. Found '201', formats allowed are: "
"'yyyy-mm-dd hh:mm:ss', 'yyyy-mm-dd hh:ss', 'yyyy-mm-dd hh' and "
"'yyyy-mm-dd'.");
- bc_error_free(err);
+ blogc_error_free(err);
err = NULL;
dt = blogc_convert_datetime("2010", "%b %d, %Y, %I:%M:%S %p GMT", &err);
@@ -120,7 +120,7 @@ test_convert_datetime_invalid_formats(void **state)
"Invalid datetime string. Found '2010', formats allowed are: "
"'yyyy-mm-dd hh:mm:ss', 'yyyy-mm-dd hh:ss', 'yyyy-mm-dd hh' and "
"'yyyy-mm-dd'.");
- bc_error_free(err);
+ blogc_error_free(err);
err = NULL;
dt = blogc_convert_datetime("2010-", "%b %d, %Y, %I:%M:%S %p GMT", &err);
@@ -131,7 +131,7 @@ test_convert_datetime_invalid_formats(void **state)
"Invalid datetime string. Found '2010-', formats allowed are: "
"'yyyy-mm-dd hh:mm:ss', 'yyyy-mm-dd hh:ss', 'yyyy-mm-dd hh' and "
"'yyyy-mm-dd'.");
- bc_error_free(err);
+ blogc_error_free(err);
err = NULL;
dt = blogc_convert_datetime("2010-1", "%b %d, %Y, %I:%M:%S %p GMT", &err);
@@ -142,7 +142,7 @@ test_convert_datetime_invalid_formats(void **state)
"Invalid datetime string. Found '2010-1', formats allowed are: "
"'yyyy-mm-dd hh:mm:ss', 'yyyy-mm-dd hh:ss', 'yyyy-mm-dd hh' and "
"'yyyy-mm-dd'.");
- bc_error_free(err);
+ blogc_error_free(err);
err = NULL;
dt = blogc_convert_datetime("2010-11", "%b %d, %Y, %I:%M:%S %p GMT", &err);
@@ -153,7 +153,7 @@ test_convert_datetime_invalid_formats(void **state)
"Invalid datetime string. Found '2010-11', formats allowed are: "
"'yyyy-mm-dd hh:mm:ss', 'yyyy-mm-dd hh:ss', 'yyyy-mm-dd hh' and "
"'yyyy-mm-dd'.");
- bc_error_free(err);
+ blogc_error_free(err);
err = NULL;
dt = blogc_convert_datetime("2010-11-", "%b %d, %Y, %I:%M:%S %p GMT", &err);
@@ -164,7 +164,7 @@ test_convert_datetime_invalid_formats(void **state)
"Invalid datetime string. Found '2010-11-', formats allowed are: "
"'yyyy-mm-dd hh:mm:ss', 'yyyy-mm-dd hh:ss', 'yyyy-mm-dd hh' and "
"'yyyy-mm-dd'.");
- bc_error_free(err);
+ blogc_error_free(err);
err = NULL;
dt = blogc_convert_datetime("2010-11-3", "%b %d, %Y, %I:%M:%S %p GMT", &err);
@@ -175,7 +175,7 @@ test_convert_datetime_invalid_formats(void **state)
"Invalid datetime string. Found '2010-11-3', formats allowed are: "
"'yyyy-mm-dd hh:mm:ss', 'yyyy-mm-dd hh:ss', 'yyyy-mm-dd hh' and "
"'yyyy-mm-dd'.");
- bc_error_free(err);
+ blogc_error_free(err);
err = NULL;
dt = blogc_convert_datetime("2010-11-30 ", "%b %d, %Y, %I:%M:%S %p GMT", &err);
@@ -186,7 +186,7 @@ test_convert_datetime_invalid_formats(void **state)
"Invalid datetime string. Found '2010-11-30 ', formats allowed are: "
"'yyyy-mm-dd hh:mm:ss', 'yyyy-mm-dd hh:ss', 'yyyy-mm-dd hh' and "
"'yyyy-mm-dd'.");
- bc_error_free(err);
+ blogc_error_free(err);
err = NULL;
dt = blogc_convert_datetime("2010-11-30 1", "%b %d, %Y, %I:%M:%S %p GMT", &err);
@@ -197,7 +197,7 @@ test_convert_datetime_invalid_formats(void **state)
"Invalid datetime string. Found '2010-11-30 1', formats allowed are: "
"'yyyy-mm-dd hh:mm:ss', 'yyyy-mm-dd hh:ss', 'yyyy-mm-dd hh' and "
"'yyyy-mm-dd'.");
- bc_error_free(err);
+ blogc_error_free(err);
err = NULL;
dt = blogc_convert_datetime("2010-11-30 12:1", "%b %d, %Y, %I:%M:%S %p GMT",
@@ -209,7 +209,7 @@ test_convert_datetime_invalid_formats(void **state)
"Invalid datetime string. Found '2010-11-30 12:1', formats allowed are: "
"'yyyy-mm-dd hh:mm:ss', 'yyyy-mm-dd hh:ss', 'yyyy-mm-dd hh' and "
"'yyyy-mm-dd'.");
- bc_error_free(err);
+ blogc_error_free(err);
err = NULL;
dt = blogc_convert_datetime("2010-11-30 12:13:1", "%b %d, %Y, %I:%M:%S %p GMT",
@@ -221,14 +221,14 @@ test_convert_datetime_invalid_formats(void **state)
"Invalid datetime string. Found '2010-11-30 12:13:1', formats allowed are: "
"'yyyy-mm-dd hh:mm:ss', 'yyyy-mm-dd hh:ss', 'yyyy-mm-dd hh' and "
"'yyyy-mm-dd'.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_1st_year(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("a010-11-30 12:13:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -236,14 +236,14 @@ test_convert_datetime_invalid_1st_year(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid first digit of year. Found 'a', must be integer >= 0 and <= 9.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_2nd_year(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2a10-11-30 12:13:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -251,14 +251,14 @@ test_convert_datetime_invalid_2nd_year(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid second digit of year. Found 'a', must be integer >= 0 and <= 9.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_3rd_year(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("20a0-11-30 12:13:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -266,14 +266,14 @@ test_convert_datetime_invalid_3rd_year(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid third digit of year. Found 'a', must be integer >= 0 and <= 9.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_4th_year(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("201a-11-30 12:13:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -281,14 +281,14 @@ test_convert_datetime_invalid_4th_year(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid fourth digit of year. Found 'a', must be integer >= 0 and <= 9.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_year(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("1899-11-30 12:13:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -296,14 +296,14 @@ test_convert_datetime_invalid_year(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid year. Found 1899, must be >= 1900.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_1st_hyphen(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010 11-30 12:13:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -311,14 +311,14 @@ test_convert_datetime_invalid_1st_hyphen(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid separator between year and month. Found ' ', must be '-'.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_1st_month(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-a1-30 12:13:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -326,14 +326,14 @@ test_convert_datetime_invalid_1st_month(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid first digit of month. Found 'a', must be integer >= 0 and <= 1.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_2nd_month(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-1a-30 12:13:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -341,14 +341,14 @@ test_convert_datetime_invalid_2nd_month(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid second digit of month. Found 'a', must be integer >= 0 and <= 9.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_month(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-13-30 12:13:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -356,14 +356,14 @@ test_convert_datetime_invalid_month(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid month. Found 13, must be >= 1 and <= 12.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_2nd_hyphen(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-11 30 12:13:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -371,14 +371,14 @@ test_convert_datetime_invalid_2nd_hyphen(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid separator between month and day. Found ' ', must be '-'.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_1st_day(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-11-a0 12:13:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -386,14 +386,14 @@ test_convert_datetime_invalid_1st_day(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid first digit of day. Found 'a', must be integer >= 0 and <= 3.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_2nd_day(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-11-3a 12:13:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -401,14 +401,14 @@ test_convert_datetime_invalid_2nd_day(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid second digit of day. Found 'a', must be integer >= 0 and <= 9.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_day(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-12-32 12:13:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -416,14 +416,14 @@ test_convert_datetime_invalid_day(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid day. Found 32, must be >= 1 and <= 31.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_space(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-11-30-12:13:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -432,14 +432,14 @@ test_convert_datetime_invalid_space(void **state)
assert_string_equal(err->msg,
"Invalid separator between date and time. Found '-', must be ' ' "
"(empty space).");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_1st_hours(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-11-30 a2:13:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -447,14 +447,14 @@ test_convert_datetime_invalid_1st_hours(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid first digit of hours. Found 'a', must be integer >= 0 and <= 2.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_2nd_hours(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-11-30 1a:13:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -462,14 +462,14 @@ test_convert_datetime_invalid_2nd_hours(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid second digit of hours. Found 'a', must be integer >= 0 and <= 9.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_hours(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-12-30 24:13:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -477,14 +477,14 @@ test_convert_datetime_invalid_hours(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid hours. Found 24, must be >= 0 and <= 23.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_1st_colon(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-11-30 12 13:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -492,14 +492,14 @@ test_convert_datetime_invalid_1st_colon(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid separator between hours and minutes. Found ' ', must be ':'.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_1st_minutes(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-11-30 12:a3:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -507,14 +507,14 @@ test_convert_datetime_invalid_1st_minutes(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid first digit of minutes. Found 'a', must be integer >= 0 and <= 5.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_2nd_minutes(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-11-30 12:1a:14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -522,14 +522,14 @@ test_convert_datetime_invalid_2nd_minutes(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid second digit of minutes. Found 'a', must be integer >= 0 and <= 9.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_2nd_colon(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-11-30 12:13 14",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -537,14 +537,14 @@ test_convert_datetime_invalid_2nd_colon(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid separator between minutes and seconds. Found ' ', must be ':'.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_1st_seconds(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-11-30 12:13:a4",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -552,14 +552,14 @@ test_convert_datetime_invalid_1st_seconds(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid first digit of seconds. Found 'a', must be integer >= 0 and <= 6.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_2nd_seconds(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-11-30 12:13:1a",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -567,14 +567,14 @@ test_convert_datetime_invalid_2nd_seconds(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid second digit of seconds. Found 'a', must be integer >= 0 and <= 9.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_seconds(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-12-30 12:13:69",
"%b %d, %Y, %I:%M:%S %p GMT", &err);
assert_null(dt);
@@ -582,14 +582,14 @@ test_convert_datetime_invalid_seconds(void **state)
assert_int_equal(err->type, BLOGC_WARNING_DATETIME_PARSER);
assert_string_equal(err->msg,
"Invalid seconds. Found 69, must be >= 0 and <= 60.");
- bc_error_free(err);
+ blogc_error_free(err);
}
static void
test_convert_datetime_invalid_format_long(void **state)
{
- bc_error_t *err = NULL;
+ blogc_error_t *err = NULL;
char *dt = blogc_convert_datetime("2010-12-30 12:13:14",
"bovhsuhxwybfrxoluiejaoqpmoylgvkrjtnuntmcgtupwabexkapnklvkwmddmplfqopvb"
"yjsiimtfdeveeeayqvvnthimbqotumngxxenurxhsvyaftwsfdtxqnjluvtcwfkomfffrk"
@@ -626,7 +626,7 @@ test_convert_datetime_invalid_format_long(void **state)
"uaeruwnphdjonqagjatjladqhvlxppyaqgvwpjqggnsccmkjvbxqykaejvgeajqpitkwsq"
"gmjiaopomnnlewidhgbgqlblotrnuyokspuvbckqhwnhmgcwyyitmlelnehdvclojvyswj"
"jgipsincitulscikxviaruryfraeqssykeftcphtndlfhdxokg");
- bc_error_free(err);
+ blogc_error_free(err);
}
@@ -634,38 +634,38 @@ int
main(void)
{
setlocale(LC_ALL, "C");
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_convert_datetime),
- cmocka_unit_test(test_convert_datetime_implicit_seconds),
- cmocka_unit_test(test_convert_datetime_implicit_minutes),
- cmocka_unit_test(test_convert_datetime_implicit_hours),
- cmocka_unit_test(test_convert_datetime_invalid_formats),
- cmocka_unit_test(test_convert_datetime_invalid_1st_year),
- cmocka_unit_test(test_convert_datetime_invalid_2nd_year),
- cmocka_unit_test(test_convert_datetime_invalid_3rd_year),
- cmocka_unit_test(test_convert_datetime_invalid_4th_year),
- cmocka_unit_test(test_convert_datetime_invalid_year),
- cmocka_unit_test(test_convert_datetime_invalid_1st_hyphen),
- cmocka_unit_test(test_convert_datetime_invalid_1st_month),
- cmocka_unit_test(test_convert_datetime_invalid_2nd_month),
- cmocka_unit_test(test_convert_datetime_invalid_month),
- cmocka_unit_test(test_convert_datetime_invalid_2nd_hyphen),
- cmocka_unit_test(test_convert_datetime_invalid_1st_day),
- cmocka_unit_test(test_convert_datetime_invalid_2nd_day),
- cmocka_unit_test(test_convert_datetime_invalid_day),
- cmocka_unit_test(test_convert_datetime_invalid_space),
- cmocka_unit_test(test_convert_datetime_invalid_1st_hours),
- cmocka_unit_test(test_convert_datetime_invalid_2nd_hours),
- cmocka_unit_test(test_convert_datetime_invalid_hours),
- cmocka_unit_test(test_convert_datetime_invalid_1st_colon),
- cmocka_unit_test(test_convert_datetime_invalid_1st_minutes),
- cmocka_unit_test(test_convert_datetime_invalid_2nd_minutes),
- //cmocka_unit_test(test_convert_datetime_invalid_minutes), // not possible
- cmocka_unit_test(test_convert_datetime_invalid_2nd_colon),
- cmocka_unit_test(test_convert_datetime_invalid_1st_seconds),
- cmocka_unit_test(test_convert_datetime_invalid_2nd_seconds),
- cmocka_unit_test(test_convert_datetime_invalid_seconds),
- cmocka_unit_test(test_convert_datetime_invalid_format_long),
+ const UnitTest tests[] = {
+ unit_test(test_convert_datetime),
+ unit_test(test_convert_datetime_implicit_seconds),
+ unit_test(test_convert_datetime_implicit_minutes),
+ unit_test(test_convert_datetime_implicit_hours),
+ unit_test(test_convert_datetime_invalid_formats),
+ unit_test(test_convert_datetime_invalid_1st_year),
+ unit_test(test_convert_datetime_invalid_2nd_year),
+ unit_test(test_convert_datetime_invalid_3rd_year),
+ unit_test(test_convert_datetime_invalid_4th_year),
+ unit_test(test_convert_datetime_invalid_year),
+ unit_test(test_convert_datetime_invalid_1st_hyphen),
+ unit_test(test_convert_datetime_invalid_1st_month),
+ unit_test(test_convert_datetime_invalid_2nd_month),
+ unit_test(test_convert_datetime_invalid_month),
+ unit_test(test_convert_datetime_invalid_2nd_hyphen),
+ unit_test(test_convert_datetime_invalid_1st_day),
+ unit_test(test_convert_datetime_invalid_2nd_day),
+ unit_test(test_convert_datetime_invalid_day),
+ unit_test(test_convert_datetime_invalid_space),
+ unit_test(test_convert_datetime_invalid_1st_hours),
+ unit_test(test_convert_datetime_invalid_2nd_hours),
+ unit_test(test_convert_datetime_invalid_hours),
+ unit_test(test_convert_datetime_invalid_1st_colon),
+ unit_test(test_convert_datetime_invalid_1st_minutes),
+ unit_test(test_convert_datetime_invalid_2nd_minutes),
+ //unit_test(test_convert_datetime_invalid_minutes), // not possible
+ unit_test(test_convert_datetime_invalid_2nd_colon),
+ unit_test(test_convert_datetime_invalid_1st_seconds),
+ unit_test(test_convert_datetime_invalid_2nd_seconds),
+ unit_test(test_convert_datetime_invalid_seconds),
+ unit_test(test_convert_datetime_invalid_format_long),
};
- return cmocka_run_group_tests(tests, NULL, NULL);
+ return run_tests(tests);
}
diff --git a/tests/common/check_error.c b/tests/check_error.c
index 658ad22..e844998 100644
--- a/tests/common/check_error.c
+++ b/tests/check_error.c
@@ -1,6 +1,6 @@
/*
* blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
*
* This program can be distributed under the terms of the BSD License.
* See the file LICENSE.
@@ -11,33 +11,28 @@
#include <setjmp.h>
#include <cmocka.h>
#include <string.h>
-#include "../../src/common/error.h"
+#include "../src/error.h"
static void
test_error_new(void **state)
{
- bc_error_t *error = bc_error_new(1, "bola %s");
+ blogc_error_t *error = blogc_error_new(1, "bola %s");
assert_non_null(error);
assert_int_equal(error->type, 1);
assert_string_equal(error->msg, "bola %s");
- bc_error_free(error);
+ blogc_error_free(error);
}
static void
test_error_new_printf(void **state)
{
- bc_error_t *error = bc_error_new_printf(2, NULL);
- assert_non_null(error);
- assert_int_equal(error->type, 2);
- assert_string_equal(error->msg, "");
- bc_error_free(error);
- error = bc_error_new_printf(2, "bola %s", "guda");
+ blogc_error_t *error = blogc_error_new_printf(2, "bola %s", "guda");
assert_non_null(error);
assert_int_equal(error->type, 2);
assert_string_equal(error->msg, "bola guda");
- bc_error_free(error);
+ blogc_error_free(error);
}
@@ -45,32 +40,32 @@ static void
test_error_parser(void **state)
{
const char *a = "bola\nguda\nchunda\n";
- bc_error_t *error = bc_error_parser(1, a, strlen(a), 11, "asd %d", 10);
+ blogc_error_t *error = blogc_error_parser(1, a, strlen(a), 11, "asd %d", 10);
assert_non_null(error);
assert_int_equal(error->type, 1);
assert_string_equal(error->msg,
"asd 10\nError occurred near line 3, position 2: chunda");
- bc_error_free(error);
+ blogc_error_free(error);
a = "bola\nguda\nchunda";
- error = bc_error_parser(1, a, strlen(a), 11, "asd %d", 10);
+ error = blogc_error_parser(1, a, strlen(a), 11, "asd %d", 10);
assert_non_null(error);
assert_int_equal(error->type, 1);
assert_string_equal(error->msg,
"asd 10\nError occurred near line 3, position 2: chunda");
- bc_error_free(error);
+ blogc_error_free(error);
a = "bola\nguda\nchunda";
- error = bc_error_parser(1, a, strlen(a), 0, "asd %d", 10);
+ error = blogc_error_parser(1, a, strlen(a), 0, "asd %d", 10);
assert_non_null(error);
assert_int_equal(error->type, 1);
assert_string_equal(error->msg,
"asd 10\nError occurred near line 1, position 1: bola");
- bc_error_free(error);
+ blogc_error_free(error);
a = "";
- error = bc_error_parser(1, a, strlen(a), 0, "asd %d", 10);
+ error = blogc_error_parser(1, a, strlen(a), 0, "asd %d", 10);
assert_non_null(error);
assert_int_equal(error->type, 1);
assert_string_equal(error->msg, "asd 10");
- bc_error_free(error);
+ blogc_error_free(error);
}
@@ -78,37 +73,37 @@ static void
test_error_parser_crlf(void **state)
{
const char *a = "bola\r\nguda\r\nchunda\r\n";
- bc_error_t *error = bc_error_parser(1, a, strlen(a), 13, "asd %d", 10);
+ blogc_error_t *error = blogc_error_parser(1, a, strlen(a), 13, "asd %d", 10);
assert_non_null(error);
assert_int_equal(error->type, 1);
assert_string_equal(error->msg,
"asd 10\nError occurred near line 3, position 2: chunda");
- bc_error_free(error);
+ blogc_error_free(error);
a = "bola\r\nguda\r\nchunda";
- error = bc_error_parser(1, a, strlen(a), 13, "asd %d", 10);
+ error = blogc_error_parser(1, a, strlen(a), 13, "asd %d", 10);
assert_non_null(error);
assert_int_equal(error->type, 1);
assert_string_equal(error->msg,
"asd 10\nError occurred near line 3, position 2: chunda");
- bc_error_free(error);
+ blogc_error_free(error);
a = "bola\r\nguda\r\nchunda";
- error = bc_error_parser(1, a, strlen(a), 0, "asd %d", 10);
+ error = blogc_error_parser(1, a, strlen(a), 0, "asd %d", 10);
assert_non_null(error);
assert_int_equal(error->type, 1);
assert_string_equal(error->msg,
"asd 10\nError occurred near line 1, position 1: bola");
- bc_error_free(error);
+ blogc_error_free(error);
}
int
main(void)
{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_error_new),
- cmocka_unit_test(test_error_new_printf),
- cmocka_unit_test(test_error_parser),
- cmocka_unit_test(test_error_parser_crlf),
+ const UnitTest tests[] = {
+ unit_test(test_error_new),
+ unit_test(test_error_new_printf),
+ unit_test(test_error_parser),
+ unit_test(test_error_parser_crlf),
};
- return cmocka_run_group_tests(tests, NULL, NULL);
+ return run_tests(tests);
}
diff --git a/tests/check_loader.c b/tests/check_loader.c
new file mode 100644
index 0000000..44468c8
--- /dev/null
+++ b/tests/check_loader.c
@@ -0,0 +1,771 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "../src/error.h"
+#include "../src/template-parser.h"
+#include "../src/loader.h"
+#include "../src/utils.h"
+
+
+static void
+test_get_filename(void **state)
+{
+ char *f = blogc_get_filename("/home/foo/asd/bola.txt");
+ assert_string_equal(f, "bola");
+ free(f);
+ f = blogc_get_filename("/home/foo/asd/bola.guda.txt");
+ assert_string_equal(f, "bola.guda");
+ free(f);
+ f = blogc_get_filename("bola.txt");
+ assert_string_equal(f, "bola");
+ free(f);
+ f = blogc_get_filename("bola.guda.txt");
+ assert_string_equal(f, "bola.guda");
+ free(f);
+ f = blogc_get_filename("/home/foo/asd/bola");
+ assert_string_equal(f, "bola");
+ free(f);
+ f = blogc_get_filename("bola");
+ assert_string_equal(f, "bola");
+ free(f);
+ f = blogc_get_filename("");
+ assert_null(f);
+ free(f);
+ f = blogc_get_filename(NULL);
+ assert_null(f);
+ free(f);
+}
+
+
+char*
+__wrap_blogc_file_get_contents(const char *path, size_t *len, blogc_error_t **err)
+{
+ assert_null(*err);
+ const char *_path = mock_type(const char*);
+ if (_path != NULL)
+ assert_string_equal(path, _path);
+ char *rv = mock_type(char*);
+ *len = 0;
+ if (rv != NULL)
+ *len = strlen(rv);
+ return rv;
+}
+
+
+int
+__wrap_blogc_fprintf(FILE *stream, const char *format, ...)
+{
+ assert_true(stream == mock_type(FILE*));
+ assert_string_equal(format, mock_type(const char*));
+ return strlen(format);
+}
+
+
+static void
+test_template_parse_from_file(void **state)
+{
+ blogc_error_t *err = NULL;
+ will_return(__wrap_blogc_file_get_contents, "bola");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup("{{ BOLA }}\n"));
+ sb_slist_t *l = blogc_template_parse_from_file("bola", &err);
+ assert_null(err);
+ assert_non_null(l);
+ assert_int_equal(sb_slist_length(l), 2);
+ blogc_template_free_stmts(l);
+}
+
+
+static void
+test_template_parse_from_file_null(void **state)
+{
+ blogc_error_t *err = NULL;
+ will_return(__wrap_blogc_file_get_contents, "bola");
+ will_return(__wrap_blogc_file_get_contents, NULL);
+ sb_slist_t *l = blogc_template_parse_from_file("bola", &err);
+ assert_null(err);
+ assert_null(l);
+}
+
+
+static void
+test_source_parse_from_file(void **state)
+{
+ blogc_error_t *err = NULL;
+ will_return(__wrap_blogc_file_get_contents, "bola.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 123\n"
+ "--------\n"
+ "bola"));
+ sb_trie_t *t = blogc_source_parse_from_file("bola.txt", &err);
+ assert_null(err);
+ assert_non_null(t);
+ assert_int_equal(sb_trie_size(t), 6);
+ assert_string_equal(sb_trie_lookup(t, "ASD"), "123");
+ assert_string_equal(sb_trie_lookup(t, "FILENAME"), "bola");
+ assert_string_equal(sb_trie_lookup(t, "EXCERPT"), "<p>bola</p>\n");
+ assert_string_equal(sb_trie_lookup(t, "CONTENT"), "<p>bola</p>\n");
+ assert_string_equal(sb_trie_lookup(t, "RAW_CONTENT"), "bola");
+ assert_string_equal(sb_trie_lookup(t, "DESCRIPTION"), "bola");
+ sb_trie_free(t);
+}
+
+
+static void
+test_source_parse_from_file_null(void **state)
+{
+ blogc_error_t *err = NULL;
+ will_return(__wrap_blogc_file_get_contents, "bola.txt");
+ will_return(__wrap_blogc_file_get_contents, NULL);
+ sb_trie_t *t = blogc_source_parse_from_file("bola.txt", &err);
+ assert_null(err);
+ assert_null(t);
+}
+
+
+static void
+test_source_parse_from_files(void **state)
+{
+ will_return(__wrap_blogc_file_get_contents, "bola1.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 123\n"
+ "DATE: 2001-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola2.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 456\n"
+ "DATE: 2002-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola3.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 789\n"
+ "DATE: 2003-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ blogc_error_t *err = NULL;
+ sb_slist_t *s = NULL;
+ s = sb_slist_append(s, sb_strdup("bola1.txt"));
+ s = sb_slist_append(s, sb_strdup("bola2.txt"));
+ s = sb_slist_append(s, sb_strdup("bola3.txt"));
+ sb_trie_t *c = sb_trie_new(free);
+ sb_slist_t *t = blogc_source_parse_from_files(c, s, &err);
+ assert_null(err);
+ assert_non_null(t);
+ assert_int_equal(sb_slist_length(t), 3); // it is enough, no need to look at the items
+ assert_int_equal(sb_trie_size(c), 4);
+ assert_string_equal(sb_trie_lookup(c, "FILENAME_FIRST"), "bola1");
+ assert_string_equal(sb_trie_lookup(c, "FILENAME_LAST"), "bola3");
+ assert_string_equal(sb_trie_lookup(c, "DATE_FIRST"), "2001-02-03 04:05:06");
+ assert_string_equal(sb_trie_lookup(c, "DATE_LAST"), "2003-02-03 04:05:06");
+ sb_trie_free(c);
+ sb_slist_free_full(s, free);
+ sb_slist_free_full(t, (sb_free_func_t) sb_trie_free);
+}
+
+
+static void
+test_source_parse_from_files_filter_by_tag(void **state)
+{
+ will_return(__wrap_blogc_file_get_contents, "bola1.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 123\n"
+ "DATE: 2001-02-03 04:05:06\n"
+ "TAGS: chunda\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola2.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 456\n"
+ "DATE: 2002-02-03 04:05:06\n"
+ "TAGS: bola, chunda\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola3.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 789\n"
+ "DATE: 2003-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ blogc_error_t *err = NULL;
+ sb_slist_t *s = NULL;
+ s = sb_slist_append(s, sb_strdup("bola1.txt"));
+ s = sb_slist_append(s, sb_strdup("bola2.txt"));
+ s = sb_slist_append(s, sb_strdup("bola3.txt"));
+ sb_trie_t *c = sb_trie_new(free);
+ sb_trie_insert(c, "FILTER_TAG", sb_strdup("chunda"));
+ sb_slist_t *t = blogc_source_parse_from_files(c, s, &err);
+ assert_null(err);
+ assert_non_null(t);
+ assert_int_equal(sb_slist_length(t), 2); // it is enough, no need to look at the items
+ assert_int_equal(sb_trie_size(c), 5);
+ assert_string_equal(sb_trie_lookup(c, "FILENAME_FIRST"), "bola1");
+ assert_string_equal(sb_trie_lookup(c, "FILENAME_LAST"), "bola2");
+ assert_string_equal(sb_trie_lookup(c, "DATE_FIRST"), "2001-02-03 04:05:06");
+ assert_string_equal(sb_trie_lookup(c, "DATE_LAST"), "2002-02-03 04:05:06");
+ assert_string_equal(sb_trie_lookup(c, "FILTER_TAG"), "chunda");
+ sb_trie_free(c);
+ sb_slist_free_full(s, free);
+ sb_slist_free_full(t, (sb_free_func_t) sb_trie_free);
+}
+
+
+static void
+test_source_parse_from_files_filter_by_page(void **state)
+{
+ will_return(__wrap_blogc_file_get_contents, "bola1.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 123\n"
+ "DATE: 2001-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola2.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 456\n"
+ "DATE: 2002-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola3.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 789\n"
+ "DATE: 2003-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola4.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7891\n"
+ "DATE: 2004-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola5.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7892\n"
+ "DATE: 2005-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola6.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7893\n"
+ "DATE: 2006-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola7.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7894\n"
+ "DATE: 2007-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ blogc_error_t *err = NULL;
+ sb_slist_t *s = NULL;
+ s = sb_slist_append(s, sb_strdup("bola1.txt"));
+ s = sb_slist_append(s, sb_strdup("bola2.txt"));
+ s = sb_slist_append(s, sb_strdup("bola3.txt"));
+ s = sb_slist_append(s, sb_strdup("bola4.txt"));
+ s = sb_slist_append(s, sb_strdup("bola5.txt"));
+ s = sb_slist_append(s, sb_strdup("bola6.txt"));
+ s = sb_slist_append(s, sb_strdup("bola7.txt"));
+ sb_trie_t *c = sb_trie_new(free);
+ sb_trie_insert(c, "FILTER_PAGE", sb_strdup("1"));
+ sb_trie_insert(c, "FILTER_PER_PAGE", sb_strdup("2"));
+ sb_slist_t *t = blogc_source_parse_from_files(c, s, &err);
+ assert_null(err);
+ assert_non_null(t);
+ assert_int_equal(sb_slist_length(t), 2); // it is enough, no need to look at the items
+ assert_int_equal(sb_trie_size(c), 10);
+ assert_string_equal(sb_trie_lookup(c, "FILENAME_FIRST"), "bola1");
+ assert_string_equal(sb_trie_lookup(c, "FILENAME_LAST"), "bola2");
+ assert_string_equal(sb_trie_lookup(c, "DATE_FIRST"), "2001-02-03 04:05:06");
+ assert_string_equal(sb_trie_lookup(c, "DATE_LAST"), "2002-02-03 04:05:06");
+ assert_string_equal(sb_trie_lookup(c, "FILTER_PAGE"), "1");
+ assert_string_equal(sb_trie_lookup(c, "FILTER_PER_PAGE"), "2");
+ assert_string_equal(sb_trie_lookup(c, "CURRENT_PAGE"), "1");
+ assert_string_equal(sb_trie_lookup(c, "NEXT_PAGE"), "2");
+ assert_string_equal(sb_trie_lookup(c, "FIRST_PAGE"), "1");
+ assert_string_equal(sb_trie_lookup(c, "LAST_PAGE"), "4");
+ sb_trie_free(c);
+ sb_slist_free_full(s, free);
+ sb_slist_free_full(t, (sb_free_func_t) sb_trie_free);
+}
+
+
+static void
+test_source_parse_from_files_filter_by_page2(void **state)
+{
+ will_return(__wrap_blogc_file_get_contents, "bola1.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 123\n"
+ "DATE: 2001-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola2.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 456\n"
+ "DATE: 2002-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola3.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 789\n"
+ "DATE: 2003-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola4.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7891\n"
+ "DATE: 2004-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola5.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7892\n"
+ "DATE: 2005-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola6.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7893\n"
+ "DATE: 2006-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola7.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7894\n"
+ "DATE: 2007-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ blogc_error_t *err = NULL;
+ sb_slist_t *s = NULL;
+ s = sb_slist_append(s, sb_strdup("bola1.txt"));
+ s = sb_slist_append(s, sb_strdup("bola2.txt"));
+ s = sb_slist_append(s, sb_strdup("bola3.txt"));
+ s = sb_slist_append(s, sb_strdup("bola4.txt"));
+ s = sb_slist_append(s, sb_strdup("bola5.txt"));
+ s = sb_slist_append(s, sb_strdup("bola6.txt"));
+ s = sb_slist_append(s, sb_strdup("bola7.txt"));
+ sb_trie_t *c = sb_trie_new(free);
+ sb_trie_insert(c, "FILTER_PAGE", sb_strdup("3"));
+ sb_trie_insert(c, "FILTER_PER_PAGE", sb_strdup("2"));
+ sb_slist_t *t = blogc_source_parse_from_files(c, s, &err);
+ assert_null(err);
+ assert_non_null(t);
+ assert_int_equal(sb_slist_length(t), 2); // it is enough, no need to look at the items
+ assert_int_equal(sb_trie_size(c), 11);
+ assert_string_equal(sb_trie_lookup(c, "FILENAME_FIRST"), "bola5");
+ assert_string_equal(sb_trie_lookup(c, "FILENAME_LAST"), "bola6");
+ assert_string_equal(sb_trie_lookup(c, "DATE_FIRST"), "2005-02-03 04:05:06");
+ assert_string_equal(sb_trie_lookup(c, "DATE_LAST"), "2006-02-03 04:05:06");
+ assert_string_equal(sb_trie_lookup(c, "FILTER_PAGE"), "3");
+ assert_string_equal(sb_trie_lookup(c, "FILTER_PER_PAGE"), "2");
+ assert_string_equal(sb_trie_lookup(c, "CURRENT_PAGE"), "3");
+ assert_string_equal(sb_trie_lookup(c, "PREVIOUS_PAGE"), "2");
+ assert_string_equal(sb_trie_lookup(c, "NEXT_PAGE"), "4");
+ assert_string_equal(sb_trie_lookup(c, "FIRST_PAGE"), "1");
+ assert_string_equal(sb_trie_lookup(c, "LAST_PAGE"), "4");
+ sb_trie_free(c);
+ sb_slist_free_full(s, free);
+ sb_slist_free_full(t, (sb_free_func_t) sb_trie_free);
+}
+
+
+static void
+test_source_parse_from_files_filter_by_page3(void **state)
+{
+ will_return(__wrap_blogc_file_get_contents, "bola1.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 123\n"
+ "DATE: 2001-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola2.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 456\n"
+ "DATE: 2002-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola3.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 789\n"
+ "DATE: 2003-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola4.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7891\n"
+ "DATE: 2004-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola5.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7892\n"
+ "DATE: 2005-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola6.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7893\n"
+ "DATE: 2006-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola7.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7894\n"
+ "DATE: 2007-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ blogc_error_t *err = NULL;
+ sb_slist_t *s = NULL;
+ s = sb_slist_append(s, sb_strdup("bola1.txt"));
+ s = sb_slist_append(s, sb_strdup("bola2.txt"));
+ s = sb_slist_append(s, sb_strdup("bola3.txt"));
+ s = sb_slist_append(s, sb_strdup("bola4.txt"));
+ s = sb_slist_append(s, sb_strdup("bola5.txt"));
+ s = sb_slist_append(s, sb_strdup("bola6.txt"));
+ s = sb_slist_append(s, sb_strdup("bola7.txt"));
+ sb_trie_t *c = sb_trie_new(free);
+ sb_trie_insert(c, "FILTER_PAGE", sb_strdup("1"));
+ sb_trie_insert(c, "FILTER_PER_PAGE", sb_strdup("2"));
+ sb_slist_t *t = blogc_source_parse_from_files(c, s, &err);
+ assert_null(err);
+ assert_non_null(t);
+ assert_int_equal(sb_slist_length(t), 2); // it is enough, no need to look at the items
+ assert_int_equal(sb_trie_size(c), 10);
+ assert_string_equal(sb_trie_lookup(c, "FILENAME_FIRST"), "bola1");
+ assert_string_equal(sb_trie_lookup(c, "FILENAME_LAST"), "bola2");
+ assert_string_equal(sb_trie_lookup(c, "DATE_FIRST"), "2001-02-03 04:05:06");
+ assert_string_equal(sb_trie_lookup(c, "DATE_LAST"), "2002-02-03 04:05:06");
+ assert_string_equal(sb_trie_lookup(c, "FILTER_PAGE"), "1");
+ assert_string_equal(sb_trie_lookup(c, "FILTER_PER_PAGE"), "2");
+ assert_string_equal(sb_trie_lookup(c, "CURRENT_PAGE"), "1");
+ assert_string_equal(sb_trie_lookup(c, "NEXT_PAGE"), "2");
+ assert_string_equal(sb_trie_lookup(c, "FIRST_PAGE"), "1");
+ assert_string_equal(sb_trie_lookup(c, "LAST_PAGE"), "4");
+ sb_trie_free(c);
+ sb_slist_free_full(s, free);
+ sb_slist_free_full(t, (sb_free_func_t) sb_trie_free);
+}
+
+
+static void
+test_source_parse_from_files_filter_by_page_and_tag(void **state)
+{
+ will_return(__wrap_blogc_file_get_contents, "bola1.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 123\n"
+ "DATE: 2001-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola2.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 456\n"
+ "DATE: 2002-02-03 04:05:06\n"
+ "TAGS: chunda\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola3.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 789\n"
+ "DATE: 2003-02-03 04:05:06\n"
+ "TAGS: chunda bola\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola4.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7891\n"
+ "DATE: 2004-02-03 04:05:06\n"
+ "TAGS: bola\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola5.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7892\n"
+ "DATE: 2005-02-03 04:05:06\n"
+ "TAGS: chunda\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola6.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7893\n"
+ "DATE: 2006-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola7.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7894\n"
+ "DATE: 2007-02-03 04:05:06\n"
+ "TAGS: yay chunda\n"
+ "--------\n"
+ "bola"));
+ blogc_error_t *err = NULL;
+ sb_slist_t *s = NULL;
+ s = sb_slist_append(s, sb_strdup("bola1.txt"));
+ s = sb_slist_append(s, sb_strdup("bola2.txt"));
+ s = sb_slist_append(s, sb_strdup("bola3.txt"));
+ s = sb_slist_append(s, sb_strdup("bola4.txt"));
+ s = sb_slist_append(s, sb_strdup("bola5.txt"));
+ s = sb_slist_append(s, sb_strdup("bola6.txt"));
+ s = sb_slist_append(s, sb_strdup("bola7.txt"));
+ sb_trie_t *c = sb_trie_new(free);
+ sb_trie_insert(c, "FILTER_TAG", sb_strdup("chunda"));
+ sb_trie_insert(c, "FILTER_PAGE", sb_strdup("2"));
+ sb_trie_insert(c, "FILTER_PER_PAGE", sb_strdup("2"));
+ sb_slist_t *t = blogc_source_parse_from_files(c, s, &err);
+ assert_null(err);
+ assert_non_null(t);
+ assert_int_equal(sb_slist_length(t), 2); // it is enough, no need to look at the items
+ assert_int_equal(sb_trie_size(c), 11);
+ assert_string_equal(sb_trie_lookup(c, "FILENAME_FIRST"), "bola5");
+ assert_string_equal(sb_trie_lookup(c, "FILENAME_LAST"), "bola7");
+ assert_string_equal(sb_trie_lookup(c, "DATE_FIRST"), "2005-02-03 04:05:06");
+ assert_string_equal(sb_trie_lookup(c, "DATE_LAST"), "2007-02-03 04:05:06");
+ assert_string_equal(sb_trie_lookup(c, "FILTER_TAG"), "chunda");
+ assert_string_equal(sb_trie_lookup(c, "FILTER_PAGE"), "2");
+ assert_string_equal(sb_trie_lookup(c, "FILTER_PER_PAGE"), "2");
+ assert_string_equal(sb_trie_lookup(c, "CURRENT_PAGE"), "2");
+ assert_string_equal(sb_trie_lookup(c, "PREVIOUS_PAGE"), "1");
+ assert_string_equal(sb_trie_lookup(c, "FIRST_PAGE"), "1");
+ assert_string_equal(sb_trie_lookup(c, "LAST_PAGE"), "2");
+ sb_trie_free(c);
+ sb_slist_free_full(s, free);
+ sb_slist_free_full(t, (sb_free_func_t) sb_trie_free);
+}
+
+
+static void
+test_source_parse_from_files_filter_by_page_invalid(void **state)
+{
+ will_return(__wrap_blogc_file_get_contents, "bola1.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 123\n"
+ "DATE: 2001-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola2.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 456\n"
+ "DATE: 2002-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola3.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 789\n"
+ "DATE: 2003-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola4.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7891\n"
+ "DATE: 2004-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola5.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7892\n"
+ "DATE: 2005-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola6.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7893\n"
+ "DATE: 2006-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola7.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7894\n"
+ "DATE: 2007-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ blogc_error_t *err = NULL;
+ sb_slist_t *s = NULL;
+ s = sb_slist_append(s, sb_strdup("bola1.txt"));
+ s = sb_slist_append(s, sb_strdup("bola2.txt"));
+ s = sb_slist_append(s, sb_strdup("bola3.txt"));
+ s = sb_slist_append(s, sb_strdup("bola4.txt"));
+ s = sb_slist_append(s, sb_strdup("bola5.txt"));
+ s = sb_slist_append(s, sb_strdup("bola6.txt"));
+ s = sb_slist_append(s, sb_strdup("bola7.txt"));
+ sb_trie_t *c = sb_trie_new(free);
+ sb_trie_insert(c, "FILTER_PAGE", sb_strdup("-1"));
+ sb_trie_insert(c, "FILTER_PER_PAGE", sb_strdup("2"));
+ sb_slist_t *t = blogc_source_parse_from_files(c, s, &err);
+ assert_null(err);
+ assert_non_null(t);
+ assert_int_equal(sb_slist_length(t), 2); // it is enough, no need to look at the items
+ assert_int_equal(sb_trie_size(c), 10);
+ assert_string_equal(sb_trie_lookup(c, "FILENAME_FIRST"), "bola1");
+ assert_string_equal(sb_trie_lookup(c, "FILENAME_LAST"), "bola2");
+ assert_string_equal(sb_trie_lookup(c, "DATE_FIRST"), "2001-02-03 04:05:06");
+ assert_string_equal(sb_trie_lookup(c, "DATE_LAST"), "2002-02-03 04:05:06");
+ assert_string_equal(sb_trie_lookup(c, "FILTER_PAGE"), "-1");
+ assert_string_equal(sb_trie_lookup(c, "FILTER_PER_PAGE"), "2");
+ assert_string_equal(sb_trie_lookup(c, "CURRENT_PAGE"), "1");
+ assert_string_equal(sb_trie_lookup(c, "NEXT_PAGE"), "2");
+ assert_string_equal(sb_trie_lookup(c, "FIRST_PAGE"), "1");
+ assert_string_equal(sb_trie_lookup(c, "LAST_PAGE"), "4");
+ sb_trie_free(c);
+ sb_slist_free_full(s, free);
+ sb_slist_free_full(t, (sb_free_func_t) sb_trie_free);
+}
+
+
+static void
+test_source_parse_from_files_filter_by_page_invalid2(void **state)
+{
+ will_return(__wrap_blogc_file_get_contents, "bola1.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 123\n"
+ "DATE: 2001-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola2.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 456\n"
+ "DATE: 2002-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola3.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 789\n"
+ "DATE: 2003-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola4.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7891\n"
+ "DATE: 2004-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola5.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7892\n"
+ "DATE: 2005-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola6.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7893\n"
+ "DATE: 2006-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola7.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 7894\n"
+ "DATE: 2007-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ blogc_error_t *err = NULL;
+ sb_slist_t *s = NULL;
+ s = sb_slist_append(s, sb_strdup("bola1.txt"));
+ s = sb_slist_append(s, sb_strdup("bola2.txt"));
+ s = sb_slist_append(s, sb_strdup("bola3.txt"));
+ s = sb_slist_append(s, sb_strdup("bola4.txt"));
+ s = sb_slist_append(s, sb_strdup("bola5.txt"));
+ s = sb_slist_append(s, sb_strdup("bola6.txt"));
+ s = sb_slist_append(s, sb_strdup("bola7.txt"));
+ sb_trie_t *c = sb_trie_new(free);
+ sb_trie_insert(c, "FILTER_PAGE", sb_strdup("5"));
+ sb_trie_insert(c, "FILTER_PER_PAGE", sb_strdup("2"));
+ sb_slist_t *t = blogc_source_parse_from_files(c, s, &err);
+ assert_null(err);
+ assert_null(t);
+ sb_trie_free(c);
+ sb_slist_free_full(s, free);
+}
+
+
+static void
+test_source_parse_from_files_without_all_dates(void **state)
+{
+ will_return(__wrap_blogc_fprintf, stderr);
+ will_return(__wrap_blogc_fprintf,
+ "blogc: warning: 'DATE' variable provided for at least one source "
+ "file, but not for all source files. This means that you may get wrong "
+ "values for 'DATE_FIRST' and 'DATE_LAST' variables.\n");
+ will_return(__wrap_blogc_file_get_contents, "bola1.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 123\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola2.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 456\n"
+ "DATE: 2002-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ will_return(__wrap_blogc_file_get_contents, "bola3.txt");
+ will_return(__wrap_blogc_file_get_contents, sb_strdup(
+ "ASD: 789\n"
+ "DATE: 2003-02-03 04:05:06\n"
+ "--------\n"
+ "bola"));
+ blogc_error_t *err = NULL;
+ sb_slist_t *s = NULL;
+ s = sb_slist_append(s, sb_strdup("bola1.txt"));
+ s = sb_slist_append(s, sb_strdup("bola2.txt"));
+ s = sb_slist_append(s, sb_strdup("bola3.txt"));
+ sb_trie_t *c = sb_trie_new(free);
+ sb_slist_t *t = blogc_source_parse_from_files(c, s, &err);
+ assert_null(err);
+ assert_non_null(t);
+ assert_int_equal(sb_slist_length(t), 3); // it is enough, no need to look at the items
+ assert_int_equal(sb_trie_size(c), 3);
+ assert_string_equal(sb_trie_lookup(c, "FILENAME_FIRST"), "bola1");
+ assert_string_equal(sb_trie_lookup(c, "FILENAME_LAST"), "bola3");
+ assert_string_equal(sb_trie_lookup(c, "DATE_LAST"), "2003-02-03 04:05:06");
+ sb_trie_free(c);
+ sb_slist_free_full(s, free);
+ sb_slist_free_full(t, (sb_free_func_t) sb_trie_free);
+}
+
+
+static void
+test_source_parse_from_files_null(void **state)
+{
+ blogc_error_t *err = NULL;
+ sb_slist_t *s = NULL;
+ sb_trie_t *c = sb_trie_new(free);
+ sb_slist_t *t = blogc_source_parse_from_files(c, s, &err);
+ assert_null(err);
+ assert_null(t);
+ assert_int_equal(sb_slist_length(t), 0);
+ assert_int_equal(sb_trie_size(c), 0);
+ sb_trie_free(c);
+ sb_slist_free_full(s, free);
+ sb_slist_free_full(t, (sb_free_func_t) sb_trie_free);
+}
+
+
+int
+main(void)
+{
+ const UnitTest tests[] = {
+ unit_test(test_get_filename),
+ unit_test(test_template_parse_from_file),
+ unit_test(test_template_parse_from_file_null),
+ unit_test(test_source_parse_from_file),
+ unit_test(test_source_parse_from_file_null),
+ unit_test(test_source_parse_from_files),
+ unit_test(test_source_parse_from_files_filter_by_tag),
+ unit_test(test_source_parse_from_files_filter_by_page),
+ unit_test(test_source_parse_from_files_filter_by_page2),
+ unit_test(test_source_parse_from_files_filter_by_page3),
+ unit_test(test_source_parse_from_files_filter_by_page_and_tag),
+ unit_test(test_source_parse_from_files_filter_by_page_invalid),
+ unit_test(test_source_parse_from_files_filter_by_page_invalid2),
+ unit_test(test_source_parse_from_files_without_all_dates),
+ unit_test(test_source_parse_from_files_null),
+ };
+ return run_tests(tests);
+}
diff --git a/tests/check_renderer.c b/tests/check_renderer.c
new file mode 100644
index 0000000..c2c5618
--- /dev/null
+++ b/tests/check_renderer.c
@@ -0,0 +1,1158 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include "../src/error.h"
+#include "../src/renderer.h"
+#include "../src/source-parser.h"
+#include "../src/template-parser.h"
+#include "../src/utils.h"
+
+
+static sb_slist_t*
+create_sources(unsigned int count)
+{
+ const char *s[] = {
+ "BOLA: asd\n"
+ "GUDA: zxc\n"
+ "GUDA2: zxc\n"
+ "DATE: 2015-01-02 03:04:05\n"
+ "DATE_FORMAT: %R\n"
+ "TAGS: foo bar baz\n"
+ "-----\n"
+ "ahahahahahahahaha",
+ "BOLA: asd2\n"
+ "GUDA: zxc2\n"
+ "DATE: 2014-02-03 04:05:06\n"
+ "-----\n"
+ "ahahahahahahahaha2",
+ "BOLA: asd3\n"
+ "GUDA: zxc3\n"
+ "DATE: 2013-01-02 03:04:05\n"
+ "-----\n"
+ "ahahahahahahahaha3",
+ };
+ assert_false(count > 3);
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = NULL;
+ for (unsigned int i = 0; i < count; i++) {
+ l = sb_slist_append(l, blogc_source_parse(s[i], strlen(s[i]), &err));
+ assert_null(err);
+ }
+ assert_int_equal(sb_slist_length(l), count);
+ return l;
+}
+
+
+static void
+test_render_entry(void **state)
+{
+ const char *str =
+ "foo\n"
+ "{% block listing_once %}fuuu{% endblock %}\n"
+ "{% block entry %}\n"
+ "{{ DATE }}\n"
+ "{% ifdef DATE_FORMATTED %}{{ DATE_FORMATTED }}{% endif %}\n"
+ "{% ifdef GUDA %}{{ GUDA }}{% endif %}\n"
+ "{% ifdef CHUNDA %}{{ CHUNDA }}{% endif %}\n"
+ "{% endblock %}\n"
+ "{% block listing %}lol{% endblock %}\n"
+ "{% if GUDA == GUDA2 %}gudabola{% endif %}\n"
+ "{% if GUDA == \"zxc\" %}LOL{% endif %}\n"
+ "{% if GUDA != \"bola\" %}HEHE{% endif %}\n"
+ "{% if GUDA < \"zxd\" %}LOL2{% endif %}\n"
+ "{% if GUDA > \"zxd\" %}LOL3{% else %}ELSE{% endif %}\n"
+ "{% if GUDA <= \"zxc\" %}LOL4{% endif %}\n"
+ "{% foreach TAGS %}lol {{ FOREACH_ITEM }} haha {% endforeach %}\n"
+ "{% foreach TAGS_ASD %}yay{% endforeach %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ char *out = blogc_render(l, s, NULL, false);
+ assert_string_equal(out,
+ "foo\n"
+ "\n"
+ "\n"
+ "2015-01-02 03:04:05\n"
+ "03:04\n"
+ "zxc\n"
+ "\n"
+ "\n"
+ "\n"
+ "gudabola\n"
+ "LOL\n"
+ "HEHE\n"
+ "LOL2\n"
+ "ELSE\n"
+ "LOL4\n"
+ "lol foo haha lol bar haha lol baz haha \n"
+ "\n");
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_listing(void **state)
+{
+ const char *str =
+ "foo\n"
+ "{% block listing_once %}fuuu{% endblock %}\n"
+ "{% block entry %}\n"
+ "{% ifdef GUDA %}{{ GUDA }}{% endif %}\n"
+ "{% ifdef CHUNDA %}{{ CHUNDA }}{% endif %}\n"
+ "{% endblock %}\n"
+ "{% block listing %}\n"
+ "{% ifdef DATE_FORMATTED %}{{ DATE_FORMATTED }}{% endif %}\n"
+ "bola: {% ifdef BOLA %}{{ BOLA }}{% endif %}\n"
+ "{% foreach TAGS %}lol {{ FOREACH_ITEM }} haha {% endforeach %}\n"
+ "{% foreach TAGS_ASD %}yay{% endforeach %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(3);
+ assert_non_null(s);
+ char *out = blogc_render(l, s, NULL, true);
+ assert_string_equal(out,
+ "foo\n"
+ "fuuu\n"
+ "\n"
+ "\n"
+ "03:04\n"
+ "bola: asd\n"
+ "lol foo haha lol bar haha lol baz haha \n"
+ "\n"
+ "\n"
+ "2014-02-03 04:05:06\n"
+ "bola: asd2\n"
+ "\n"
+ "\n"
+ "\n"
+ "2013-01-02 03:04:05\n"
+ "bola: asd3\n"
+ "\n"
+ "\n"
+ "\n");
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_listing_empty(void **state)
+{
+ const char *str =
+ "foo\n"
+ "{% block listing_once %}fuuu{% endblock %}\n"
+ "{% block entry %}\n"
+ "{% ifdef GUDA %}{{ GUDA }}{% endif %}\n"
+ "{% ifdef CHUNDA %}{{ CHUNDA }}{% endif %}\n"
+ "{% endblock %}\n"
+ "{% block listing %}\n"
+ "{% ifdef DATE_FORMATTED %}{{ DATE_FORMATTED }}{% endif %}\n"
+ "bola: {% ifdef BOLA %}{{ BOLA }}{% endif %}\n"
+ "{% foreach TAGS %}lol {{ FOREACH_ITEM }} haha {% endforeach %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ char *out = blogc_render(l, NULL, NULL, true);
+ assert_string_equal(out,
+ "foo\n"
+ "fuuu\n"
+ "\n"
+ "\n");
+ blogc_template_free_stmts(l);
+ free(out);
+}
+
+
+static void
+test_render_ifdef(void **state)
+{
+ const char *str =
+ "{% block entry %}\n"
+ "{% ifdef CHUNDA %}chunda\n"
+ "{% ifdef GUDA %}guda\n"
+ "{% ifdef BOLA %}bola\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ char *out = blogc_render(l, s, NULL, false);
+ assert_string_equal(out,
+ "\n"
+ "\n"
+ "\n");
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_ifdef2(void **state)
+{
+ const char *str =
+ "{% block entry %}\n"
+ "{% ifdef GUDA %}guda\n"
+ "{% ifdef CHUNDA %}chunda\n"
+ "{% ifdef BOLA %}bola\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ char *out = blogc_render(l, s, NULL, false);
+ assert_string_equal(out,
+ "\n"
+ "guda\n"
+ "\n"
+ "\n"
+ "\n");
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_ifdef3(void **state)
+{
+ const char *str =
+ "{% block entry %}\n"
+ "{% ifdef GUDA %}guda\n"
+ "{% ifdef BOLA %}bola\n"
+ "{% ifdef CHUNDA %}chunda\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ char *out = blogc_render(l, s, NULL, false);
+ assert_string_equal(out,
+ "\n"
+ "guda\n"
+ "bola\n"
+ "\n"
+ "\n"
+ "\n"
+ "\n");
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_ifdef4(void **state)
+{
+ const char *str =
+ "{% block entry %}\n"
+ "{% ifdef GUDA %}guda\n"
+ "{% ifdef BOLA %}bola\n"
+ "{% ifdef CHUNDA %}chunda\n"
+ "{% else %}else\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% else %}lol\n"
+ "{% endif %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ char *out = blogc_render(l, s, NULL, false);
+ assert_string_equal(out,
+ "\n"
+ "guda\n"
+ "bola\n"
+ "else\n"
+ "\n"
+ "\n"
+ "\n"
+ "\n");
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_ifdef5(void **state)
+{
+ const char *str =
+ "{% block entry %}\n"
+ "{% ifdef GUDA %}guda\n"
+ "{% ifdef CHUNDA %}chunda\n"
+ "{% ifdef BOLA %}bola\n"
+ "{% endif %}\n"
+ "{% else %}else\n"
+ "{% endif %}\n"
+ "{% else %}lol\n"
+ "{% endif %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ char *out = blogc_render(l, s, NULL, false);
+ assert_string_equal(out,
+ "\n"
+ "guda\n"
+ "else\n"
+ "\n"
+ "\n"
+ "\n");
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_ifdef6(void **state)
+{
+ const char *str =
+ "{% block entry %}\n"
+ "{% ifdef CHUNDA %}chunda\n"
+ "{% ifdef GUDA %}guda\n"
+ "{% ifdef BOLA %}bola\n"
+ "{% endif %}\n"
+ "{% else %}else\n"
+ "{% endif %}\n"
+ "{% else %}lol\n"
+ "{% endif %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ char *out = blogc_render(l, s, NULL, false);
+ assert_string_equal(out,
+ "\n"
+ "lol\n"
+ "\n"
+ "\n");
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_ifdef7(void **state)
+{
+ const char *str =
+ "{% block entry %}\n"
+ "{% ifdef GUDA %}guda\n"
+ "{% ifdef BOLA %}bola\n"
+ "{% ifdef CHUNDA %}chunda\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% ifdef CHUNDA %}ch\n"
+ "{% else %}else\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ char *out = blogc_render(l, s, NULL, false);
+ assert_string_equal(out,
+ "\n"
+ "guda\n"
+ "bola\n"
+ "\n"
+ "\n"
+ "else\n"
+ "\n"
+ "\n"
+ "\n");
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_ifndef(void **state)
+{
+ const char *str =
+ "{% block entry %}\n"
+ "{% ifndef CHUNDA %}chunda\n"
+ "{% ifdef GUDA %}guda\n"
+ "{% ifndef BOLA %}bola\n"
+ "{% else %}else\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ char *out = blogc_render(l, s, NULL, false);
+ assert_string_equal(out,
+ "\n"
+ "chunda\n"
+ "guda\n"
+ "else\n"
+ "\n"
+ "\n"
+ "\n"
+ "\n");
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_if_eq(void **state)
+{
+ const char *str =
+ "{% block entry %}\n"
+ "{% if GUDA == GUDA2 %}gudabola{% endif %}\n"
+ "{% if GUDA == \"zxc\" %}guda\n"
+ "{% ifdef BOLA %}bola\n"
+ "{% if GUDA > \"zxc\" %}asd\n"
+ "{% else %}else\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ char *out = blogc_render(l, s, NULL, false);
+ assert_string_equal(out,
+ "\n"
+ "gudabola\n"
+ "guda\n"
+ "bola\n"
+ "else\n"
+ "\n"
+ "\n"
+ "\n"
+ "\n");
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_if_neq(void **state)
+{
+ const char *str =
+ "{% block entry %}\n"
+ "{% if GUDA != BOLA %}gudabola{% endif %}\n"
+ "{% if GUDA != \"zxa\" %}guda\n"
+ "{% ifdef BOLA %}bola\n"
+ "{% if GUDA > \"zxc\" %}asd\n"
+ "{% else %}else\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ char *out = blogc_render(l, s, NULL, false);
+ assert_string_equal(out,
+ "\n"
+ "gudabola\n"
+ "guda\n"
+ "bola\n"
+ "else\n"
+ "\n"
+ "\n"
+ "\n"
+ "\n");
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_if_lt(void **state)
+{
+ const char *str =
+ "{% block entry %}\n"
+ "{% if BOLA < GUDA %}gudabola{% endif %}\n"
+ "{% if GUDA < \"zxe\" %}guda\n"
+ "{% ifdef BOLA %}bola\n"
+ "{% if GUDA > \"zxc\" %}asd\n"
+ "{% else %}else\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ char *out = blogc_render(l, s, NULL, false);
+ assert_string_equal(out,
+ "\n"
+ "gudabola\n"
+ "guda\n"
+ "bola\n"
+ "else\n"
+ "\n"
+ "\n"
+ "\n"
+ "\n");
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_if_gt(void **state)
+{
+ const char *str =
+ "{% block entry %}\n"
+ "{% if GUDA > BOLA %}gudabola{% endif %}\n"
+ "{% if GUDA > \"zxa\" %}guda\n"
+ "{% ifdef BOLA %}bola\n"
+ "{% if GUDA > \"zxc\" %}asd\n"
+ "{% else %}else\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ char *out = blogc_render(l, s, NULL, false);
+ assert_string_equal(out,
+ "\n"
+ "gudabola\n"
+ "guda\n"
+ "bola\n"
+ "else\n"
+ "\n"
+ "\n"
+ "\n"
+ "\n");
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_if_lt_eq(void **state)
+{
+ const char *str =
+ "{% block entry %}\n"
+ "{% if BOLA <= GUDA %}gudabola{% endif %}\n"
+ "{% if GUDA <= \"zxc\" %}guda\n"
+ "{% if GUDA <= \"zxe\" %}guda2\n"
+ "{% ifdef BOLA %}bola\n"
+ "{% if GUDA > \"zxc\" %}asd\n"
+ "{% else %}else\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ char *out = blogc_render(l, s, NULL, false);
+ assert_string_equal(out,
+ "\n"
+ "gudabola\n"
+ "guda\n"
+ "guda2\n"
+ "bola\n"
+ "else\n"
+ "\n"
+ "\n"
+ "\n"
+ "\n"
+ "\n");
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_if_gt_eq(void **state)
+{
+ const char *str =
+ "{% block entry %}\n"
+ "{% if GUDA >= BOLA %}gudabola{% endif %}\n"
+ "{% if GUDA >= \"zxc\" %}guda\n"
+ "{% if GUDA >= \"zxa\" %}guda2\n"
+ "{% ifdef BOLA %}bola\n"
+ "{% if GUDA > \"zxc\" %}asd\n"
+ "{% else %}else\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ char *out = blogc_render(l, s, NULL, false);
+ assert_string_equal(out,
+ "\n"
+ "gudabola\n"
+ "guda\n"
+ "guda2\n"
+ "bola\n"
+ "else\n"
+ "\n"
+ "\n"
+ "\n"
+ "\n"
+ "\n");
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_foreach(void **state)
+{
+ const char *str =
+ "{% block entry %}\n"
+ "{% foreach TAGS %} {{ FOREACH_ITEM }} {% endforeach %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ char *out = blogc_render(l, s, NULL, false);
+ assert_string_equal(out,
+ "\n"
+ " foo bar baz \n"
+ "\n");
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_foreach_if(void **state)
+{
+ const char *str =
+ "{% block entry %}\n"
+ "{% foreach TAGS %} {% if FOREACH_ITEM == \"bar\" %}{{ FOREACH_ITEM }}"
+ "{% endif %} {% endforeach %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ char *out = blogc_render(l, s, NULL, false);
+ assert_string_equal(out,
+ "\n"
+ " bar \n"
+ "\n");
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_foreach_if_else(void **state)
+{
+ const char *str =
+ "{% block entry %}\n"
+ "{% foreach TAGS %}{% if FOREACH_ITEM == \"bar\" %}yay"
+ "{% else %}{{ FOREACH_ITEM }}"
+ "{% endif %} {% endforeach %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ char *out = blogc_render(l, s, NULL, false);
+ assert_string_equal(out,
+ "\n"
+ "foo yay baz \n"
+ "\n");
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_null(void **state)
+{
+ assert_null(blogc_render(NULL, NULL, NULL, false));
+}
+
+
+static void
+test_render_outside_block(void **state)
+{
+ const char *str =
+ "{% ifdef GUDA %}bola{% endif %}\n"
+ "{{ BOLA }}\n"
+ "{% ifndef CHUNDA %}lol{% endif %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ sb_trie_t *c = sb_trie_new(free);
+ sb_trie_insert(c, "GUDA", sb_strdup("asd"));
+ char *out = blogc_render(l, s, c, false);
+ assert_string_equal(out,
+ "bola\n"
+ "\n"
+ "lol\n");
+ sb_trie_free(c);
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_prefer_local_variable(void **state)
+{
+ const char *str =
+ "{% block entry %}\n"
+ "{% ifdef LOL %}{{ LOL }}{% endif %}\n"
+ "{% ifndef CHUNDA %}chunda\n"
+ "{% ifdef GUDA %}{{ GUDA }}\n"
+ "{% ifndef BOLA %}bola\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ sb_trie_t *c = sb_trie_new(free);
+ sb_trie_insert(c, "GUDA", sb_strdup("hehe"));
+ sb_trie_insert(c, "LOL", sb_strdup("hmm"));
+ char *out = blogc_render(l, s, c, false);
+ assert_string_equal(out,
+ "\n"
+ "hmm\n"
+ "chunda\n"
+ "zxc\n"
+ "\n"
+ "\n"
+ "\n"
+ "\n");
+ sb_trie_free(c);
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_respect_variable_scope(void **state)
+{
+ const char *str =
+ "{{ LOL }}\n"
+ "{{ BOLA }}\n"
+ "{% block entry %}\n"
+ "{% ifdef LOL %}{{ LOL }}{% endif %}\n"
+ "{% ifdef BOLA %}{{ BOLA }}{% endif %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = create_sources(1);
+ assert_non_null(s);
+ sb_trie_t *c = sb_trie_new(free);
+ char *out = blogc_render(l, s, c, false);
+ assert_string_equal(out,
+ "\n"
+ "\n"
+ "\n"
+ "\n"
+ "asd\n"
+ "\n");
+ sb_trie_free(c);
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_render_ifcount_bug(void **state)
+{
+ const char *str =
+ "{% block entry %}\n"
+ "{% ifdef TITLE %}<h3>{{ TITLE }}</h3>{% endif %}\n"
+ "{% ifdef IS_POST %}\n"
+ "{% ifdef ASD %}ASD{% endif %}\n"
+ "{% endif %}\n"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *l = blogc_template_parse(str, strlen(str), &err);
+ assert_non_null(l);
+ assert_null(err);
+ sb_slist_t *s = NULL;
+ s = sb_slist_append(s, sb_trie_new(free));
+ sb_trie_insert(s->data, "TITLE", sb_strdup("bola"));
+ sb_trie_t *c = sb_trie_new(free);
+ char *out = blogc_render(l, s, c, false);
+ assert_string_equal(out,
+ "\n"
+ "<h3>bola</h3>\n"
+ "\n"
+ "\n");
+ sb_trie_free(c);
+ blogc_template_free_stmts(l);
+ sb_slist_free_full(s, (sb_free_func_t) sb_trie_free);
+ free(out);
+}
+
+
+static void
+test_get_variable(void **state)
+{
+ sb_trie_t *g = sb_trie_new(free);
+ sb_trie_insert(g, "NAME", sb_strdup("bola"));
+ sb_trie_insert(g, "TITLE", sb_strdup("bola2"));
+ sb_trie_t *l = sb_trie_new(free);
+ sb_trie_insert(l, "NAME", sb_strdup("chunda"));
+ sb_trie_insert(l, "TITLE", sb_strdup("chunda2"));
+ assert_string_equal(blogc_get_variable("NAME", g, l), "chunda");
+ assert_string_equal(blogc_get_variable("TITLE", g, l), "chunda2");
+ assert_null(blogc_get_variable("BOLA", g, l));
+ sb_trie_free(g);
+ sb_trie_free(l);
+}
+
+
+static void
+test_get_variable_only_local(void **state)
+{
+ sb_trie_t *g = NULL;
+ sb_trie_t *l = sb_trie_new(free);
+ sb_trie_insert(l, "NAME", sb_strdup("chunda"));
+ sb_trie_insert(l, "TITLE", sb_strdup("chunda2"));
+ assert_string_equal(blogc_get_variable("NAME", g, l), "chunda");
+ assert_string_equal(blogc_get_variable("TITLE", g, l), "chunda2");
+ assert_null(blogc_get_variable("BOLA", g, l));
+ sb_trie_free(l);
+}
+
+
+static void
+test_get_variable_only_global(void **state)
+{
+ sb_trie_t *g = sb_trie_new(free);
+ sb_trie_insert(g, "NAME", sb_strdup("bola"));
+ sb_trie_insert(g, "TITLE", sb_strdup("bola2"));
+ sb_trie_t *l = NULL;
+ assert_string_equal(blogc_get_variable("NAME", g, l), "bola");
+ assert_string_equal(blogc_get_variable("TITLE", g, l), "bola2");
+ assert_null(blogc_get_variable("BOLA", g, l));
+ sb_trie_free(g);
+}
+
+
+static void
+test_format_date(void **state)
+{
+ sb_trie_t *g = sb_trie_new(free);
+ sb_trie_insert(g, "DATE_FORMAT", sb_strdup("%H -- %M"));
+ sb_trie_t *l = sb_trie_new(free);
+ sb_trie_insert(l, "DATE_FORMAT", sb_strdup("%R"));
+ char *date = blogc_format_date("2015-01-02 03:04:05", g, l);
+ assert_string_equal(date, "03:04");
+ free(date);
+ sb_trie_free(g);
+ sb_trie_free(l);
+}
+
+
+static void
+test_format_date_with_global_format(void **state)
+{
+ sb_trie_t *g = sb_trie_new(free);
+ sb_trie_insert(g, "DATE_FORMAT", sb_strdup("%H -- %M"));
+ sb_trie_t *l = sb_trie_new(free);
+ char *date = blogc_format_date("2015-01-02 03:04:05", g, l);
+ assert_string_equal(date, "03 -- 04");
+ free(date);
+ sb_trie_free(g);
+ sb_trie_free(l);
+}
+
+
+static void
+test_format_date_without_format(void **state)
+{
+ sb_trie_t *g = sb_trie_new(free);
+ sb_trie_t *l = sb_trie_new(free);
+ char *date = blogc_format_date("2015-01-02 03:04:05", g, l);
+ assert_string_equal(date, "2015-01-02 03:04:05");
+ free(date);
+ sb_trie_free(g);
+ sb_trie_free(l);
+}
+
+
+static void
+test_format_date_without_date(void **state)
+{
+ sb_trie_t *g = sb_trie_new(free);
+ sb_trie_t *l = sb_trie_new(free);
+ char *date = blogc_format_date(NULL, g, l);
+ assert_null(date);
+ free(date);
+ sb_trie_free(g);
+ sb_trie_free(l);
+}
+
+
+static void
+test_format_variable(void **state)
+{
+ // FIXME: test warnings
+ sb_trie_t *g = sb_trie_new(free);
+ sb_trie_insert(g, "NAME", sb_strdup("bola"));
+ sb_trie_insert(g, "TITLE", sb_strdup("bola2"));
+ sb_trie_t *l = sb_trie_new(free);
+ sb_trie_insert(l, "NAME", sb_strdup("chunda"));
+ sb_trie_insert(l, "TITLE", sb_strdup("chunda2"));
+ sb_trie_insert(l, "SIZE", sb_strdup("1234567890987654321"));
+ char *tmp = blogc_format_variable("NAME", g, l, NULL);
+ assert_string_equal(tmp, "chunda");
+ free(tmp);
+ tmp = blogc_format_variable("TITLE", g, l, NULL);
+ assert_string_equal(tmp, "chunda2");
+ free(tmp);
+ tmp = blogc_format_variable("TITLE_2", g, l, NULL);
+ assert_string_equal(tmp, "ch");
+ free(tmp);
+ tmp = blogc_format_variable("SIZE_12", g, l, NULL);
+ assert_string_equal(tmp, "123456789098");
+ free(tmp);
+ tmp = blogc_format_variable("SIZE_200", g, l, NULL);
+ assert_string_equal(tmp, "1234567890987654321");
+ free(tmp);
+ assert_null(blogc_format_variable("SIZE_", g, l, NULL));
+ assert_null(blogc_format_variable("BOLA", g, l, NULL));
+ sb_trie_free(g);
+ sb_trie_free(l);
+}
+
+
+static void
+test_format_variable_with_date(void **state)
+{
+ sb_trie_t *g = sb_trie_new(free);
+ sb_trie_insert(g, "DATE", sb_strdup("2010-11-12 13:14:15"));
+ sb_trie_insert(g, "DATE_FORMAT", sb_strdup("%R"));
+ sb_trie_t *l = sb_trie_new(free);
+ sb_trie_insert(l, "DATE", sb_strdup("2011-12-13 14:15:16"));
+ char *tmp = blogc_format_variable("DATE_FORMATTED", g, l, NULL);
+ assert_string_equal(tmp, "14:15");
+ free(tmp);
+ tmp = blogc_format_variable("DATE_FORMATTED_3", g, l, NULL);
+ assert_string_equal(tmp, "14:");
+ free(tmp);
+ tmp = blogc_format_variable("DATE_FORMATTED_10", g, l, NULL);
+ assert_string_equal(tmp, "14:15");
+ free(tmp);
+ sb_trie_free(g);
+ sb_trie_free(l);
+}
+
+
+static void
+test_format_variable_foreach(void **state)
+{
+ sb_slist_t *l = NULL;
+ l = sb_slist_append(l, sb_strdup("asd"));
+ l = sb_slist_append(l, sb_strdup("qwe"));
+ l = sb_slist_append(l, sb_strdup("zxcvbn"));
+ char *tmp = blogc_format_variable("FOREACH_ITEM", NULL, NULL, l->next);
+ assert_string_equal(tmp, "qwe");
+ free(tmp);
+ tmp = blogc_format_variable("FOREACH_ITEM_4", NULL, NULL,
+ l->next->next);
+ assert_string_equal(tmp, "zxcv");
+ free(tmp);
+ tmp = blogc_format_variable("FOREACH_ITEM_10", NULL, NULL,
+ l->next->next);
+ assert_string_equal(tmp, "zxcvbn");
+ free(tmp);
+ sb_slist_free_full(l, free);
+}
+
+
+static void
+test_format_variable_foreach_empty(void **state)
+{
+ assert_null(blogc_format_variable("FOREACH_ITEM", NULL, NULL, NULL));
+ assert_null(blogc_format_variable("FOREACH_ITEM_4", NULL, NULL, NULL));
+}
+
+
+static void
+test_split_list_variable(void **state)
+{
+ sb_trie_t *g = sb_trie_new(free);
+ sb_trie_insert(g, "TAGS", sb_strdup("asd lol hehe"));
+ sb_trie_t *l = sb_trie_new(free);
+ sb_trie_insert(l, "TAGS", sb_strdup("asd lol XD"));
+ sb_slist_t *tmp = blogc_split_list_variable("TAGS", g, l);
+ assert_string_equal(tmp->data, "asd");
+ assert_string_equal(tmp->next->data, "lol");
+ assert_string_equal(tmp->next->next->data, "XD");
+ sb_slist_free_full(tmp, free);
+ sb_trie_free(g);
+ sb_trie_free(l);
+}
+
+
+static void
+test_split_list_variable_not_found(void **state)
+{
+ sb_trie_t *g = sb_trie_new(free);
+ sb_trie_insert(g, "TAGS", sb_strdup("asd lol hehe"));
+ sb_trie_t *l = sb_trie_new(free);
+ sb_trie_insert(l, "TAGS", sb_strdup("asd lol XD"));
+ sb_slist_t *tmp = blogc_split_list_variable("TAG", g, l);
+ assert_null(tmp);
+ sb_trie_free(g);
+ sb_trie_free(l);
+}
+
+
+int
+main(void)
+{
+ const UnitTest tests[] = {
+ unit_test(test_render_entry),
+ unit_test(test_render_listing),
+ unit_test(test_render_listing_empty),
+ unit_test(test_render_ifdef),
+ unit_test(test_render_ifdef2),
+ unit_test(test_render_ifdef3),
+ unit_test(test_render_ifdef4),
+ unit_test(test_render_ifdef5),
+ unit_test(test_render_ifdef6),
+ unit_test(test_render_ifdef7),
+ unit_test(test_render_ifndef),
+ unit_test(test_render_if_eq),
+ unit_test(test_render_if_neq),
+ unit_test(test_render_if_lt),
+ unit_test(test_render_if_gt),
+ unit_test(test_render_if_lt_eq),
+ unit_test(test_render_if_gt_eq),
+ unit_test(test_render_foreach),
+ unit_test(test_render_foreach_if),
+ unit_test(test_render_foreach_if_else),
+ unit_test(test_render_null),
+ unit_test(test_render_outside_block),
+ unit_test(test_render_prefer_local_variable),
+ unit_test(test_render_respect_variable_scope),
+ unit_test(test_render_ifcount_bug),
+ unit_test(test_get_variable),
+ unit_test(test_get_variable_only_local),
+ unit_test(test_get_variable_only_global),
+ unit_test(test_format_date),
+ unit_test(test_format_date_with_global_format),
+ unit_test(test_format_date_without_format),
+ unit_test(test_format_date_without_date),
+ unit_test(test_format_variable),
+ unit_test(test_format_variable_with_date),
+ unit_test(test_format_variable_foreach),
+ unit_test(test_format_variable_foreach_empty),
+ unit_test(test_split_list_variable),
+ unit_test(test_split_list_variable_not_found),
+ };
+ return run_tests(tests);
+}
diff --git a/tests/check_source_parser.c b/tests/check_source_parser.c
new file mode 100644
index 0000000..bbd9ec6
--- /dev/null
+++ b/tests/check_source_parser.c
@@ -0,0 +1,542 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <string.h>
+#include "../src/source-parser.h"
+#include "../src/error.h"
+#include "../src/utils.h"
+
+
+static void
+test_source_parse(void **state)
+{
+ const char *a =
+ "VAR1: asd asd\n"
+ "VAR2: 123chunda\n"
+ "----------\n"
+ "# This is a test\n"
+ "\n"
+ "bola\n";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(err);
+ assert_non_null(source);
+ assert_int_equal(sb_trie_size(source), 6);
+ assert_string_equal(sb_trie_lookup(source, "VAR1"), "asd asd");
+ assert_string_equal(sb_trie_lookup(source, "VAR2"), "123chunda");
+ assert_string_equal(sb_trie_lookup(source, "EXCERPT"),
+ "<h1 id=\"this-is-a-test\">This is a test</h1>\n"
+ "<p>bola</p>\n");
+ assert_string_equal(sb_trie_lookup(source, "CONTENT"),
+ "<h1 id=\"this-is-a-test\">This is a test</h1>\n"
+ "<p>bola</p>\n");
+ assert_string_equal(sb_trie_lookup(source, "RAW_CONTENT"),
+ "# This is a test\n"
+ "\n"
+ "bola\n");
+ assert_string_equal(sb_trie_lookup(source, "DESCRIPTION"), "bola");
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_crlf(void **state)
+{
+ const char *a =
+ "VAR1: asd asd\r\n"
+ "VAR2: 123chunda\r\n"
+ "----------\r\n"
+ "# This is a test\r\n"
+ "\r\n"
+ "bola\r\n";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(err);
+ assert_non_null(source);
+ assert_int_equal(sb_trie_size(source), 6);
+ assert_string_equal(sb_trie_lookup(source, "VAR1"), "asd asd");
+ assert_string_equal(sb_trie_lookup(source, "VAR2"), "123chunda");
+ assert_string_equal(sb_trie_lookup(source, "EXCERPT"),
+ "<h1 id=\"this-is-a-test\">This is a test</h1>\r\n"
+ "<p>bola</p>\r\n");
+ assert_string_equal(sb_trie_lookup(source, "CONTENT"),
+ "<h1 id=\"this-is-a-test\">This is a test</h1>\r\n"
+ "<p>bola</p>\r\n");
+ assert_string_equal(sb_trie_lookup(source, "RAW_CONTENT"),
+ "# This is a test\r\n"
+ "\r\n"
+ "bola\r\n");
+ assert_string_equal(sb_trie_lookup(source, "DESCRIPTION"), "bola");
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_with_spaces(void **state)
+{
+ const char *a =
+ "\n \n"
+ "VAR1: chunda \t \n"
+ "\n\n"
+ "BOLA: guda\n"
+ "----------\n"
+ "# This is a test\n"
+ "\n"
+ "bola\n";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(err);
+ assert_non_null(source);
+ assert_int_equal(sb_trie_size(source), 6);
+ assert_string_equal(sb_trie_lookup(source, "VAR1"), "chunda");
+ assert_string_equal(sb_trie_lookup(source, "BOLA"), "guda");
+ assert_string_equal(sb_trie_lookup(source, "EXCERPT"),
+ "<h1 id=\"this-is-a-test\">This is a test</h1>\n"
+ "<p>bola</p>\n");
+ assert_string_equal(sb_trie_lookup(source, "CONTENT"),
+ "<h1 id=\"this-is-a-test\">This is a test</h1>\n"
+ "<p>bola</p>\n");
+ assert_string_equal(sb_trie_lookup(source, "RAW_CONTENT"),
+ "# This is a test\n"
+ "\n"
+ "bola\n");
+ assert_string_equal(sb_trie_lookup(source, "DESCRIPTION"), "bola");
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_with_excerpt(void **state)
+{
+ const char *a =
+ "VAR1: asd asd\n"
+ "VAR2: 123chunda\n"
+ "----------\n"
+ "# This is a test\n"
+ "\n"
+ "bola\n"
+ "\n"
+ "...\n"
+ "\n"
+ "guda\n"
+ "yay";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(err);
+ assert_non_null(source);
+ assert_int_equal(sb_trie_size(source), 6);
+ assert_string_equal(sb_trie_lookup(source, "VAR1"), "asd asd");
+ assert_string_equal(sb_trie_lookup(source, "VAR2"), "123chunda");
+ assert_string_equal(sb_trie_lookup(source, "EXCERPT"),
+ "<h1 id=\"this-is-a-test\">This is a test</h1>\n"
+ "<p>bola</p>\n");
+ assert_string_equal(sb_trie_lookup(source, "CONTENT"),
+ "<h1 id=\"this-is-a-test\">This is a test</h1>\n"
+ "<p>bola</p>\n"
+ "<p>guda\n"
+ "yay</p>\n");
+ assert_string_equal(sb_trie_lookup(source, "RAW_CONTENT"),
+ "# This is a test\n"
+ "\n"
+ "bola\n"
+ "\n"
+ "...\n"
+ "\n"
+ "guda\n"
+ "yay");
+ assert_string_equal(sb_trie_lookup(source, "DESCRIPTION"), "bola");
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_with_description(void **state)
+{
+ const char *a =
+ "VAR1: asd asd\n"
+ "VAR2: 123chunda\n"
+ "DESCRIPTION: huehuehuebrbr\n"
+ "----------\n"
+ "# This is a test\n"
+ "\n"
+ "bola\n";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(err);
+ assert_non_null(source);
+ assert_int_equal(sb_trie_size(source), 6);
+ assert_string_equal(sb_trie_lookup(source, "VAR1"), "asd asd");
+ assert_string_equal(sb_trie_lookup(source, "VAR2"), "123chunda");
+ assert_string_equal(sb_trie_lookup(source, "EXCERPT"),
+ "<h1 id=\"this-is-a-test\">This is a test</h1>\n"
+ "<p>bola</p>\n");
+ assert_string_equal(sb_trie_lookup(source, "CONTENT"),
+ "<h1 id=\"this-is-a-test\">This is a test</h1>\n"
+ "<p>bola</p>\n");
+ assert_string_equal(sb_trie_lookup(source, "RAW_CONTENT"),
+ "# This is a test\n"
+ "\n"
+ "bola\n");
+ assert_string_equal(sb_trie_lookup(source, "DESCRIPTION"), "huehuehuebrbr");
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_config_empty(void **state)
+{
+ const char *a = "";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(source);
+ assert_non_null(err);
+ assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
+ assert_string_equal(err->msg, "Your source file is empty.");
+ blogc_error_free(err);
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_config_invalid_key(void **state)
+{
+ const char *a = "bola: guda";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
+ assert_string_equal(err->msg,
+ "Can't find a configuration key or the content separator.\n"
+ "Error occurred near line 1, position 1: bola: guda");
+ blogc_error_free(err);
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_config_no_key(void **state)
+{
+ const char *a = "BOLa";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid configuration key.\n"
+ "Error occurred near line 1, position 4: BOLa");
+ blogc_error_free(err);
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_config_no_key2(void **state)
+{
+ const char *a = "BOLA";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
+ assert_string_equal(err->msg,
+ "Your last configuration key is missing ':' and the value\n"
+ "Error occurred near line 1, position 5: BOLA");
+ blogc_error_free(err);
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_config_no_value(void **state)
+{
+ const char *a = "BOLA:\r\n";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(source);
+ assert_non_null(err);
+ assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
+ assert_string_equal(err->msg,
+ "Configuration value not provided for 'BOLA'.\n"
+ "Error occurred near line 1, position 6: BOLA:");
+ blogc_error_free(err);
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_config_no_value2(void **state)
+{
+ const char *a = "BOLA:";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(source);
+ assert_non_null(err);
+ assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
+ assert_string_equal(err->msg,
+ "Configuration value not provided for 'BOLA'.\n"
+ "Error occurred near line 1, position 6: BOLA:");
+ blogc_error_free(err);
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_config_reserved_name(void **state)
+{
+ const char *a = "FILENAME: asd\r\n";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(source);
+ assert_non_null(err);
+ assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
+ assert_string_equal(err->msg,
+ "'FILENAME' variable is forbidden in source files. It will be set "
+ "for you by the compiler.");
+ blogc_error_free(err);
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_config_reserved_name2(void **state)
+{
+ const char *a = "CONTENT: asd\r\n";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(source);
+ assert_non_null(err);
+ assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
+ assert_string_equal(err->msg,
+ "'CONTENT' variable is forbidden in source files. It will be set "
+ "for you by the compiler.");
+ blogc_error_free(err);
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_config_reserved_name3(void **state)
+{
+ const char *a = "DATE_FORMATTED: asd\r\n";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(source);
+ assert_non_null(err);
+ assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
+ assert_string_equal(err->msg,
+ "'DATE_FORMATTED' variable is forbidden in source files. It will be set "
+ "for you by the compiler.");
+ blogc_error_free(err);
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_config_reserved_name4(void **state)
+{
+ const char *a = "DATE_FIRST_FORMATTED: asd\r\n";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(source);
+ assert_non_null(err);
+ assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
+ assert_string_equal(err->msg,
+ "'DATE_FIRST_FORMATTED' variable is forbidden in source files. It will be set "
+ "for you by the compiler.");
+ blogc_error_free(err);
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_config_reserved_name5(void **state)
+{
+ const char *a = "DATE_LAST_FORMATTED: asd\r\n";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(source);
+ assert_non_null(err);
+ assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
+ assert_string_equal(err->msg,
+ "'DATE_LAST_FORMATTED' variable is forbidden in source files. It will be set "
+ "for you by the compiler.");
+ blogc_error_free(err);
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_config_reserved_name6(void **state)
+{
+ const char *a = "PAGE_FIRST: asd\r\n";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(source);
+ assert_non_null(err);
+ assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
+ assert_string_equal(err->msg,
+ "'PAGE_FIRST' variable is forbidden in source files. It will be set "
+ "for you by the compiler.");
+ blogc_error_free(err);
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_config_reserved_name7(void **state)
+{
+ const char *a = "PAGE_PREVIOUS: asd\r\n";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(source);
+ assert_non_null(err);
+ assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
+ assert_string_equal(err->msg,
+ "'PAGE_PREVIOUS' variable is forbidden in source files. It will be set "
+ "for you by the compiler.");
+ blogc_error_free(err);
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_config_reserved_name8(void **state)
+{
+ const char *a = "PAGE_CURRENT: asd\r\n";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(source);
+ assert_non_null(err);
+ assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
+ assert_string_equal(err->msg,
+ "'PAGE_CURRENT' variable is forbidden in source files. It will be set "
+ "for you by the compiler.");
+ blogc_error_free(err);
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_config_reserved_name9(void **state)
+{
+ const char *a = "PAGE_NEXT: asd\r\n";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(source);
+ assert_non_null(err);
+ assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
+ assert_string_equal(err->msg,
+ "'PAGE_NEXT' variable is forbidden in source files. It will be set "
+ "for you by the compiler.");
+ blogc_error_free(err);
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_config_reserved_name10(void **state)
+{
+ const char *a = "PAGE_LAST: asd\r\n";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(source);
+ assert_non_null(err);
+ assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
+ assert_string_equal(err->msg,
+ "'PAGE_LAST' variable is forbidden in source files. It will be set "
+ "for you by the compiler.");
+ blogc_error_free(err);
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_config_reserved_name11(void **state)
+{
+ const char *a = "BLOGC_VERSION: 1.0\r\n";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(source);
+ assert_non_null(err);
+ assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
+ assert_string_equal(err->msg,
+ "'BLOGC_VERSION' variable is forbidden in source files. It will be set "
+ "for you by the compiler.");
+ blogc_error_free(err);
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_config_value_no_line_ending(void **state)
+{
+ const char *a = "BOLA: asd";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(source);
+ assert_non_null(err);
+ assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
+ assert_string_equal(err->msg,
+ "No line ending after the configuration value for 'BOLA'.\n"
+ "Error occurred near line 1, position 10: BOLA: asd");
+ blogc_error_free(err);
+ sb_trie_free(source);
+}
+
+
+static void
+test_source_parse_invalid_separator(void **state)
+{
+ const char *a = "BOLA: asd\n---#";
+ blogc_error_t *err = NULL;
+ sb_trie_t *source = blogc_source_parse(a, strlen(a), &err);
+ assert_null(source);
+ assert_non_null(err);
+ assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid content separator. Must be more than one '-' characters.\n"
+ "Error occurred near line 2, position 4: ---#");
+ blogc_error_free(err);
+ sb_trie_free(source);
+}
+
+
+int
+main(void)
+{
+ const UnitTest tests[] = {
+ unit_test(test_source_parse),
+ unit_test(test_source_parse_crlf),
+ unit_test(test_source_parse_with_spaces),
+ unit_test(test_source_parse_with_excerpt),
+ unit_test(test_source_parse_with_description),
+ unit_test(test_source_parse_config_empty),
+ unit_test(test_source_parse_config_invalid_key),
+ unit_test(test_source_parse_config_no_key),
+ unit_test(test_source_parse_config_no_key2),
+ unit_test(test_source_parse_config_no_value),
+ unit_test(test_source_parse_config_no_value2),
+ unit_test(test_source_parse_config_reserved_name),
+ unit_test(test_source_parse_config_reserved_name2),
+ unit_test(test_source_parse_config_reserved_name3),
+ unit_test(test_source_parse_config_reserved_name4),
+ unit_test(test_source_parse_config_reserved_name5),
+ unit_test(test_source_parse_config_reserved_name6),
+ unit_test(test_source_parse_config_reserved_name7),
+ unit_test(test_source_parse_config_reserved_name8),
+ unit_test(test_source_parse_config_reserved_name9),
+ unit_test(test_source_parse_config_reserved_name10),
+ unit_test(test_source_parse_config_reserved_name11),
+ unit_test(test_source_parse_config_value_no_line_ending),
+ unit_test(test_source_parse_invalid_separator),
+ };
+ return run_tests(tests);
+}
diff --git a/tests/check_template_parser.c b/tests/check_template_parser.c
new file mode 100644
index 0000000..da6a184
--- /dev/null
+++ b/tests/check_template_parser.c
@@ -0,0 +1,1184 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <string.h>
+#include "../src/template-parser.h"
+#include "../src/error.h"
+#include "../src/utils.h"
+
+
+static void
+blogc_assert_template_stmt(sb_slist_t *l, const char *value,
+ const blogc_template_stmt_type_t type)
+{
+ blogc_template_stmt_t *stmt = l->data;
+ if (value == NULL)
+ assert_null(stmt->value);
+ else
+ assert_string_equal(stmt->value, value);
+ assert_int_equal(stmt->type, type);
+}
+
+
+static void
+blogc_assert_template_if_stmt(sb_slist_t *l, const char *variable,
+ blogc_template_stmt_operator_t operator, const char *operand)
+{
+ blogc_template_stmt_t *stmt = l->data;
+ assert_string_equal(stmt->value, variable);
+ assert_int_equal(stmt->op, operator);
+ assert_string_equal(stmt->value2, operand);
+ assert_int_equal(stmt->type, BLOGC_TEMPLATE_IF_STMT);
+}
+
+
+static void
+test_template_parse(void **state)
+{
+ const char *a =
+ "Test\n"
+ "\n"
+ " {%- block entry -%}\n"
+ "{% ifdef CHUNDA %}\n"
+ "bola\n"
+ "{% endif %}\n"
+ "{% ifndef BOLA %}\n"
+ "bolao\n"
+ "{%- endif %}\n"
+ "{% endblock %}\n"
+ "{% block listing %}{{ BOLA }}{% endblock %}\n"
+ "{% block listing_once %}asd{% endblock %}\n"
+ "{%- foreach BOLA %}hahaha{% endforeach %}\n"
+ "{% if BOLA == \"1\\\"0\" %}aee{% else %}fffuuuuuuu{% endif %}";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_null(err);
+ assert_non_null(stmts);
+ blogc_assert_template_stmt(stmts, "Test",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(stmts->next, "entry",
+ BLOGC_TEMPLATE_BLOCK_STMT);
+ blogc_assert_template_stmt(stmts->next->next, "",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next, "CHUNDA",
+ BLOGC_TEMPLATE_IFDEF_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next->next, "\nbola\n",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next->next->next, NULL,
+ BLOGC_TEMPLATE_ENDIF_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next->next->next->next, "\n",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ sb_slist_t *tmp = stmts->next->next->next->next->next->next->next;
+ blogc_assert_template_stmt(tmp, "BOLA", BLOGC_TEMPLATE_IFNDEF_STMT);
+ blogc_assert_template_stmt(tmp->next, "\nbolao", BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next, NULL, BLOGC_TEMPLATE_ENDIF_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next, "\n",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ tmp = tmp->next->next->next->next;
+ blogc_assert_template_stmt(tmp, NULL, BLOGC_TEMPLATE_ENDBLOCK_STMT);
+ blogc_assert_template_stmt(tmp->next, "\n", BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next, "listing",
+ BLOGC_TEMPLATE_BLOCK_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next, "BOLA",
+ BLOGC_TEMPLATE_VARIABLE_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next,
+ NULL, BLOGC_TEMPLATE_ENDBLOCK_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next, "\n",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next,
+ "listing_once", BLOGC_TEMPLATE_BLOCK_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next->next,
+ "asd", BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next->next->next,
+ NULL, BLOGC_TEMPLATE_ENDBLOCK_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next->next->next->next,
+ "", BLOGC_TEMPLATE_CONTENT_STMT);
+ tmp = tmp->next->next->next->next->next->next->next->next->next->next;
+ blogc_assert_template_stmt(tmp, "BOLA", BLOGC_TEMPLATE_FOREACH_STMT);
+ blogc_assert_template_stmt(tmp->next, "hahaha",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next, NULL,
+ BLOGC_TEMPLATE_ENDFOREACH_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next, "\n",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_if_stmt(tmp->next->next->next->next, "BOLA",
+ BLOGC_TEMPLATE_OP_EQ, "\"1\\\"0\"");
+ blogc_assert_template_stmt(tmp->next->next->next->next->next, "aee",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next, NULL,
+ BLOGC_TEMPLATE_ELSE_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next->next,
+ "fffuuuuuuu", BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next->next->next,
+ NULL, BLOGC_TEMPLATE_ENDIF_STMT);
+ assert_null(tmp->next->next->next->next->next->next->next->next->next);
+ blogc_template_free_stmts(stmts);
+}
+
+
+static void
+test_template_parse_crlf(void **state)
+{
+ const char *a =
+ "Test\r\n"
+ "\r\n"
+ " {%- block entry -%}\r\n"
+ "{% ifdef CHUNDA %}\r\n"
+ "bola\r\n"
+ "{% endif %}\r\n"
+ "{% ifndef BOLA %}\r\n"
+ "bolao\r\n"
+ "{%- endif %}\r\n"
+ "{% endblock %}\r\n"
+ "{% block listing %}{{ BOLA }}{% endblock %}\r\n"
+ "{% block listing_once %}asd{% endblock %}\r\n"
+ "{%- foreach BOLA %}hahaha{% endforeach %}\r\n"
+ "{% if BOLA == \"1\\\"0\" %}aee{% else %}fffuuuuuuu{% endif %}";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_null(err);
+ assert_non_null(stmts);
+ blogc_assert_template_stmt(stmts, "Test",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(stmts->next, "entry",
+ BLOGC_TEMPLATE_BLOCK_STMT);
+ blogc_assert_template_stmt(stmts->next->next, "",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next, "CHUNDA",
+ BLOGC_TEMPLATE_IFDEF_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next->next, "\r\nbola\r\n",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next->next->next, NULL,
+ BLOGC_TEMPLATE_ENDIF_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next->next->next->next, "\r\n",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ sb_slist_t *tmp = stmts->next->next->next->next->next->next->next;
+ blogc_assert_template_stmt(tmp, "BOLA", BLOGC_TEMPLATE_IFNDEF_STMT);
+ blogc_assert_template_stmt(tmp->next, "\r\nbolao", BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next, NULL, BLOGC_TEMPLATE_ENDIF_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next, "\r\n",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ tmp = tmp->next->next->next->next;
+ blogc_assert_template_stmt(tmp, NULL, BLOGC_TEMPLATE_ENDBLOCK_STMT);
+ blogc_assert_template_stmt(tmp->next, "\r\n", BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next, "listing",
+ BLOGC_TEMPLATE_BLOCK_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next, "BOLA",
+ BLOGC_TEMPLATE_VARIABLE_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next,
+ NULL, BLOGC_TEMPLATE_ENDBLOCK_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next, "\r\n",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next,
+ "listing_once", BLOGC_TEMPLATE_BLOCK_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next->next,
+ "asd", BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next->next->next,
+ NULL, BLOGC_TEMPLATE_ENDBLOCK_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next->next->next->next,
+ "", BLOGC_TEMPLATE_CONTENT_STMT);
+ tmp = tmp->next->next->next->next->next->next->next->next->next->next;
+ blogc_assert_template_stmt(tmp, "BOLA", BLOGC_TEMPLATE_FOREACH_STMT);
+ blogc_assert_template_stmt(tmp->next, "hahaha",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next, NULL,
+ BLOGC_TEMPLATE_ENDFOREACH_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next, "\r\n",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_if_stmt(tmp->next->next->next->next, "BOLA",
+ BLOGC_TEMPLATE_OP_EQ, "\"1\\\"0\"");
+ blogc_assert_template_stmt(tmp->next->next->next->next->next, "aee",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next, NULL,
+ BLOGC_TEMPLATE_ELSE_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next->next,
+ "fffuuuuuuu", BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next->next->next,
+ NULL, BLOGC_TEMPLATE_ENDIF_STMT);
+ assert_null(tmp->next->next->next->next->next->next->next->next->next);
+ blogc_template_free_stmts(stmts);
+}
+
+
+static void
+test_template_parse_html(void **state)
+{
+ const char *a =
+ "<html>\n"
+ " <head>\n"
+ " {% block entry %}\n"
+ " <title>My cool blog >> {{ TITLE }}</title>\n"
+ " {% endblock %}\n"
+ " {% block listing_once %}\n"
+ " <title>My cool blog - Main page</title>\n"
+ " {% endblock %}\n"
+ " </head>\n"
+ " <body>\n"
+ " <h1>My cool blog</h1>\n"
+ " {% block entry %}\n"
+ " <h2>{{ TITLE }}</h2>\n"
+ " {% ifdef DATE %}<h4>Published in: {{ DATE }}</h4>{% endif %}\n"
+ " <pre>{{ CONTENT }}</pre>\n"
+ " {% endblock %}\n"
+ " {% block listing_once %}<ul>{% endblock %}\n"
+ " {% block listing %}<p><a href=\"{{ FILENAME }}.html\">"
+ "{{ TITLE }}</a>{% ifdef DATE %} - {{ DATE }}{% endif %}</p>{% endblock %}\n"
+ " {% block listing_once %}</ul>{% endblock %}\n"
+ " </body>\n"
+ "</html>\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_null(err);
+ assert_non_null(stmts);
+ blogc_assert_template_stmt(stmts, "<html>\n <head>\n ",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(stmts->next, "entry",
+ BLOGC_TEMPLATE_BLOCK_STMT);
+ blogc_assert_template_stmt(stmts->next->next,
+ "\n <title>My cool blog >> ", BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next, "TITLE",
+ BLOGC_TEMPLATE_VARIABLE_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next->next,
+ "</title>\n ", BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next->next->next, NULL,
+ BLOGC_TEMPLATE_ENDBLOCK_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next->next->next->next,
+ "\n ", BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next->next->next->next->next,
+ "listing_once", BLOGC_TEMPLATE_BLOCK_STMT);
+ sb_slist_t *tmp = stmts->next->next->next->next->next->next->next->next;
+ blogc_assert_template_stmt(tmp,
+ "\n <title>My cool blog - Main page</title>\n ",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next, NULL, BLOGC_TEMPLATE_ENDBLOCK_STMT);
+ blogc_assert_template_stmt(tmp->next->next,
+ "\n </head>\n <body>\n <h1>My cool blog</h1>\n ",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next, "entry",
+ BLOGC_TEMPLATE_BLOCK_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next,
+ "\n <h2>", BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next,
+ "TITLE", BLOGC_TEMPLATE_VARIABLE_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next,
+ "</h2>\n ", BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next->next,
+ "DATE", BLOGC_TEMPLATE_IFDEF_STMT);
+ tmp = tmp->next->next->next->next->next->next->next->next;
+ blogc_assert_template_stmt(tmp, "<h4>Published in: ",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next, "DATE", BLOGC_TEMPLATE_VARIABLE_STMT);
+ blogc_assert_template_stmt(tmp->next->next, "</h4>",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next, NULL,
+ BLOGC_TEMPLATE_ENDIF_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next, "\n <pre>",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next,
+ "CONTENT", BLOGC_TEMPLATE_VARIABLE_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next,
+ "</pre>\n ", BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next->next,
+ NULL, BLOGC_TEMPLATE_ENDBLOCK_STMT);
+ tmp = tmp->next->next->next->next->next->next->next->next;
+ blogc_assert_template_stmt(tmp, "\n ", BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next, "listing_once",
+ BLOGC_TEMPLATE_BLOCK_STMT);
+ blogc_assert_template_stmt(tmp->next->next, "<ul>",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next, NULL,
+ BLOGC_TEMPLATE_ENDBLOCK_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next, "\n ",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next,
+ "listing", BLOGC_TEMPLATE_BLOCK_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next,
+ "<p><a href=\"", BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next->next,
+ "FILENAME", BLOGC_TEMPLATE_VARIABLE_STMT);
+ tmp = tmp->next->next->next->next->next->next->next->next;
+ blogc_assert_template_stmt(tmp, ".html\">", BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next, "TITLE",
+ BLOGC_TEMPLATE_VARIABLE_STMT);
+ blogc_assert_template_stmt(tmp->next->next, "</a>",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next, "DATE",
+ BLOGC_TEMPLATE_IFDEF_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next, " - ",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next, "DATE",
+ BLOGC_TEMPLATE_VARIABLE_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next,
+ NULL, BLOGC_TEMPLATE_ENDIF_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next->next,
+ "</p>", BLOGC_TEMPLATE_CONTENT_STMT);
+ tmp = tmp->next->next->next->next->next->next->next->next;
+ blogc_assert_template_stmt(tmp, NULL, BLOGC_TEMPLATE_ENDBLOCK_STMT);
+ blogc_assert_template_stmt(tmp->next, "\n ",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next, "listing_once",
+ BLOGC_TEMPLATE_BLOCK_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next, "</ul>",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next, NULL,
+ BLOGC_TEMPLATE_ENDBLOCK_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next,
+ "\n </body>\n</html>\n", BLOGC_TEMPLATE_CONTENT_STMT);
+ assert_null(tmp->next->next->next->next->next->next);
+ blogc_template_free_stmts(stmts);
+}
+
+
+static void
+test_template_parse_ifdef_and_var_outside_block(void **state)
+{
+ const char *a =
+ "{% ifdef GUDA %}bola{% endif %}\n"
+ "{{ BOLA }}\n"
+ "{% ifndef CHUNDA %}{{ CHUNDA }}{% endif %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_null(err);
+ assert_non_null(stmts);
+ blogc_assert_template_stmt(stmts, "GUDA", BLOGC_TEMPLATE_IFDEF_STMT);
+ blogc_assert_template_stmt(stmts->next, "bola",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(stmts->next->next, NULL,
+ BLOGC_TEMPLATE_ENDIF_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next, "\n",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next->next, "BOLA",
+ BLOGC_TEMPLATE_VARIABLE_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next->next->next, "\n",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next->next->next->next,
+ "CHUNDA", BLOGC_TEMPLATE_IFNDEF_STMT);
+ sb_slist_t *tmp = stmts->next->next->next->next->next->next->next;
+ blogc_assert_template_stmt(tmp, "CHUNDA", BLOGC_TEMPLATE_VARIABLE_STMT);
+ blogc_assert_template_stmt(tmp->next, NULL, BLOGC_TEMPLATE_ENDIF_STMT);
+ blogc_assert_template_stmt(tmp->next->next, "\n",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ assert_null(tmp->next->next->next);
+ blogc_template_free_stmts(stmts);
+}
+
+
+static void
+test_template_parse_nested_else(void **state)
+{
+ const char *a =
+ "{% ifdef GUDA %}\n"
+ "{% ifdef BOLA %}\n"
+ "asd\n"
+ "{% else %}\n"
+ "{% ifdef CHUNDA %}\n"
+ "qwe\n"
+ "{% else %}\n"
+ "rty\n"
+ "{% endif %}\n"
+ "{% endif %}\n"
+ "{% ifdef LOL %}\n"
+ "zxc\n"
+ "{% else %}\n"
+ "bnm\n"
+ "{% endif %}\n"
+ "{% endif %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_null(err);
+ assert_non_null(stmts);
+ blogc_assert_template_stmt(stmts, "GUDA", BLOGC_TEMPLATE_IFDEF_STMT);
+ blogc_assert_template_stmt(stmts->next, "\n", BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(stmts->next->next, "BOLA", BLOGC_TEMPLATE_IFDEF_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next, "\nasd\n",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next->next, NULL,
+ BLOGC_TEMPLATE_ELSE_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next->next->next, "\n",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next->next->next->next,
+ "CHUNDA", BLOGC_TEMPLATE_IFDEF_STMT);
+ blogc_assert_template_stmt(stmts->next->next->next->next->next->next->next,
+ "\nqwe\n", BLOGC_TEMPLATE_CONTENT_STMT);
+ sb_slist_t *tmp = stmts->next->next->next->next->next->next->next->next;
+ blogc_assert_template_stmt(tmp, NULL, BLOGC_TEMPLATE_ELSE_STMT);
+ blogc_assert_template_stmt(tmp->next, "\nrty\n", BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next, NULL,
+ BLOGC_TEMPLATE_ENDIF_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next, "\n",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next, NULL,
+ BLOGC_TEMPLATE_ENDIF_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next, "\n",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next,
+ "LOL", BLOGC_TEMPLATE_IFDEF_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next->next->next,
+ "\nzxc\n", BLOGC_TEMPLATE_CONTENT_STMT);
+ tmp = tmp->next->next->next->next->next->next->next->next;
+ blogc_assert_template_stmt(tmp, NULL, BLOGC_TEMPLATE_ELSE_STMT);
+ blogc_assert_template_stmt(tmp->next, "\nbnm\n", BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next, NULL,
+ BLOGC_TEMPLATE_ENDIF_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next, "\n",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next, NULL,
+ BLOGC_TEMPLATE_ENDIF_STMT);
+ blogc_assert_template_stmt(tmp->next->next->next->next->next, "\n",
+ BLOGC_TEMPLATE_CONTENT_STMT);
+ assert_null(tmp->next->next->next->next->next->next);
+ blogc_template_free_stmts(stmts);
+}
+
+
+static void
+test_template_parse_invalid_block_start(void **state)
+{
+ const char *a = "{% ASD %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid statement syntax. Must begin with lowercase letter.\n"
+ "Error occurred near line 1, position 4: {% ASD %}");
+ blogc_error_free(err);
+ a = "{%-- block entry %}\n";
+ err = NULL;
+ stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid statement syntax. Duplicated whitespace cleaner before statement.\n"
+ "Error occurred near line 1, position 4: {%-- block entry %}");
+ blogc_error_free(err);
+ a = "{% block entry --%}\n";
+ err = NULL;
+ stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid statement syntax. Duplicated whitespace cleaner after statement.\n"
+ "Error occurred near line 1, position 17: {% block entry --%}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_block_nested(void **state)
+{
+ const char *a =
+ "{% block entry %}\n"
+ "{% block listing %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Blocks can't be nested.\n"
+ "Error occurred near line 2, position 9: {% block listing %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_foreach_nested(void **state)
+{
+ const char *a =
+ "{% foreach A %}\n"
+ "{% foreach B %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "'foreach' statements can't be nested.\n"
+ "Error occurred near line 2, position 11: {% foreach B %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_block_not_open(void **state)
+{
+ const char *a = "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "'endblock' statement without an open 'block' statement.\n"
+ "Error occurred near line 1, position 12: {% endblock %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_endif_not_open(void **state)
+{
+ const char *a = "{% block listing %}{% endif %}{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "'endif' statement without an open 'if', 'ifdef' or 'ifndef' statement.\n"
+ "Error occurred near line 1, position 28: "
+ "{% block listing %}{% endif %}{% endblock %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_endif_not_open_inside_block(void **state)
+{
+ const char *a = "{% ifdef BOLA %}{% block listing %}{% endif %}{% endblock %}";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "'endif' statement without an open 'if', 'ifdef' or 'ifndef' statement.\n"
+ "Error occurred near line 1, position 44: {% ifdef BOLA %}{% block "
+ "listing %}{% endif %}{% endblock %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_else_not_open_inside_block(void **state)
+{
+ const char *a = "{% ifdef BOLA %}{% block listing %}{% else %}{% endif %}{% endblock %}";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "'else' statement without an open 'if', 'ifdef' or 'ifndef' statement.\n"
+ "Error occurred near line 1, position 43: {% ifdef BOLA %}"
+ "{% block listing %}{% else %}{% endif %}{% endblock %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_endforeach_not_open(void **state)
+{
+ const char *a = "{% endforeach %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "'endforeach' statement without an open 'foreach' statement.\n"
+ "Error occurred near line 1, position 14: {% endforeach %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_endforeach_not_open_inside_block(void **state)
+{
+ const char *a = "{% foreach TAGS %}{% block entry %}{% endforeach %}"
+ "{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "'endforeach' statement without an open 'foreach' statement.\n"
+ "Error occurred near line 1, position 49: {% foreach TAGS %}"
+ "{% block entry %}{% endforeach %}{% endblock %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_endforeach_not_open_inside_block2(void **state)
+{
+ const char *a = "{% block entry %}{% foreach TAGS %}"
+ "{% endforeach %}{% endforeach %}{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "'endforeach' statement without an open 'foreach' statement.\n"
+ "Error occurred near line 1, position 65: {% block entry %}"
+ "{% foreach TAGS %}{% endforeach %}{% endforeach %}{% endblock %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_endforeach_not_closed_inside_block(void **state)
+{
+ const char *a = "{% block entry %}{% foreach TAGS %}{% endblock %}"
+ "{% endforeach %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "An open 'foreach' statement was not closed inside a 'entry' block!");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_endforeach_not_closed_inside_block2(void **state)
+{
+ const char *a = "{% block entry %}{% foreach TAGS %}{% endforeach %}"
+ "{% foreach TAGS %}{% endblock %}{% endforeach %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "An open 'foreach' statement was not closed inside a 'entry' block!");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_block_name(void **state)
+{
+ const char *a = "{% chunda %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid statement type: Allowed types are: 'block', 'endblock', 'if', "
+ "'ifdef', 'ifndef', 'else', 'endif', 'foreach' and 'endforeach'.\n"
+ "Error occurred near line 1, position 10: {% chunda %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_block_type_start(void **state)
+{
+ const char *a = "{% block ENTRY %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid block syntax. Must begin with lowercase letter.\n"
+ "Error occurred near line 1, position 10: {% block ENTRY %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_block_type(void **state)
+{
+ const char *a = "{% block chunda %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid block type. Allowed types are: 'entry', 'listing' and 'listing_once'.\n"
+ "Error occurred near line 1, position 16: {% block chunda %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_ifdef_start(void **state)
+{
+ const char *a = "{% block entry %}{% ifdef guda %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid variable name. Must begin with uppercase letter.\n"
+ "Error occurred near line 1, position 27: "
+ "{% block entry %}{% ifdef guda %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_foreach_start(void **state)
+{
+ const char *a = "{% block entry %}{% foreach guda %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid foreach variable name. Must begin with uppercase letter.\n"
+ "Error occurred near line 1, position 29: "
+ "{% block entry %}{% foreach guda %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_ifdef_variable(void **state)
+{
+ const char *a = "{% block entry %}{% ifdef BoLA %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid variable name. Must be uppercase letter, number or '_'.\n"
+ "Error occurred near line 1, position 28: "
+ "{% block entry %}{% ifdef BoLA %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_ifdef_variable2(void **state)
+{
+ const char *a = "{% block entry %}{% ifdef 0123 %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid variable name. Must begin with uppercase letter.\n"
+ "Error occurred near line 1, position 27: "
+ "{% block entry %}{% ifdef 0123 %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_foreach_variable(void **state)
+{
+ const char *a = "{% block entry %}{% foreach BoLA %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid foreach variable name. Must be uppercase letter, number or '_'.\n"
+ "Error occurred near line 1, position 30: "
+ "{% block entry %}{% foreach BoLA %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_foreach_variable2(void **state)
+{
+ const char *a = "{% block entry %}{% foreach 0123 %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid foreach variable name. Must begin with uppercase letter.\n"
+ "Error occurred near line 1, position 29: {% block entry %}"
+ "{% foreach 0123 %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_if_operator(void **state)
+{
+ const char *a = "{% block entry %}{% if BOLA = \"asd\" %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid 'if' operator. Must be '<', '>', '<=', '>=', '==' or '!='.\n"
+ "Error occurred near line 1, position 29: "
+ "{% block entry %}{% if BOLA = \"asd\" %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_if_operand(void **state)
+{
+ const char *a = "{% block entry %}{% if BOLA == asd %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid 'if' operand. Must be double-quoted static string or variable.\n"
+ "Error occurred near line 1, position 32: "
+ "{% block entry %}{% if BOLA == asd %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_if_operand2(void **state)
+{
+ const char *a = "{% block entry %}{% if BOLA == \"asd %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Found an open double-quoted string.\n"
+ "Error occurred near line 1, position 32: "
+ "{% block entry %}{% if BOLA == \"asd %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_if_operand3(void **state)
+{
+ const char *a = "{% block entry %}{% if BOLA == 0123 %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid 'if' operand. Must be double-quoted static string or variable.\n"
+ "Error occurred near line 1, position 32: "
+ "{% block entry %}{% if BOLA == 0123 %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_else1(void **state)
+{
+ const char *a = "{% else %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "'else' statement without an open 'if', 'ifdef' or 'ifndef' statement.\n"
+ "Error occurred near line 1, position 8: {% else %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_else2(void **state)
+{
+ const char *a = "{% if BOLA == \"123\" %}{% if GUDA == \"1\" %}{% else %}{% else %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "More than one 'else' statement for an open 'if', 'ifdef' or 'ifndef' "
+ "statement.\nError occurred near line 1, position 60: {% if BOLA == \"123\" "
+ "%}{% if GUDA == \"1\" %}{% else %}{% else %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_else3(void **state)
+{
+ const char *a =
+ "{% if BOLA == \"123\" %}\n"
+ "{% if GUDA == \"1\" %}\n"
+ "{% else %}\n"
+ "asd\n"
+ "{% endif %}\n"
+ "{% else %}\n"
+ "{% else %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "More than one 'else' statement for an open 'if', 'ifdef' or 'ifndef' "
+ "statement.\nError occurred near line 7, position 8: {% else %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_block_end(void **state)
+{
+ const char *a = "{% block entry }}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid statement syntax. Must end with '%}'.\n"
+ "Error occurred near line 1, position 16: {% block entry }}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_variable_name(void **state)
+{
+ const char *a = "{% block entry %}{{ bola }}{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid variable name. Must begin with uppercase letter.\n"
+ "Error occurred near line 1, position 21: "
+ "{% block entry %}{{ bola }}{% endblock %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_variable_name2(void **state)
+{
+ const char *a = "{% block entry %}{{ Bola }}{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid variable name. Must be uppercase letter, number or '_'.\n"
+ "Error occurred near line 1, position 22: "
+ "{% block entry %}{{ Bola }}{% endblock %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_variable_name3(void **state)
+{
+ const char *a = "{% block entry %}{{ 0123 }}{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid variable name. Must begin with uppercase letter.\n"
+ "Error occurred near line 1, position 21: {% block entry %}{{ 0123 }}"
+ "{% endblock %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_variable_end(void **state)
+{
+ const char *a = "{% block entry %}{{ BOLA %}{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid statement syntax. Must end with '}}'.\n"
+ "Error occurred near line 1, position 26: "
+ "{% block entry %}{{ BOLA %}{% endblock %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_close(void **state)
+{
+ const char *a = "{% block entry %%\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid statement syntax. Must end with '}'.\n"
+ "Error occurred near line 1, position 17: {% block entry %%");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_close2(void **state)
+{
+ const char *a = "{% block entry %}{{ BOLA }%{% endblock %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "Invalid statement syntax. Must end with '}'.\n"
+ "Error occurred near line 1, position 27: "
+ "{% block entry %}{{ BOLA }%{% endblock %}");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_endif_not_closed(void **state)
+{
+ const char *a = "{% block entry %}{% endblock %}{% ifdef BOLA %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg, "1 open 'if', 'ifdef' and/or 'ifndef' statements "
+ "were not closed!");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_endif_not_closed_inside_block(void **state)
+{
+ const char *a = "{% block listing %}{% ifdef BOLA %}{% endblock %}{% endif %}";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "1 open 'if', 'ifdef' and/or 'ifndef' statements were not closed inside "
+ "a 'listing' block!");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_else_not_closed_inside_block(void **state)
+{
+ const char *a = "{% block listing %}{% ifdef BOLA %}{% else %}{% endblock %}{% endif %}";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg,
+ "1 open 'if', 'ifdef' and/or 'ifndef' statements were not closed inside "
+ "a 'listing' block!");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_block_not_closed(void **state)
+{
+ const char *a = "{% block entry %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg, "An open block was not closed!");
+ blogc_error_free(err);
+}
+
+
+static void
+test_template_parse_invalid_foreach_not_closed(void **state)
+{
+ const char *a = "{% foreach ASD %}\n";
+ blogc_error_t *err = NULL;
+ sb_slist_t *stmts = blogc_template_parse(a, strlen(a), &err);
+ assert_non_null(err);
+ assert_null(stmts);
+ assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
+ assert_string_equal(err->msg, "An open 'foreach' statement was not closed!");
+ blogc_error_free(err);
+}
+
+
+int
+main(void)
+{
+ const UnitTest tests[] = {
+ unit_test(test_template_parse),
+ unit_test(test_template_parse_crlf),
+ unit_test(test_template_parse_html),
+ unit_test(test_template_parse_ifdef_and_var_outside_block),
+ unit_test(test_template_parse_nested_else),
+ unit_test(test_template_parse_invalid_block_start),
+ unit_test(test_template_parse_invalid_block_nested),
+ unit_test(test_template_parse_invalid_foreach_nested),
+ unit_test(test_template_parse_invalid_block_not_open),
+ unit_test(test_template_parse_invalid_endif_not_open),
+ unit_test(test_template_parse_invalid_endif_not_open_inside_block),
+ unit_test(test_template_parse_invalid_else_not_open_inside_block),
+ unit_test(test_template_parse_invalid_endforeach_not_open),
+ unit_test(test_template_parse_invalid_endforeach_not_open_inside_block),
+ unit_test(test_template_parse_invalid_endforeach_not_open_inside_block2),
+ unit_test(test_template_parse_invalid_endforeach_not_closed_inside_block),
+ unit_test(test_template_parse_invalid_endforeach_not_closed_inside_block2),
+ unit_test(test_template_parse_invalid_block_name),
+ unit_test(test_template_parse_invalid_block_type_start),
+ unit_test(test_template_parse_invalid_block_type),
+ unit_test(test_template_parse_invalid_ifdef_start),
+ unit_test(test_template_parse_invalid_foreach_start),
+ unit_test(test_template_parse_invalid_ifdef_variable),
+ unit_test(test_template_parse_invalid_ifdef_variable2),
+ unit_test(test_template_parse_invalid_foreach_variable),
+ unit_test(test_template_parse_invalid_foreach_variable2),
+ unit_test(test_template_parse_invalid_if_operator),
+ unit_test(test_template_parse_invalid_if_operand),
+ unit_test(test_template_parse_invalid_if_operand2),
+ unit_test(test_template_parse_invalid_if_operand3),
+ unit_test(test_template_parse_invalid_else1),
+ unit_test(test_template_parse_invalid_else2),
+ unit_test(test_template_parse_invalid_else3),
+ unit_test(test_template_parse_invalid_block_end),
+ unit_test(test_template_parse_invalid_variable_name),
+ unit_test(test_template_parse_invalid_variable_name2),
+ unit_test(test_template_parse_invalid_variable_name3),
+ unit_test(test_template_parse_invalid_variable_end),
+ unit_test(test_template_parse_invalid_close),
+ unit_test(test_template_parse_invalid_close2),
+ unit_test(test_template_parse_invalid_endif_not_closed),
+ unit_test(test_template_parse_invalid_endif_not_closed_inside_block),
+ unit_test(test_template_parse_invalid_else_not_closed_inside_block),
+ unit_test(test_template_parse_invalid_block_not_closed),
+ unit_test(test_template_parse_invalid_foreach_not_closed),
+ };
+ return run_tests(tests);
+}
diff --git a/tests/check_utf8.c b/tests/check_utf8.c
new file mode 100644
index 0000000..e7be61e
--- /dev/null
+++ b/tests/check_utf8.c
@@ -0,0 +1,101 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "../src/utf8.h"
+#include "../src/utils.h"
+
+// this file MUST be ASCII
+
+
+static void
+test_utf8_valid(void **state)
+{
+ const char *c = "<a href=\"{{ BASE_URL }}/page/{{ PREVIOUS_PAGE }}/\">"
+ "\xc2\xab Newer posts</a>";
+ assert_true(blogc_utf8_validate((uint8_t*) c, strlen(c)));
+ const uint8_t d[3] = {0xe2, 0x82, 0xac}; // euro sign
+ assert_true(blogc_utf8_validate(d, 3));
+ const uint8_t e[3] = {0xef, 0xbb, 0xbf}; // utf-8 bom
+ assert_true(blogc_utf8_validate(e, 3));
+}
+
+
+static void
+test_utf8_invalid(void **state)
+{
+ const uint8_t c[4] = {0xff, 0xfe, 0xac, 0x20}; // utf-16
+ assert_false(blogc_utf8_validate(c, 4));
+ const uint8_t d[8] = {0xff, 0xfe, 0x00, 0x00, 0xac, 0x20, 0x00, 0x00}; // utf-32
+ assert_false(blogc_utf8_validate(d, 8));
+}
+
+
+static void
+test_utf8_valid_str(void **state)
+{
+ sb_string_t *s = sb_string_new();
+ sb_string_append(s,
+ "<a href=\"{{ BASE_URL }}/page/{{ PREVIOUS_PAGE }}/\">\xc2\xab Newer "
+ "posts</a>");
+ assert_true(blogc_utf8_validate_str(s));
+ sb_string_free(s, true);
+ s = sb_string_new();
+ sb_string_append(s, "\xe2\x82\xac");
+ assert_true(blogc_utf8_validate_str(s));
+ sb_string_free(s, true);
+}
+
+
+static void
+test_utf8_invalid_str(void **state)
+{
+ sb_string_t *s = sb_string_new();
+ sb_string_append(s, "\xff\xfe\xac\x20"); // utf-16
+ assert_false(blogc_utf8_validate_str(s));
+ sb_string_free(s, true);
+ s = sb_string_new();
+ sb_string_append(s, "\xff\xfe\x00\x00\xac\x20\x00\x00"); // utf-32
+ assert_false(blogc_utf8_validate_str(s));
+ sb_string_free(s, true);
+}
+
+
+static void
+test_utf8_skip_bom(void **state)
+{
+ const uint8_t c[4] = {0xef, 0xbb, 0xbf, 0};
+ assert_int_equal(blogc_utf8_skip_bom(c, 2), 0);
+ assert_int_equal(blogc_utf8_skip_bom(c, 3), 3);
+ assert_string_equal(c + 3, "");
+ const uint8_t d[8] = {0xef, 0xbb, 0xbf, 'b', 'o', 'l', 'a', 0};
+ assert_int_equal(blogc_utf8_skip_bom(d, 7), 3);
+ assert_string_equal(d + 3, "bola");
+ const uint8_t e[5] = "bola";
+ assert_int_equal(blogc_utf8_skip_bom(e, 4), 0);
+}
+
+
+int
+main(void)
+{
+ const UnitTest tests[] = {
+ unit_test(test_utf8_valid),
+ unit_test(test_utf8_invalid),
+ unit_test(test_utf8_valid_str),
+ unit_test(test_utf8_invalid_str),
+ unit_test(test_utf8_skip_bom),
+ };
+ return run_tests(tests);
+}
diff --git a/tests/common/check_utils.c b/tests/check_utils.c
index 20e6891..1750aa2 100644
--- a/tests/common/check_utils.c
+++ b/tests/check_utils.c
@@ -1,6 +1,6 @@
/*
* blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ * Copyright (C) 2014-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
*
* This program can be distributed under the terms of the BSD License.
* See the file LICENSE.
@@ -12,99 +12,58 @@
#include <cmocka.h>
#include <stdbool.h>
#include <stdlib.h>
-#include "../../src/common/utils.h"
+#include "../src/utils.h"
-#define BC_STRING_CHUNK_SIZE 128
+#define SB_STRING_CHUNK_SIZE 128
static void
test_slist_append(void **state)
{
- bc_slist_t *l = NULL;
- l = bc_slist_append(l, (void*) bc_strdup("bola"));
+ sb_slist_t *l = NULL;
+ l = sb_slist_append(l, (void*) sb_strdup("bola"));
assert_non_null(l);
assert_string_equal(l->data, "bola");
assert_null(l->next);
- l = bc_slist_append(l, (void*) bc_strdup("guda"));
+ l = sb_slist_append(l, (void*) sb_strdup("guda"));
assert_non_null(l);
assert_string_equal(l->data, "bola");
assert_non_null(l->next);
assert_string_equal(l->next->data, "guda");
assert_null(l->next->next);
- bc_slist_free_full(l, free);
+ sb_slist_free_full(l, free);
}
static void
test_slist_prepend(void **state)
{
- bc_slist_t *l = NULL;
- l = bc_slist_prepend(l, (void*) bc_strdup("bola"));
+ sb_slist_t *l = NULL;
+ l = sb_slist_prepend(l, (void*) sb_strdup("bola"));
assert_non_null(l);
assert_string_equal(l->data, "bola");
assert_null(l->next);
- l = bc_slist_prepend(l, (void*) bc_strdup("guda"));
+ l = sb_slist_prepend(l, (void*) sb_strdup("guda"));
assert_non_null(l);
assert_string_equal(l->data, "guda");
assert_non_null(l->next);
assert_string_equal(l->next->data, "bola");
assert_null(l->next->next);
- bc_slist_free_full(l, free);
-}
-
-
-static void
-test_slist_append_list(void **state)
-{
- assert_null(bc_slist_append_list(NULL, NULL));
-
- bc_slist_t *l = NULL;
- l = bc_slist_append(l, (void*) bc_strdup("bola"));
- l = bc_slist_append(l, (void*) bc_strdup("guda"));
-
- bc_slist_t *t = bc_slist_append_list(l, NULL);
- assert_non_null(t);
- assert_string_equal(t->data, "bola");
- assert_non_null(t->next);
- assert_string_equal(t->next->data, "guda");
- assert_null(t->next->next);
-
- t = bc_slist_append_list(NULL, l);
- assert_non_null(t);
- assert_string_equal(t->data, "bola");
- assert_non_null(t->next);
- assert_string_equal(t->next->data, "guda");
- assert_null(t->next->next);
-
- bc_slist_t *n = NULL;
- n = bc_slist_append(n, (void*) bc_strdup("chunda"));
- n = bc_slist_append(n, (void*) bc_strdup("asd"));
-
- t = bc_slist_append_list(l, n);
- assert_non_null(t);
- assert_string_equal(t->data, "bola");
- assert_non_null(t->next);
- assert_string_equal(t->next->data, "guda");
- assert_non_null(t->next->next);
- assert_string_equal(t->next->next->data, "chunda");
- assert_non_null(t->next->next->next);
- assert_string_equal(t->next->next->next->data, "asd");
- assert_null(t->next->next->next->next);
- bc_slist_free_full(t, free);
+ sb_slist_free_full(l, free);
}
static void
test_slist_free(void **state)
{
- bc_slist_t *l = NULL;
- char *t1 = bc_strdup("bola");
- char *t2 = bc_strdup("guda");
- char *t3 = bc_strdup("chunda");
- l = bc_slist_append(l, (void*) t1);
- l = bc_slist_append(l, (void*) t2);
- l = bc_slist_append(l, (void*) t3);
- bc_slist_free(l);
+ sb_slist_t *l = NULL;
+ char *t1 = sb_strdup("bola");
+ char *t2 = sb_strdup("guda");
+ char *t3 = sb_strdup("chunda");
+ l = sb_slist_append(l, (void*) t1);
+ l = sb_slist_append(l, (void*) t2);
+ l = sb_slist_append(l, (void*) t3);
+ sb_slist_free(l);
assert_string_equal(t1, "bola");
assert_string_equal(t2, "guda");
assert_string_equal(t3, "chunda");
@@ -117,23 +76,23 @@ test_slist_free(void **state)
static void
test_slist_length(void **state)
{
- bc_slist_t *l = NULL;
- l = bc_slist_append(l, (void*) bc_strdup("bola"));
- l = bc_slist_append(l, (void*) bc_strdup("guda"));
- l = bc_slist_append(l, (void*) bc_strdup("chunda"));
- assert_int_equal(bc_slist_length(l), 3);
- bc_slist_free_full(l, free);
- assert_int_equal(bc_slist_length(NULL), 0);
+ sb_slist_t *l = NULL;
+ l = sb_slist_append(l, (void*) sb_strdup("bola"));
+ l = sb_slist_append(l, (void*) sb_strdup("guda"));
+ l = sb_slist_append(l, (void*) sb_strdup("chunda"));
+ assert_int_equal(sb_slist_length(l), 3);
+ sb_slist_free_full(l, free);
+ assert_int_equal(sb_slist_length(NULL), 0);
}
static void
test_strdup(void **state)
{
- char *str = bc_strdup("bola");
+ char *str = sb_strdup("bola");
assert_string_equal(str, "bola");
free(str);
- str = bc_strdup(NULL);
+ str = sb_strdup(NULL);
assert_null(str);
}
@@ -141,16 +100,16 @@ test_strdup(void **state)
static void
test_strndup(void **state)
{
- char *str = bc_strndup("bolaguda", 4);
+ char *str = sb_strndup("bolaguda", 4);
assert_string_equal(str, "bola");
free(str);
- str = bc_strndup("bolaguda", 30);
+ str = sb_strndup("bolaguda", 30);
assert_string_equal(str, "bolaguda");
free(str);
- str = bc_strndup("bolaguda", 8);
+ str = sb_strndup("bolaguda", 8);
assert_string_equal(str, "bolaguda");
free(str);
- str = bc_strdup(NULL);
+ str = sb_strdup(NULL);
assert_null(str);
}
@@ -158,11 +117,10 @@ test_strndup(void **state)
static void
test_strdup_printf(void **state)
{
- assert_null(bc_strdup_printf(NULL));
- char *str = bc_strdup_printf("bola");
+ char *str = sb_strdup_printf("bola");
assert_string_equal(str, "bola");
free(str);
- str = bc_strdup_printf("bola, %s", "guda");
+ str = sb_strdup_printf("bola, %s", "guda");
assert_string_equal(str, "bola, guda");
free(str);
}
@@ -171,166 +129,141 @@ test_strdup_printf(void **state)
static void
test_str_starts_with(void **state)
{
- assert_true(bc_str_starts_with("bolaguda", "bola"));
- assert_true(bc_str_starts_with("bola", "bola"));
- assert_false(bc_str_starts_with("gudabola", "bola"));
- assert_false(bc_str_starts_with("guda", "bola"));
- assert_false(bc_str_starts_with("bola", "bolaguda"));
+ assert_true(sb_str_starts_with("bolaguda", "bola"));
+ assert_true(sb_str_starts_with("bola", "bola"));
+ assert_false(sb_str_starts_with("gudabola", "bola"));
+ assert_false(sb_str_starts_with("guda", "bola"));
+ assert_false(sb_str_starts_with("bola", "bolaguda"));
}
static void
test_str_ends_with(void **state)
{
- assert_true(bc_str_ends_with("bolaguda", "guda"));
- assert_true(bc_str_ends_with("bola", "bola"));
- assert_false(bc_str_ends_with("gudabola", "guda"));
- assert_false(bc_str_ends_with("guda", "bola"));
- assert_false(bc_str_ends_with("bola", "gudabola"));
+ assert_true(sb_str_ends_with("bolaguda", "guda"));
+ assert_true(sb_str_ends_with("bola", "bola"));
+ assert_false(sb_str_ends_with("gudabola", "guda"));
+ assert_false(sb_str_ends_with("guda", "bola"));
+ assert_false(sb_str_ends_with("bola", "gudabola"));
}
static void
test_str_lstrip(void **state)
{
- char *str = bc_strdup(" \tbola\n \t");
- assert_string_equal(bc_str_lstrip(str), "bola\n \t");
+ char *str = sb_strdup(" \tbola\n \t");
+ assert_string_equal(sb_str_lstrip(str), "bola\n \t");
free(str);
- str = bc_strdup("guda");
- assert_string_equal(bc_str_lstrip(str), "guda");
+ str = sb_strdup("guda");
+ assert_string_equal(sb_str_lstrip(str), "guda");
free(str);
- str = bc_strdup("\n");
- assert_string_equal(bc_str_lstrip(str), "");
+ str = sb_strdup("\n");
+ assert_string_equal(sb_str_lstrip(str), "");
free(str);
- str = bc_strdup("\t \n");
- assert_string_equal(bc_str_lstrip(str), "");
+ str = sb_strdup("\t \n");
+ assert_string_equal(sb_str_lstrip(str), "");
free(str);
- str = bc_strdup("");
- assert_string_equal(bc_str_lstrip(str), "");
+ str = sb_strdup("");
+ assert_string_equal(sb_str_lstrip(str), "");
free(str);
- assert_null(bc_str_lstrip(NULL));
+ assert_null(sb_str_lstrip(NULL));
}
static void
test_str_rstrip(void **state)
{
- char *str = bc_strdup(" \tbola\n \t");
- assert_string_equal(bc_str_rstrip(str), " \tbola");
+ char *str = sb_strdup(" \tbola\n \t");
+ assert_string_equal(sb_str_rstrip(str), " \tbola");
free(str);
- str = bc_strdup("guda");
- assert_string_equal(bc_str_rstrip(str), "guda");
+ str = sb_strdup("guda");
+ assert_string_equal(sb_str_rstrip(str), "guda");
free(str);
- str = bc_strdup("\n");
- assert_string_equal(bc_str_rstrip(str), "");
+ str = sb_strdup("\n");
+ assert_string_equal(sb_str_rstrip(str), "");
free(str);
- str = bc_strdup("\t \n");
- assert_string_equal(bc_str_rstrip(str), "");
+ str = sb_strdup("\t \n");
+ assert_string_equal(sb_str_rstrip(str), "");
free(str);
- str = bc_strdup("");
- assert_string_equal(bc_str_rstrip(str), "");
+ str = sb_strdup("");
+ assert_string_equal(sb_str_rstrip(str), "");
free(str);
- assert_null(bc_str_rstrip(NULL));
+ assert_null(sb_str_rstrip(NULL));
}
static void
test_str_strip(void **state)
{
- char *str = bc_strdup(" \tbola\n \t");
- assert_string_equal(bc_str_strip(str), "bola");
+ char *str = sb_strdup(" \tbola\n \t");
+ assert_string_equal(sb_str_strip(str), "bola");
free(str);
- str = bc_strdup("guda");
- assert_string_equal(bc_str_strip(str), "guda");
+ str = sb_strdup("guda");
+ assert_string_equal(sb_str_strip(str), "guda");
free(str);
- str = bc_strdup("\n");
- assert_string_equal(bc_str_strip(str), "");
+ str = sb_strdup("\n");
+ assert_string_equal(sb_str_strip(str), "");
free(str);
- str = bc_strdup("\t \n");
- assert_string_equal(bc_str_strip(str), "");
+ str = sb_strdup("\t \n");
+ assert_string_equal(sb_str_strip(str), "");
free(str);
- str = bc_strdup("");
- assert_string_equal(bc_str_strip(str), "");
+ str = sb_strdup("");
+ assert_string_equal(sb_str_strip(str), "");
free(str);
- assert_null(bc_str_strip(NULL));
+ assert_null(sb_str_strip(NULL));
}
static void
test_str_split(void **state)
{
- char **strv = bc_str_split("bola:guda:chunda", ':', 0);
+ char **strv = sb_str_split("bola:guda:chunda", ':', 0);
assert_string_equal(strv[0], "bola");
assert_string_equal(strv[1], "guda");
assert_string_equal(strv[2], "chunda");
assert_null(strv[3]);
- bc_strv_free(strv);
- strv = bc_str_split("bola:guda:chunda", ':', 2);
+ sb_strv_free(strv);
+ strv = sb_str_split("bola:guda:chunda", ':', 2);
assert_string_equal(strv[0], "bola");
assert_string_equal(strv[1], "guda:chunda");
assert_null(strv[2]);
- bc_strv_free(strv);
- strv = bc_str_split("bola:guda:chunda", ':', 1);
+ sb_strv_free(strv);
+ strv = sb_str_split("bola:guda:chunda", ':', 1);
assert_string_equal(strv[0], "bola:guda:chunda");
assert_null(strv[1]);
- bc_strv_free(strv);
- strv = bc_str_split("", ':', 1);
+ sb_strv_free(strv);
+ strv = sb_str_split("", ':', 1);
assert_null(strv[0]);
- bc_strv_free(strv);
- assert_null(bc_str_split(NULL, ':', 0));
+ sb_strv_free(strv);
+ assert_null(sb_str_split(NULL, ':', 0));
}
static void
test_str_replace(void **state)
{
- char *str = bc_str_replace("bolao", 'o', "zaz");
+ char *str = sb_str_replace("bolao", 'o', "zaz");
assert_string_equal(str, "bzazlazaz");
free(str);
- str = bc_str_replace("bolao", 'b', "zaz");
+ str = sb_str_replace("bolao", 'b', "zaz");
assert_string_equal(str, "zazolao");
free(str);
- str = bc_str_replace("bolao", 'b', NULL);
+ str = sb_str_replace("bolao", 'b', NULL);
assert_string_equal(str, "bolao");
free(str);
- assert_null(bc_str_replace(NULL, 'b', "zaz"));
+ assert_null(sb_str_replace(NULL, 'b', "zaz"));
}
static void
test_str_find(void **state)
{
- assert_null(bc_str_find(NULL, 'c'));
- assert_string_equal(bc_str_find("bola", 'l'), "la");
- assert_string_equal(bc_str_find("bo\\lalala", 'l'), "lala");
- assert_string_equal(bc_str_find("bola", '\0'), "");
- assert_null(bc_str_find("bola", 'g'));
- assert_null(bc_str_find("bo\\la", 'l'));
-}
-
-
-static void
-test_str_to_bool(void **state)
-{
- assert_false(bc_str_to_bool(NULL));
- assert_true(bc_str_to_bool("1"));
- assert_true(bc_str_to_bool("y"));
- assert_true(bc_str_to_bool("Y"));
- assert_true(bc_str_to_bool("yes"));
- assert_true(bc_str_to_bool("YES"));
- assert_true(bc_str_to_bool("true"));
- assert_true(bc_str_to_bool("TRUE"));
- assert_true(bc_str_to_bool("on"));
- assert_true(bc_str_to_bool("ON"));
- assert_false(bc_str_to_bool("0"));
- assert_false(bc_str_to_bool("n"));
- assert_false(bc_str_to_bool("N"));
- assert_false(bc_str_to_bool("no"));
- assert_false(bc_str_to_bool("NO"));
- assert_false(bc_str_to_bool("false"));
- assert_false(bc_str_to_bool("FALSE"));
- assert_false(bc_str_to_bool("off"));
- assert_false(bc_str_to_bool("OFF"));
+ assert_null(sb_str_find(NULL, 'c'));
+ assert_string_equal(sb_str_find("bola", 'l'), "la");
+ assert_string_equal(sb_str_find("bo\\lalala", 'l'), "lala");
+ assert_string_equal(sb_str_find("bola", '\0'), "");
+ assert_null(sb_str_find("bola", 'g'));
+ assert_null(sb_str_find("bo\\la", 'l'));
}
@@ -338,16 +271,16 @@ static void
test_strv_join(void **state)
{
char *pieces[] = {"guda","bola", "chunda", NULL};
- char *str = bc_strv_join(pieces, ":");
+ char *str = sb_strv_join(pieces, ":");
assert_string_equal(str, "guda:bola:chunda");
free(str);
char *pieces2[] = {NULL};
- str = bc_strv_join(pieces2, ":");
+ str = sb_strv_join(pieces2, ":");
assert_string_equal(str, "");
free(str);
- assert_null(bc_strv_join(pieces, NULL));
- assert_null(bc_strv_join(NULL, ":"));
- assert_null(bc_strv_join(NULL, NULL));
+ assert_null(sb_strv_join(pieces, NULL));
+ assert_null(sb_strv_join(NULL, ":"));
+ assert_null(sb_strv_join(NULL, NULL));
}
@@ -355,88 +288,88 @@ static void
test_strv_length(void **state)
{
char *pieces[] = {"guda","bola", "chunda", NULL};
- assert_int_equal(bc_strv_length(pieces), 3);
+ assert_int_equal(sb_strv_length(pieces), 3);
char *pieces2[] = {NULL};
- assert_int_equal(bc_strv_length(pieces2), 0);
- assert_int_equal(bc_strv_length(NULL), 0);
+ assert_int_equal(sb_strv_length(pieces2), 0);
+ assert_int_equal(sb_strv_length(NULL), 0);
}
static void
test_string_new(void **state)
{
- bc_string_t *str = bc_string_new();
+ sb_string_t *str = sb_string_new();
assert_non_null(str);
assert_string_equal(str->str, "");
assert_int_equal(str->len, 0);
- assert_int_equal(str->allocated_len, BC_STRING_CHUNK_SIZE);
- assert_null(bc_string_free(str, true));
+ assert_int_equal(str->allocated_len, SB_STRING_CHUNK_SIZE);
+ assert_null(sb_string_free(str, true));
}
static void
test_string_free(void **state)
{
- bc_string_t *str = bc_string_new();
+ sb_string_t *str = sb_string_new();
free(str->str);
- str->str = bc_strdup("bola");
+ str->str = sb_strdup("bola");
str->len = 4;
- str->allocated_len = BC_STRING_CHUNK_SIZE;
- char *tmp = bc_string_free(str, false);
+ str->allocated_len = SB_STRING_CHUNK_SIZE;
+ char *tmp = sb_string_free(str, false);
assert_string_equal(tmp, "bola");
free(tmp);
- assert_null(bc_string_free(NULL, false));
+ assert_null(sb_string_free(NULL, false));
}
static void
test_string_dup(void **state)
{
- bc_string_t *str = bc_string_new();
+ sb_string_t *str = sb_string_new();
free(str->str);
- str->str = bc_strdup("bola");
+ str->str = sb_strdup("bola");
str->len = 4;
- str->allocated_len = BC_STRING_CHUNK_SIZE;
- bc_string_t *new = bc_string_dup(str);
+ str->allocated_len = SB_STRING_CHUNK_SIZE;
+ sb_string_t *new = sb_string_dup(str);
assert_non_null(new);
assert_string_equal(new->str, "bola");
assert_int_equal(new->len, 4);
- assert_int_equal(new->allocated_len, BC_STRING_CHUNK_SIZE);
- assert_null(bc_string_free(new, true));
- assert_null(bc_string_free(str, true));
- assert_null(bc_string_dup(NULL));
+ assert_int_equal(new->allocated_len, SB_STRING_CHUNK_SIZE);
+ assert_null(sb_string_free(new, true));
+ assert_null(sb_string_free(str, true));
+ assert_null(sb_string_dup(NULL));
}
static void
test_string_append_len(void **state)
{
- bc_string_t *str = bc_string_new();
- str = bc_string_append_len(str, "guda", 4);
+ sb_string_t *str = sb_string_new();
+ str = sb_string_append_len(str, "guda", 4);
assert_non_null(str);
assert_string_equal(str->str, "guda");
assert_int_equal(str->len, 4);
- assert_int_equal(str->allocated_len, BC_STRING_CHUNK_SIZE);
- assert_null(bc_string_free(str, true));
- str = bc_string_new();
- str = bc_string_append_len(str, "guda", 4);
- str = bc_string_append_len(str, "bola", 4);
+ assert_int_equal(str->allocated_len, SB_STRING_CHUNK_SIZE);
+ assert_null(sb_string_free(str, true));
+ str = sb_string_new();
+ str = sb_string_append_len(str, "guda", 4);
+ str = sb_string_append_len(str, "bola", 4);
assert_non_null(str);
assert_string_equal(str->str, "gudabola");
assert_int_equal(str->len, 8);
- assert_int_equal(str->allocated_len, BC_STRING_CHUNK_SIZE);
- assert_null(bc_string_free(str, true));
- str = bc_string_new();
- str = bc_string_append_len(str, "guda", 3);
- str = bc_string_append_len(str, "bola", 4);
+ assert_int_equal(str->allocated_len, SB_STRING_CHUNK_SIZE);
+ assert_null(sb_string_free(str, true));
+ str = sb_string_new();
+ str = sb_string_append_len(str, "guda", 3);
+ str = sb_string_append_len(str, "bola", 4);
assert_non_null(str);
assert_string_equal(str->str, "gudbola");
assert_int_equal(str->len, 7);
- assert_int_equal(str->allocated_len, BC_STRING_CHUNK_SIZE);
- assert_null(bc_string_free(str, true));
- str = bc_string_new();
- str = bc_string_append_len(str, "guda", 4);
- str = bc_string_append_len(str,
+ assert_int_equal(str->allocated_len, SB_STRING_CHUNK_SIZE);
+ assert_null(sb_string_free(str, true));
+ str = sb_string_new();
+ str = sb_string_append_len(str, "guda", 4);
+ str = sb_string_append_len(str,
"cwlwmwxxmvjnwtidmjehzdeexbxjnjowruxjrqpgpfhmvwgqeacdjissntmbtsjidzkcw"
"nnqhxhneolbwqlctcxmrsutolrjikpavxombpfpjyaqltgvzrjidotalcuwrwxtaxjiwa"
"xfhfyzymtffusoqywaruxpybwggukltspqqmghzpqstvcvlqbkhquihzndnrvkaqvevaz"
@@ -446,8 +379,8 @@ test_string_append_len(void **state)
"dxntikgoqlidfnmdhxzevqzlzubvyleeksdirmmttqthhkvfjggznpmarcamacpvwsrnr"
"ftzfeyasjpxoevyptpdnqokswiondusnuymqwaryrmdgscbnuilxtypuynckancsfnwtg"
"okxhegoifakimxbbafkeannglvsxprqzfekdinssqymtfexf", 600);
- str = bc_string_append_len(str, NULL, 0);
- str = bc_string_append_len(str,
+ str = sb_string_append_len(str, NULL, 0);
+ str = sb_string_append_len(str,
"cwlwmwxxmvjnwtidmjehzdeexbxjnjowruxjrqpgpfhmvwgqeacdjissntmbtsjidzkcw"
"nnqhxhneolbwqlctcxmrsutolrjikpavxombpfpjyaqltgvzrjidotalcuwrwxtaxjiwa"
"xfhfyzymtffusoqywaruxpybwggukltspqqmghzpqstvcvlqbkhquihzndnrvkaqvevaz"
@@ -478,40 +411,40 @@ test_string_append_len(void **state)
"pdnqokswiondusnuymqwaryrmdgscbnuilxtypuynckancsfnwtgokxhegoifakimxbba"
"fkeannglvsxprqzfekdinssqymtfexf");
assert_int_equal(str->len, 1204);
- assert_int_equal(str->allocated_len, BC_STRING_CHUNK_SIZE * 10);
- assert_null(bc_string_free(str, true));
- str = bc_string_new();
- str = bc_string_append_len(str, NULL, 0);
+ assert_int_equal(str->allocated_len, SB_STRING_CHUNK_SIZE * 10);
+ assert_null(sb_string_free(str, true));
+ str = sb_string_new();
+ str = sb_string_append_len(str, NULL, 0);
assert_non_null(str);
assert_string_equal(str->str, "");
assert_int_equal(str->len, 0);
- assert_int_equal(str->allocated_len, BC_STRING_CHUNK_SIZE);
- assert_null(bc_string_free(str, true));
- assert_null(bc_string_append_len(NULL, "foo", 3));
+ assert_int_equal(str->allocated_len, SB_STRING_CHUNK_SIZE);
+ assert_null(sb_string_free(str, true));
+ assert_null(sb_string_append_len(NULL, "foo", 3));
}
static void
test_string_append(void **state)
{
- bc_string_t *str = bc_string_new();
- str = bc_string_append(str, "guda");
+ sb_string_t *str = sb_string_new();
+ str = sb_string_append(str, "guda");
assert_non_null(str);
assert_string_equal(str->str, "guda");
assert_int_equal(str->len, 4);
- assert_int_equal(str->allocated_len, BC_STRING_CHUNK_SIZE);
- assert_null(bc_string_free(str, true));
- str = bc_string_new();
- str = bc_string_append(str, "guda");
- str = bc_string_append(str, "bola");
+ assert_int_equal(str->allocated_len, SB_STRING_CHUNK_SIZE);
+ assert_null(sb_string_free(str, true));
+ str = sb_string_new();
+ str = sb_string_append(str, "guda");
+ str = sb_string_append(str, "bola");
assert_non_null(str);
assert_string_equal(str->str, "gudabola");
assert_int_equal(str->len, 8);
- assert_int_equal(str->allocated_len, BC_STRING_CHUNK_SIZE);
- assert_null(bc_string_free(str, true));
- str = bc_string_new();
- str = bc_string_append(str, "guda");
- str = bc_string_append(str,
+ assert_int_equal(str->allocated_len, SB_STRING_CHUNK_SIZE);
+ assert_null(sb_string_free(str, true));
+ str = sb_string_new();
+ str = sb_string_append(str, "guda");
+ str = sb_string_append(str,
"cwlwmwxxmvjnwtidmjehzdeexbxjnjowruxjrqpgpfhmvwgqeacdjissntmbtsjidzkcw"
"nnqhxhneolbwqlctcxmrsutolrjikpavxombpfpjyaqltgvzrjidotalcuwrwxtaxjiwa"
"xfhfyzymtffusoqywaruxpybwggukltspqqmghzpqstvcvlqbkhquihzndnrvkaqvevaz"
@@ -521,8 +454,8 @@ test_string_append(void **state)
"dxntikgoqlidfnmdhxzevqzlzubvyleeksdirmmttqthhkvfjggznpmarcamacpvwsrnr"
"ftzfeyasjpxoevyptpdnqokswiondusnuymqwaryrmdgscbnuilxtypuynckancsfnwtg"
"okxhegoifakimxbbafkeannglvsxprqzfekdinssqymtfexf");
- str = bc_string_append(str, NULL);
- str = bc_string_append(str,
+ str = sb_string_append(str, NULL);
+ str = sb_string_append(str,
"cwlwmwxxmvjnwtidmjehzdeexbxjnjowruxjrqpgpfhmvwgqeacdjissntmbtsjidzkcw"
"nnqhxhneolbwqlctcxmrsutolrjikpavxombpfpjyaqltgvzrjidotalcuwrwxtaxjiwa"
"xfhfyzymtffusoqywaruxpybwggukltspqqmghzpqstvcvlqbkhquihzndnrvkaqvevaz"
@@ -553,27 +486,27 @@ test_string_append(void **state)
"pdnqokswiondusnuymqwaryrmdgscbnuilxtypuynckancsfnwtgokxhegoifakimxbba"
"fkeannglvsxprqzfekdinssqymtfexf");
assert_int_equal(str->len, 1204);
- assert_int_equal(str->allocated_len, BC_STRING_CHUNK_SIZE * 10);
- assert_null(bc_string_free(str, true));
- str = bc_string_new();
- str = bc_string_append(str, NULL);
+ assert_int_equal(str->allocated_len, SB_STRING_CHUNK_SIZE * 10);
+ assert_null(sb_string_free(str, true));
+ str = sb_string_new();
+ str = sb_string_append(str, NULL);
assert_non_null(str);
assert_string_equal(str->str, "");
assert_int_equal(str->len, 0);
- assert_int_equal(str->allocated_len, BC_STRING_CHUNK_SIZE);
- assert_null(bc_string_free(str, true));
- assert_null(bc_string_append(NULL, "asd"));
- assert_null(bc_string_append(NULL, NULL));
+ assert_int_equal(str->allocated_len, SB_STRING_CHUNK_SIZE);
+ assert_null(sb_string_free(str, true));
+ assert_null(sb_string_append(NULL, "asd"));
+ assert_null(sb_string_append(NULL, NULL));
}
static void
test_string_append_c(void **state)
{
- bc_string_t *str = bc_string_new();
- str = bc_string_append_len(str, "guda", 4);
+ sb_string_t *str = sb_string_new();
+ str = sb_string_append_len(str, "guda", 4);
for (int i = 0; i < 600; i++)
- str = bc_string_append_c(str, 'c');
+ str = sb_string_append_c(str, 'c');
assert_non_null(str);
assert_string_equal(str->str,
"gudaccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
@@ -586,65 +519,62 @@ test_string_append_c(void **state)
"ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
"cccccccccccccccccccccccccccccccccccccccccccccccccccc");
assert_int_equal(str->len, 604);
- assert_int_equal(str->allocated_len, BC_STRING_CHUNK_SIZE * 5);
- assert_null(bc_string_free(str, true));
- assert_null(bc_string_append_c(NULL, 0));
+ assert_int_equal(str->allocated_len, SB_STRING_CHUNK_SIZE * 5);
+ assert_null(sb_string_free(str, true));
+ assert_null(sb_string_append_c(NULL, 0));
}
static void
test_string_append_printf(void **state)
{
- bc_string_t *str = bc_string_new();
- str = bc_string_append_printf(str, NULL);
- assert_string_equal(str->str, "");
- assert_non_null(str);
- str = bc_string_append_printf(str, "guda: %s %d", "bola", 1);
+ sb_string_t *str = sb_string_new();
+ str = sb_string_append_printf(str, "guda: %s %d", "bola", 1);
assert_non_null(str);
assert_string_equal(str->str, "guda: bola 1");
assert_int_equal(str->len, 12);
- assert_int_equal(str->allocated_len, BC_STRING_CHUNK_SIZE);
- assert_null(bc_string_free(str, true));
- assert_null(bc_string_append_printf(NULL, "asd"));
+ assert_int_equal(str->allocated_len, SB_STRING_CHUNK_SIZE);
+ assert_null(sb_string_free(str, true));
+ assert_null(sb_string_append_printf(NULL, "asd"));
}
static void
test_string_append_escaped(void **state)
{
- bc_string_t *str = bc_string_new();
- str = bc_string_append_escaped(str, NULL);
+ sb_string_t *str = sb_string_new();
+ str = sb_string_append_escaped(str, NULL);
assert_non_null(str);
assert_string_equal(str->str, "");
assert_int_equal(str->len, 0);
- assert_int_equal(str->allocated_len, BC_STRING_CHUNK_SIZE);
- str = bc_string_append_escaped(str, "foo \\a bar \\\\ lol");
+ assert_int_equal(str->allocated_len, SB_STRING_CHUNK_SIZE);
+ str = sb_string_append_escaped(str, "foo \\a bar \\\\ lol");
assert_non_null(str);
assert_string_equal(str->str, "foo a bar \\ lol");
assert_int_equal(str->len, 15);
- assert_int_equal(str->allocated_len, BC_STRING_CHUNK_SIZE);
- assert_null(bc_string_free(str, true));
- assert_null(bc_string_append_escaped(NULL, "asd"));
+ assert_int_equal(str->allocated_len, SB_STRING_CHUNK_SIZE);
+ assert_null(sb_string_free(str, true));
+ assert_null(sb_string_append_escaped(NULL, "asd"));
}
static void
test_trie_new(void **state)
{
- bc_trie_t *trie = bc_trie_new(free);
+ sb_trie_t *trie = sb_trie_new(free);
assert_non_null(trie);
assert_null(trie->root);
assert_true(trie->free_func == free);
- bc_trie_free(trie);
+ sb_trie_free(trie);
}
static void
test_trie_insert(void **state)
{
- bc_trie_t *trie = bc_trie_new(free);
+ sb_trie_t *trie = sb_trie_new(free);
- bc_trie_insert(trie, "bola", bc_strdup("guda"));
+ sb_trie_insert(trie, "bola", sb_strdup("guda"));
assert_true(trie->root->key == 'b');
assert_null(trie->root->data);
assert_true(trie->root->child->key == 'o');
@@ -657,7 +587,7 @@ test_trie_insert(void **state)
assert_string_equal(trie->root->child->child->child->child->data, "guda");
- bc_trie_insert(trie, "chu", bc_strdup("nda"));
+ sb_trie_insert(trie, "chu", sb_strdup("nda"));
assert_true(trie->root->key == 'b');
assert_null(trie->root->data);
assert_true(trie->root->child->key == 'o');
@@ -679,7 +609,7 @@ test_trie_insert(void **state)
assert_string_equal(trie->root->next->child->child->child->data, "nda");
- bc_trie_insert(trie, "bote", bc_strdup("aba"));
+ sb_trie_insert(trie, "bote", sb_strdup("aba"));
assert_true(trie->root->key == 'b');
assert_null(trie->root->data);
assert_true(trie->root->child->key == 'o');
@@ -708,7 +638,7 @@ test_trie_insert(void **state)
assert_string_equal(trie->root->child->child->next->child->child->data, "aba");
- bc_trie_insert(trie, "bo", bc_strdup("haha"));
+ sb_trie_insert(trie, "bo", sb_strdup("haha"));
assert_true(trie->root->key == 'b');
assert_null(trie->root->data);
assert_true(trie->root->child->key == 'o');
@@ -739,12 +669,12 @@ test_trie_insert(void **state)
assert_true(trie->root->child->child->next->next->key == '\0');
assert_string_equal(trie->root->child->child->next->next->data, "haha");
- bc_trie_free(trie);
+ sb_trie_free(trie);
- trie = bc_trie_new(free);
+ trie = sb_trie_new(free);
- bc_trie_insert(trie, "chu", bc_strdup("nda"));
+ sb_trie_insert(trie, "chu", sb_strdup("nda"));
assert_true(trie->root->key == 'c');
assert_null(trie->root->data);
assert_true(trie->root->child->key == 'h');
@@ -755,7 +685,7 @@ test_trie_insert(void **state)
assert_string_equal(trie->root->child->child->child->data, "nda");
- bc_trie_insert(trie, "bola", bc_strdup("guda"));
+ sb_trie_insert(trie, "bola", sb_strdup("guda"));
assert_true(trie->root->key == 'c');
assert_null(trie->root->data);
assert_true(trie->root->child->key == 'h');
@@ -777,7 +707,7 @@ test_trie_insert(void **state)
assert_string_equal(trie->root->next->child->child->child->child->data, "guda");
- bc_trie_insert(trie, "bote", bc_strdup("aba"));
+ sb_trie_insert(trie, "bote", sb_strdup("aba"));
assert_true(trie->root->key == 'c');
assert_null(trie->root->data);
assert_true(trie->root->child->key == 'h');
@@ -806,7 +736,7 @@ test_trie_insert(void **state)
assert_string_equal(trie->root->next->child->child->next->child->child->data, "aba");
- bc_trie_insert(trie, "bo", bc_strdup("haha"));
+ sb_trie_insert(trie, "bo", sb_strdup("haha"));
assert_true(trie->root->key == 'c');
assert_null(trie->root->data);
assert_true(trie->root->child->key == 'h');
@@ -837,16 +767,16 @@ test_trie_insert(void **state)
assert_true(trie->root->next->child->child->next->next->key == '\0');
assert_string_equal(trie->root->next->child->child->next->next->data, "haha");
- bc_trie_free(trie);
+ sb_trie_free(trie);
}
static void
test_trie_insert_duplicated(void **state)
{
- bc_trie_t *trie = bc_trie_new(free);
+ sb_trie_t *trie = sb_trie_new(free);
- bc_trie_insert(trie, "bola", bc_strdup("guda"));
+ sb_trie_insert(trie, "bola", sb_strdup("guda"));
assert_true(trie->root->key == 'b');
assert_null(trie->root->data);
assert_true(trie->root->child->key == 'o');
@@ -858,7 +788,7 @@ test_trie_insert_duplicated(void **state)
assert_true(trie->root->child->child->child->child->key == '\0');
assert_string_equal(trie->root->child->child->child->child->data, "guda");
- bc_trie_insert(trie, "bola", bc_strdup("asdf"));
+ sb_trie_insert(trie, "bola", sb_strdup("asdf"));
assert_true(trie->root->key == 'b');
assert_null(trie->root->data);
assert_true(trie->root->child->key == 'o');
@@ -870,10 +800,10 @@ test_trie_insert_duplicated(void **state)
assert_true(trie->root->child->child->child->child->key == '\0');
assert_string_equal(trie->root->child->child->child->child->data, "asdf");
- bc_trie_free(trie);
+ sb_trie_free(trie);
trie = NULL;
- bc_trie_insert(trie, "bola", NULL);
+ sb_trie_insert(trie, "bola", NULL);
assert_null(trie);
}
@@ -881,19 +811,19 @@ test_trie_insert_duplicated(void **state)
static void
test_trie_keep_data(void **state)
{
- bc_trie_t *trie = bc_trie_new(NULL);
+ sb_trie_t *trie = sb_trie_new(NULL);
char *t1 = "guda";
char *t2 = "nda";
char *t3 = "aba";
char *t4 = "haha";
- bc_trie_insert(trie, "bola", t1);
- bc_trie_insert(trie, "chu", t2);
- bc_trie_insert(trie, "bote", t3);
- bc_trie_insert(trie, "bo", t4);
+ sb_trie_insert(trie, "bola", t1);
+ sb_trie_insert(trie, "chu", t2);
+ sb_trie_insert(trie, "bote", t3);
+ sb_trie_insert(trie, "bo", t4);
- bc_trie_free(trie);
+ sb_trie_free(trie);
assert_string_equal(t1, "guda");
assert_string_equal(t2, "nda");
@@ -905,80 +835,80 @@ test_trie_keep_data(void **state)
static void
test_trie_lookup(void **state)
{
- bc_trie_t *trie = bc_trie_new(free);
+ sb_trie_t *trie = sb_trie_new(free);
- bc_trie_insert(trie, "bola", bc_strdup("guda"));
- bc_trie_insert(trie, "chu", bc_strdup("nda"));
- bc_trie_insert(trie, "bote", bc_strdup("aba"));
- bc_trie_insert(trie, "bo", bc_strdup("haha"));
+ sb_trie_insert(trie, "bola", sb_strdup("guda"));
+ sb_trie_insert(trie, "chu", sb_strdup("nda"));
+ sb_trie_insert(trie, "bote", sb_strdup("aba"));
+ sb_trie_insert(trie, "bo", sb_strdup("haha"));
- assert_string_equal(bc_trie_lookup(trie, "bola"), "guda");
- assert_string_equal(bc_trie_lookup(trie, "chu"), "nda");
- assert_string_equal(bc_trie_lookup(trie, "bote"), "aba");
- assert_string_equal(bc_trie_lookup(trie, "bo"), "haha");
+ assert_string_equal(sb_trie_lookup(trie, "bola"), "guda");
+ assert_string_equal(sb_trie_lookup(trie, "chu"), "nda");
+ assert_string_equal(sb_trie_lookup(trie, "bote"), "aba");
+ assert_string_equal(sb_trie_lookup(trie, "bo"), "haha");
- assert_null(bc_trie_lookup(trie, "arcoiro"));
+ assert_null(sb_trie_lookup(trie, "arcoiro"));
- bc_trie_free(trie);
+ sb_trie_free(trie);
- trie = bc_trie_new(free);
+ trie = sb_trie_new(free);
- bc_trie_insert(trie, "chu", bc_strdup("nda"));
- bc_trie_insert(trie, "bola", bc_strdup("guda"));
- bc_trie_insert(trie, "bote", bc_strdup("aba"));
- bc_trie_insert(trie, "bo", bc_strdup("haha"));
- bc_trie_insert(trie, "copa", bc_strdup("bu"));
- bc_trie_insert(trie, "b", bc_strdup("c"));
- bc_trie_insert(trie, "test", bc_strdup("asd"));
+ sb_trie_insert(trie, "chu", sb_strdup("nda"));
+ sb_trie_insert(trie, "bola", sb_strdup("guda"));
+ sb_trie_insert(trie, "bote", sb_strdup("aba"));
+ sb_trie_insert(trie, "bo", sb_strdup("haha"));
+ sb_trie_insert(trie, "copa", sb_strdup("bu"));
+ sb_trie_insert(trie, "b", sb_strdup("c"));
+ sb_trie_insert(trie, "test", sb_strdup("asd"));
- assert_string_equal(bc_trie_lookup(trie, "bola"), "guda");
- assert_string_equal(bc_trie_lookup(trie, "chu"), "nda");
- assert_string_equal(bc_trie_lookup(trie, "bote"), "aba");
- assert_string_equal(bc_trie_lookup(trie, "bo"), "haha");
+ assert_string_equal(sb_trie_lookup(trie, "bola"), "guda");
+ assert_string_equal(sb_trie_lookup(trie, "chu"), "nda");
+ assert_string_equal(sb_trie_lookup(trie, "bote"), "aba");
+ assert_string_equal(sb_trie_lookup(trie, "bo"), "haha");
- assert_null(bc_trie_lookup(trie, "arcoiro"));
+ assert_null(sb_trie_lookup(trie, "arcoiro"));
- bc_trie_free(trie);
+ sb_trie_free(trie);
- assert_null(bc_trie_lookup(NULL, "bola"));
+ assert_null(sb_trie_lookup(NULL, "bola"));
}
static void
test_trie_size(void **state)
{
- bc_trie_t *trie = bc_trie_new(free);
+ sb_trie_t *trie = sb_trie_new(free);
- bc_trie_insert(trie, "bola", bc_strdup("guda"));
- bc_trie_insert(trie, "chu", bc_strdup("nda"));
- bc_trie_insert(trie, "bote", bc_strdup("aba"));
- bc_trie_insert(trie, "bo", bc_strdup("haha"));
+ sb_trie_insert(trie, "bola", sb_strdup("guda"));
+ sb_trie_insert(trie, "chu", sb_strdup("nda"));
+ sb_trie_insert(trie, "bote", sb_strdup("aba"));
+ sb_trie_insert(trie, "bo", sb_strdup("haha"));
- assert_int_equal(bc_trie_size(trie), 4);
- assert_int_equal(bc_trie_size(NULL), 0);
+ assert_int_equal(sb_trie_size(trie), 4);
+ assert_int_equal(sb_trie_size(NULL), 0);
- bc_trie_free(trie);
+ sb_trie_free(trie);
- trie = bc_trie_new(free);
+ trie = sb_trie_new(free);
- bc_trie_insert(trie, "chu", bc_strdup("nda"));
- bc_trie_insert(trie, "bola", bc_strdup("guda"));
- bc_trie_insert(trie, "bote", bc_strdup("aba"));
- bc_trie_insert(trie, "bo", bc_strdup("haha"));
- bc_trie_insert(trie, "copa", bc_strdup("bu"));
- bc_trie_insert(trie, "b", bc_strdup("c"));
- bc_trie_insert(trie, "test", bc_strdup("asd"));
+ sb_trie_insert(trie, "chu", sb_strdup("nda"));
+ sb_trie_insert(trie, "bola", sb_strdup("guda"));
+ sb_trie_insert(trie, "bote", sb_strdup("aba"));
+ sb_trie_insert(trie, "bo", sb_strdup("haha"));
+ sb_trie_insert(trie, "copa", sb_strdup("bu"));
+ sb_trie_insert(trie, "b", sb_strdup("c"));
+ sb_trie_insert(trie, "test", sb_strdup("asd"));
- assert_int_equal(bc_trie_size(trie), 7);
- assert_int_equal(bc_trie_size(NULL), 0);
+ assert_int_equal(sb_trie_size(trie), 7);
+ assert_int_equal(sb_trie_size(NULL), 0);
- bc_trie_free(trie);
+ sb_trie_free(trie);
}
-static size_t counter;
-static char *expected_keys[] = {"chu", "copa", "bola", "bote", "bo", "b", "test", "testa"};
-static char *expected_datas[] = {"nda", "bu", "guda", "aba", "haha", "c", "asd", "lol"};
+static unsigned int counter;
+static char *expected_keys[] = {"chu", "copa", "bola", "bote", "bo", "b", "test"};
+static char *expected_datas[] = {"nda", "bu", "guda", "aba", "haha", "c", "asd"};
static void
mock_foreach(const char *key, void *data, void *user_data)
@@ -992,150 +922,71 @@ mock_foreach(const char *key, void *data, void *user_data)
static void
test_trie_foreach(void **state)
{
- bc_trie_t *trie = bc_trie_new(free);
+ sb_trie_t *trie = sb_trie_new(free);
- bc_trie_insert(trie, "chu", bc_strdup("nda"));
- bc_trie_insert(trie, "bola", bc_strdup("guda"));
- bc_trie_insert(trie, "bote", bc_strdup("aba"));
- bc_trie_insert(trie, "bo", bc_strdup("haha"));
- bc_trie_insert(trie, "copa", bc_strdup("bu"));
- bc_trie_insert(trie, "b", bc_strdup("c"));
- bc_trie_insert(trie, "test", bc_strdup("asd"));
- bc_trie_insert(trie, "testa", bc_strdup("lol"));
+ sb_trie_insert(trie, "chu", sb_strdup("nda"));
+ sb_trie_insert(trie, "bola", sb_strdup("guda"));
+ sb_trie_insert(trie, "bote", sb_strdup("aba"));
+ sb_trie_insert(trie, "bo", sb_strdup("haha"));
+ sb_trie_insert(trie, "copa", sb_strdup("bu"));
+ sb_trie_insert(trie, "b", sb_strdup("c"));
+ sb_trie_insert(trie, "test", sb_strdup("asd"));
counter = 0;
- bc_trie_foreach(trie, mock_foreach, "foo");
- bc_trie_foreach(NULL, mock_foreach, "foo");
- bc_trie_foreach(trie, NULL, "foo");
- bc_trie_foreach(NULL, NULL, "foo");
- assert_int_equal(counter, 8);
-
- bc_trie_free(trie);
-}
-
-
-static void
-test_trie_inserted_after_prefix(void **state)
-{
- bc_trie_t *trie = bc_trie_new(free);
-
- bc_trie_insert(trie, "bola", bc_strdup("guda"));
- assert_true(trie->root->key == 'b');
- assert_null(trie->root->data);
- assert_true(trie->root->child->key == 'o');
- assert_null(trie->root->child->data);
- assert_true(trie->root->child->child->key == 'l');
- assert_null(trie->root->child->child->data);
- assert_true(trie->root->child->child->child->key == 'a');
- assert_null(trie->root->child->child->child->data);
- assert_true(trie->root->child->child->child->child->key == '\0');
- assert_string_equal(trie->root->child->child->child->child->data, "guda");
-
- bc_trie_insert(trie, "bolaoo", bc_strdup("asdf"));
- assert_true(trie->root->key == 'b');
- assert_null(trie->root->data);
- assert_true(trie->root->child->key == 'o');
- assert_null(trie->root->child->data);
- assert_true(trie->root->child->child->key == 'l');
- assert_null(trie->root->child->child->data);
- assert_true(trie->root->child->child->child->key == 'a');
- assert_null(trie->root->child->child->child->data);
- assert_true(trie->root->child->child->child->child->key == '\0');
- assert_string_equal(trie->root->child->child->child->child->data, "guda");
- assert_non_null(trie->root->child->child->child->child->next);
- assert_true(trie->root->child->child->child->child->next->key == 'o');
- assert_null(trie->root->child->child->child->child->next->data);
- assert_true(trie->root->child->child->child->child->next->child->key == 'o');
- assert_null(trie->root->child->child->child->child->next->child->data);
- assert_true(trie->root->child->child->child->child->next->child->child->key == '\0');
- assert_string_equal(trie->root->child->child->child->child->next->child->child->data, "asdf");
-
- assert_int_equal(bc_trie_size(trie), 2);
- assert_string_equal(bc_trie_lookup(trie, "bola"), "guda");
- assert_string_equal(bc_trie_lookup(trie, "bolaoo"), "asdf");
-
- bc_trie_free(trie);
-}
-
+ sb_trie_foreach(trie, mock_foreach, "foo");
+ sb_trie_foreach(NULL, mock_foreach, "foo");
+ sb_trie_foreach(trie, NULL, "foo");
+ sb_trie_foreach(NULL, NULL, "foo");
+ assert_int_equal(counter, 7);
-static void
-test_shell_quote(void **state)
-{
- char *t;
- t = bc_shell_quote(NULL);
- assert_string_equal(t, "''");
- free(t);
- t = bc_shell_quote("!bola");
- assert_string_equal(t, "''\\!'bola'");
- free(t);
- t = bc_shell_quote("'bola");
- assert_string_equal(t, "''\\''bola'");
- free(t);
- t = bc_shell_quote("bo!bola");
- assert_string_equal(t, "'bo'\\!'bola'");
- free(t);
- t = bc_shell_quote("bo'bola");
- assert_string_equal(t, "'bo'\\''bola'");
- free(t);
- t = bc_shell_quote("bola!");
- assert_string_equal(t, "'bola'\\!''");
- free(t);
- t = bc_shell_quote("bola'");
- assert_string_equal(t, "'bola'\\'''");
- free(t);
+ sb_trie_free(trie);
}
int
main(void)
{
- const struct CMUnitTest tests[] = {
+ const UnitTest tests[] = {
// slist
- cmocka_unit_test(test_slist_append),
- cmocka_unit_test(test_slist_prepend),
- cmocka_unit_test(test_slist_append_list),
- cmocka_unit_test(test_slist_free),
- cmocka_unit_test(test_slist_length),
+ unit_test(test_slist_append),
+ unit_test(test_slist_prepend),
+ unit_test(test_slist_free),
+ unit_test(test_slist_length),
// strfuncs
- cmocka_unit_test(test_strdup),
- cmocka_unit_test(test_strndup),
- cmocka_unit_test(test_strdup_printf),
- cmocka_unit_test(test_str_starts_with),
- cmocka_unit_test(test_str_ends_with),
- cmocka_unit_test(test_str_lstrip),
- cmocka_unit_test(test_str_rstrip),
- cmocka_unit_test(test_str_strip),
- cmocka_unit_test(test_str_split),
- cmocka_unit_test(test_str_replace),
- cmocka_unit_test(test_str_find),
- cmocka_unit_test(test_str_to_bool),
- cmocka_unit_test(test_strv_join),
- cmocka_unit_test(test_strv_length),
+ unit_test(test_strdup),
+ unit_test(test_strndup),
+ unit_test(test_strdup_printf),
+ unit_test(test_str_starts_with),
+ unit_test(test_str_ends_with),
+ unit_test(test_str_lstrip),
+ unit_test(test_str_rstrip),
+ unit_test(test_str_strip),
+ unit_test(test_str_split),
+ unit_test(test_str_replace),
+ unit_test(test_str_find),
+ unit_test(test_strv_join),
+ unit_test(test_strv_length),
// string
- cmocka_unit_test(test_string_new),
- cmocka_unit_test(test_string_free),
- cmocka_unit_test(test_string_dup),
- cmocka_unit_test(test_string_append_len),
- cmocka_unit_test(test_string_append),
- cmocka_unit_test(test_string_append_c),
- cmocka_unit_test(test_string_append_printf),
- cmocka_unit_test(test_string_append_escaped),
+ unit_test(test_string_new),
+ unit_test(test_string_free),
+ unit_test(test_string_dup),
+ unit_test(test_string_append_len),
+ unit_test(test_string_append),
+ unit_test(test_string_append_c),
+ unit_test(test_string_append_printf),
+ unit_test(test_string_append_escaped),
// trie
- cmocka_unit_test(test_trie_new),
- cmocka_unit_test(test_trie_insert),
- cmocka_unit_test(test_trie_insert_duplicated),
- cmocka_unit_test(test_trie_keep_data),
- cmocka_unit_test(test_trie_lookup),
- cmocka_unit_test(test_trie_size),
- cmocka_unit_test(test_trie_foreach),
- cmocka_unit_test(test_trie_inserted_after_prefix),
-
- // shell
- cmocka_unit_test(test_shell_quote),
+ unit_test(test_trie_new),
+ unit_test(test_trie_insert),
+ unit_test(test_trie_insert_duplicated),
+ unit_test(test_trie_keep_data),
+ unit_test(test_trie_lookup),
+ unit_test(test_trie_size),
+ unit_test(test_trie_foreach),
};
- return cmocka_run_group_tests(tests, NULL, NULL);
+ return run_tests(tests);
}
diff --git a/tests/common/check_config_parser.c b/tests/common/check_config_parser.c
deleted file mode 100644
index 5360f54..0000000
--- a/tests/common/check_config_parser.c
+++ /dev/null
@@ -1,1037 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "../../src/common/config-parser.h"
-#include "../../src/common/error.h"
-#include "../../src/common/utils.h"
-
-
-static void
-test_config_empty(void **state)
-{
- const char *a = "";
- bc_error_t *err = NULL;
- bc_config_t *c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 0);
- assert_string_equal(bc_config_get_with_default(c, "bola", "foo", "bar"), "bar");
- bc_config_free(c);
-}
-
-
-static void
-test_config_section_empty(void **state)
-{
- const char *a = "[foo]";
- bc_error_t *err = NULL;
- bc_config_t *c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- char **s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- char **k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 0);
- assert_null(k[0]);
- bc_strv_free(k);
- bc_config_free(c);
-}
-
-
-static void
-test_config_section(void **state)
-{
- const char *a =
- "[foo]\n"
- "asd = zxc";
- bc_error_t *err = NULL;
- bc_config_t *c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- char **s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "zxc");
- char **k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 1);
- assert_string_equal(k[0], "asd");
- assert_null(k[1]);
- bc_strv_free(k);
- bc_config_free(c);
-
- a =
- "[foo]\n"
- "asd = zxc\n";
- err = NULL;
- c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "zxc");
- k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 1);
- assert_string_equal(k[0], "asd");
- assert_null(k[1]);
- bc_strv_free(k);
- bc_config_free(c);
-
- a =
- "[foo]\r\n"
- "asd = zxc\r\n";
- err = NULL;
- c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "zxc");
- k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 1);
- assert_string_equal(k[0], "asd");
- assert_null(k[1]);
- bc_strv_free(k);
- bc_config_free(c);
-}
-
-
-static void
-test_config_section_multiple_keys(void **state)
-{
- const char *a =
- "[foo]\n"
- "asd = zxc\n"
- "qwe = rty \n"
- "zxc = vbn";
- bc_error_t *err = NULL;
- bc_config_t *c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- char **s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "zxc");
- assert_string_equal(bc_config_get(c, "foo", "qwe"), "rty");
- assert_string_equal(bc_config_get(c, "foo", "zxc"), "vbn");
- char **k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 3);
- assert_string_equal(k[0], "asd");
- assert_string_equal(k[1], "qwe");
- assert_string_equal(k[2], "zxc");
- assert_null(k[3]);
- bc_strv_free(k);
- bc_config_free(c);
-
- a =
- "[foo]\n"
- "asd = zxc\n"
- "qwe = rty \n"
- "zxc = vbn\n";
- err = NULL;
- c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "zxc");
- assert_string_equal(bc_config_get(c, "foo", "qwe"), "rty");
- assert_string_equal(bc_config_get(c, "foo", "zxc"), "vbn");
- k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 3);
- assert_string_equal(k[0], "asd");
- assert_string_equal(k[1], "qwe");
- assert_string_equal(k[2], "zxc");
- assert_null(k[3]);
- bc_strv_free(k);
- bc_config_free(c);
-
- a =
- "[foo]\r\n"
- "asd = zxc\r\n"
- "qwe = rty \r\n"
- "zxc = vbn\r\n";
- err = NULL;
- c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "zxc");
- assert_string_equal(bc_config_get(c, "foo", "qwe"), "rty");
- assert_string_equal(bc_config_get(c, "foo", "zxc"), "vbn");
- k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 3);
- assert_string_equal(k[0], "asd");
- assert_string_equal(k[1], "qwe");
- assert_string_equal(k[2], "zxc");
- assert_null(k[3]);
- bc_strv_free(k);
- bc_config_free(c);
-}
-
-
-static void
-test_config_section_multiple_sections(void **state)
-{
- const char *a =
- "[foo]\n"
- "asd = zxc\n"
- "qwe = rty\n"
- "zxc = vbn\n"
- "\n"
- "[bar]\n"
- "lol = hehe";
- bc_error_t *err = NULL;
- bc_config_t *c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 2);
- char **s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 2);
- assert_string_equal(s[0], "foo");
- assert_string_equal(s[1], "bar");
- assert_null(s[2]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "zxc");
- assert_string_equal(bc_config_get(c, "foo", "qwe"), "rty");
- assert_string_equal(bc_config_get(c, "foo", "zxc"), "vbn");
- assert_string_equal(bc_config_get(c, "bar", "lol"), "hehe");
- char **k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 3);
- assert_string_equal(k[0], "asd");
- assert_string_equal(k[1], "qwe");
- assert_string_equal(k[2], "zxc");
- assert_null(k[3]);
- bc_strv_free(k);
- k = bc_config_list_keys(c, "bar");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 1);
- assert_string_equal(k[0], "lol");
- assert_null(k[1]);
- bc_strv_free(k);
- bc_config_free(c);
-
- a =
- "[foo]\n"
- "asd = zxc\n"
- "qwe = rty\n"
- "zxc = vbn\n"
- "\n"
- "[bar]\n"
- "lol = hehe\n";
- err = NULL;
- c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 2);
- s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 2);
- assert_string_equal(s[0], "foo");
- assert_string_equal(s[1], "bar");
- assert_null(s[2]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "zxc");
- assert_string_equal(bc_config_get(c, "foo", "qwe"), "rty");
- assert_string_equal(bc_config_get(c, "foo", "zxc"), "vbn");
- assert_string_equal(bc_config_get(c, "bar", "lol"), "hehe");
- k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 3);
- assert_string_equal(k[0], "asd");
- assert_string_equal(k[1], "qwe");
- assert_string_equal(k[2], "zxc");
- assert_null(k[3]);
- bc_strv_free(k);
- k = bc_config_list_keys(c, "bar");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 1);
- assert_string_equal(k[0], "lol");
- assert_null(k[1]);
- bc_strv_free(k);
- bc_config_free(c);
-
- a =
- "[foo]\r\n"
- "asd = zxc\r\n"
- "qwe = rty\r\n"
- "zxc = vbn\r\n"
- "\r\n"
- "[bar]\r\n"
- "lol = hehe\r\n";
- err = NULL;
- c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 2);
- s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 2);
- assert_string_equal(s[0], "foo");
- assert_string_equal(s[1], "bar");
- assert_null(s[2]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "zxc");
- assert_string_equal(bc_config_get(c, "foo", "qwe"), "rty");
- assert_string_equal(bc_config_get(c, "foo", "zxc"), "vbn");
- assert_string_equal(bc_config_get(c, "bar", "lol"), "hehe");
- k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 3);
- assert_string_equal(k[0], "asd");
- assert_string_equal(k[1], "qwe");
- assert_string_equal(k[2], "zxc");
- assert_null(k[3]);
- bc_strv_free(k);
- k = bc_config_list_keys(c, "bar");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 1);
- assert_string_equal(k[0], "lol");
- assert_null(k[1]);
- bc_strv_free(k);
- bc_config_free(c);
-}
-
-
-static void
-test_config_section_list(void **state)
-{
- const char *a =
- "[foo]\n"
- "asd = zxc\n"
- "qwe = rty\n"
- "zxc = vbn\n"
- "\n"
- "[bar]\n"
- "lol = hehe\n"
- " asdasdadssad ";
- bc_error_t *err = NULL;
- const char *sections[] = {"bar", NULL};
- bc_config_t *c = bc_config_parse(a, strlen(a), sections, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 2);
- char **s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 2);
- assert_string_equal(s[0], "foo");
- assert_string_equal(s[1], "bar");
- assert_null(s[2]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "zxc");
- assert_string_equal(bc_config_get(c, "foo", "qwe"), "rty");
- assert_string_equal(bc_config_get(c, "foo", "zxc"), "vbn");
- char **bar = bc_config_get_list(c, "bar");
- assert_non_null(bar);
- assert_string_equal(bar[0], "lol = hehe");
- assert_string_equal(bar[1], "asdasdadssad");
- assert_null(bar[2]);
- bc_strv_free(bar);
- char **k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 3);
- assert_string_equal(k[0], "asd");
- assert_string_equal(k[1], "qwe");
- assert_string_equal(k[2], "zxc");
- assert_null(k[3]);
- bc_strv_free(k);
- k = bc_config_list_keys(c, "bar");
- assert_null(k);
- bc_config_free(c);
-
- a =
- "[foo]\n"
- "asd = zxc\n"
- "qwe = rty\n"
- "zxc = vbn\n"
- "\n"
- "[bar]\n"
- "lol = hehe\n"
- "asdasdadssad\n";
- err = NULL;
- c = bc_config_parse(a, strlen(a), sections, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 2);
- s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 2);
- assert_string_equal(s[0], "foo");
- assert_string_equal(s[1], "bar");
- assert_null(s[2]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "zxc");
- assert_string_equal(bc_config_get(c, "foo", "qwe"), "rty");
- assert_string_equal(bc_config_get(c, "foo", "zxc"), "vbn");
- bar = bc_config_get_list(c, "bar");
- assert_non_null(bar);
- assert_string_equal(bar[0], "lol = hehe");
- assert_string_equal(bar[1], "asdasdadssad");
- assert_null(bar[2]);
- bc_strv_free(bar);
- k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 3);
- assert_string_equal(k[0], "asd");
- assert_string_equal(k[1], "qwe");
- assert_string_equal(k[2], "zxc");
- assert_null(k[3]);
- bc_strv_free(k);
- k = bc_config_list_keys(c, "bar");
- assert_null(k);
- bc_config_free(c);
-
- a =
- "[foo]\r\n"
- "asd = zxc\r\n"
- "qwe = rty\r\n"
- "zxc = vbn\r\n"
- "\r\n"
- "[bar]\r\n"
- "lol = hehe\r\n"
- "asdasdadssad\r\n";
- err = NULL;
- c = bc_config_parse(a, strlen(a), sections, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 2);
- s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 2);
- assert_string_equal(s[0], "foo");
- assert_string_equal(s[1], "bar");
- assert_null(s[2]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "zxc");
- assert_string_equal(bc_config_get(c, "foo", "qwe"), "rty");
- assert_string_equal(bc_config_get(c, "foo", "zxc"), "vbn");
- bar = bc_config_get_list(c, "bar");
- assert_non_null(bar);
- assert_string_equal(bar[0], "lol = hehe");
- assert_string_equal(bar[1], "asdasdadssad");
- assert_null(bar[2]);
- bc_strv_free(bar);
- k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 3);
- assert_string_equal(k[0], "asd");
- assert_string_equal(k[1], "qwe");
- assert_string_equal(k[2], "zxc");
- assert_null(k[3]);
- bc_strv_free(k);
- k = bc_config_list_keys(c, "bar");
- assert_null(k);
- bc_config_free(c);
-}
-
-
-static void
-test_config_quoted_values(void **state)
-{
- const char *a =
- "[foo]\n"
- "a = \"lol\"\n"
- "b = \"lo\\\"l\"\n"
- "c = \"lo'l\"\n"
- "d = 'lol'\n"
- "e = 'lo\\'l'\n"
- "f = 'lo\"l'\n"
- "g = \\\\asd\n"
- "h = \"\\\\asd\"\n"
- "i = '\\\\asd'\n";
- bc_error_t *err = NULL;
- bc_config_t *c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- char **s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- char **k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 9);
- assert_string_equal(k[0], "a");
- assert_string_equal(k[1], "b");
- assert_string_equal(k[2], "c");
- assert_string_equal(k[3], "d");
- assert_string_equal(k[4], "e");
- assert_string_equal(k[5], "f");
- assert_string_equal(k[6], "g");
- assert_string_equal(k[7], "h");
- assert_string_equal(k[8], "i");
- assert_null(k[9]);
- bc_strv_free(k);
- assert_string_equal(bc_config_get(c, "foo", "a"), "lol");
- assert_string_equal(bc_config_get(c, "foo", "b"), "lo\"l");
- assert_string_equal(bc_config_get(c, "foo", "c"), "lo'l");
- assert_string_equal(bc_config_get(c, "foo", "d"), "'lol'");
- assert_string_equal(bc_config_get(c, "foo", "e"), "'lo'l'");
- assert_string_equal(bc_config_get(c, "foo", "f"), "'lo\"l'");
- assert_string_equal(bc_config_get(c, "foo", "g"), "\\asd");
- assert_string_equal(bc_config_get(c, "foo", "h"), "\\asd");
- assert_string_equal(bc_config_get(c, "foo", "i"), "'\\asd'");
- bc_config_free(c);
-
- a =
- "[foo]\n"
- "\"lol\"\n"
- "\"lo\\\"l\"\n"
- "\"lo'l\"\n"
- "'lol'\n"
- "'lo\\'l'\n"
- "'lo\"l'\n"
- "\\\\asd\n"
- "\"\\\\asd\"\n"
- "'\\\\asd'\n"
- "\n"
- "[bar]\n"
- "'lol = hehe'\n"
- "\" asdasdadssad \"";
- err = NULL;
- const char *sections[] = {"foo", "bar", NULL};
- c = bc_config_parse(a, strlen(a), sections, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 2);
- s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 2);
- assert_string_equal(s[0], "foo");
- assert_string_equal(s[1], "bar");
- assert_null(s[2]);
- bc_strv_free(s);
- char **bar = bc_config_get_list(c, "foo");
- assert_string_equal(bar[0], "lol");
- assert_string_equal(bar[1], "lo\"l");
- assert_string_equal(bar[2], "lo'l");
- assert_string_equal(bar[3], "'lol'");
- assert_string_equal(bar[4], "'lo'l'");
- assert_string_equal(bar[5], "'lo\"l'");
- assert_string_equal(bar[6], "\\asd");
- assert_string_equal(bar[7], "\\asd");
- assert_string_equal(bar[8], "'\\asd'");
- assert_null(bar[9]);
- bc_strv_free(bar);
- bar = bc_config_get_list(c, "bar");
- assert_non_null(bar);
- assert_string_equal(bar[0], "'lol = hehe'");
- assert_string_equal(bar[1], " asdasdadssad ");
- assert_null(bar[2]);
- bc_strv_free(bar);
- k = bc_config_list_keys(c, "foo");
- assert_null(k);
- k = bc_config_list_keys(c, "bar");
- assert_null(k);
- bc_config_free(c);
-}
-
-
-static void
-test_config_empty_values(void **state)
-{
- const char *a =
- "[foo]\n"
- "asd =";
- bc_error_t *err = NULL;
- bc_config_t *c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- char **s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "");
- char **k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 1);
- assert_string_equal(k[0], "asd");
- assert_null(k[1]);
- bc_strv_free(k);
- bc_config_free(c);
-
- a =
- "[foo]\n"
- "asd = \n";
- err = NULL;
- c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "");
- k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 1);
- assert_string_equal(k[0], "asd");
- assert_null(k[1]);
- bc_strv_free(k);
- bc_config_free(c);
-
- a =
- "[foo]\n"
- "asd = foo\n"
- "qwe =";
- err = NULL;
- c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "foo");
- assert_string_equal(bc_config_get(c, "foo", "qwe"), "");
- k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 2);
- assert_string_equal(k[0], "asd");
- assert_string_equal(k[1], "qwe");
- assert_null(k[2]);
- bc_strv_free(k);
- bc_config_free(c);
-
- a =
- "[foo]\n"
- "asd = foo\n"
- "qwe = \n";
- err = NULL;
- c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "foo");
- assert_string_equal(bc_config_get(c, "foo", "qwe"), "");
- k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 2);
- assert_string_equal(k[0], "asd");
- assert_string_equal(k[1], "qwe");
- assert_null(k[2]);
- bc_strv_free(k);
- bc_config_free(c);
-
- a =
- "[foo]\n"
- "asd =\n"
- "qwe = foo";
- err = NULL;
- c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "");
- assert_string_equal(bc_config_get(c, "foo", "qwe"), "foo");
- k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 2);
- assert_string_equal(k[0], "asd");
- assert_string_equal(k[1], "qwe");
- assert_null(k[2]);
- bc_strv_free(k);
- bc_config_free(c);
-
- a =
- "[foo]\n"
- "asd = \n"
- "qwe = foo\n";
- err = NULL;
- c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "");
- assert_string_equal(bc_config_get(c, "foo", "qwe"), "foo");
- k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 2);
- assert_string_equal(k[0], "asd");
- assert_string_equal(k[1], "qwe");
- assert_null(k[2]);
- bc_strv_free(k);
- bc_config_free(c);
-
- a =
- "[foo]\r\n"
- "asd =";
- err = NULL;
- c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "");
- k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 1);
- assert_string_equal(k[0], "asd");
- assert_null(k[1]);
- bc_strv_free(k);
- bc_config_free(c);
-
- a =
- "[foo]\r\n"
- "asd = \r\n";
- err = NULL;
- c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "");
- k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 1);
- assert_string_equal(k[0], "asd");
- assert_null(k[1]);
- bc_strv_free(k);
- bc_config_free(c);
-
- a =
- "[foo]\r\n"
- "asd = foo\r\n"
- "qwe =";
- err = NULL;
- c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "foo");
- assert_string_equal(bc_config_get(c, "foo", "qwe"), "");
- k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 2);
- assert_string_equal(k[0], "asd");
- assert_string_equal(k[1], "qwe");
- assert_null(k[2]);
- bc_strv_free(k);
- bc_config_free(c);
-
- a =
- "[foo]\r\n"
- "asd = foo\r\n"
- "qwe = \r\n";
- err = NULL;
- c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "foo");
- assert_string_equal(bc_config_get(c, "foo", "qwe"), "");
- k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 2);
- assert_string_equal(k[0], "asd");
- assert_string_equal(k[1], "qwe");
- assert_null(k[2]);
- bc_strv_free(k);
- bc_config_free(c);
-
- a =
- "[foo]\r\n"
- "asd =\r\n"
- "qwe = foo";
- err = NULL;
- c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "");
- assert_string_equal(bc_config_get(c, "foo", "qwe"), "foo");
- k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 2);
- assert_string_equal(k[0], "asd");
- assert_string_equal(k[1], "qwe");
- assert_null(k[2]);
- bc_strv_free(k);
- bc_config_free(c);
-
- a =
- "[foo]\r\n"
- "asd = \r\n"
- "qwe = foo\r\n";
- err = NULL;
- c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- assert_string_equal(bc_config_get(c, "foo", "asd"), "");
- assert_string_equal(bc_config_get(c, "foo", "qwe"), "foo");
- k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 2);
- assert_string_equal(k[0], "asd");
- assert_string_equal(k[1], "qwe");
- assert_null(k[2]);
- bc_strv_free(k);
- bc_config_free(c);
-}
-
-
-static void
-test_config_key_prefix(void **state)
-{
- const char *a =
- "[foo]\n"
- "LAST_FLIGHT = lol\n"
- "LAST_FLIGHT_SLUG = hehe\n";
- bc_error_t *err = NULL;
- bc_config_t *c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_null(err);
- assert_non_null(c);
- assert_non_null(c->root);
- assert_int_equal(bc_trie_size(c->root), 1);
- char **s = bc_config_list_sections(c);
- assert_non_null(s);
- assert_int_equal(bc_strv_length(s), 1);
- assert_string_equal(s[0], "foo");
- assert_null(s[1]);
- bc_strv_free(s);
- char **k = bc_config_list_keys(c, "foo");
- assert_non_null(k);
- assert_int_equal(bc_strv_length(k), 2);
- assert_string_equal(k[0], "LAST_FLIGHT");
- assert_string_equal(k[1], "LAST_FLIGHT_SLUG");
- assert_null(k[2]);
- bc_strv_free(k);
- assert_string_equal(bc_config_get(c, "foo", "LAST_FLIGHT"), "lol");
- assert_string_equal(bc_config_get(c, "foo", "LAST_FLIGHT_SLUG"), "hehe");
- bc_config_free(c);
-}
-
-
-static void
-test_config_error_start(void **state)
-{
- const char *a =
- "asd\n"
- "[foo]";
- bc_error_t *err = NULL;
- bc_config_t *c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_non_null(err);
- assert_null(c);
- assert_int_equal(err->type, BC_ERROR_CONFIG_PARSER);
- assert_string_equal(err->msg,
- "File must start with section.\n"
- "Error occurred near line 1, position 1: asd");
- bc_error_free(err);
-}
-
-
-static void
-test_config_error_section_with_newline(void **state)
-{
- const char *a =
- "[foo\nbar]";
- bc_error_t *err = NULL;
- bc_config_t *c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_non_null(err);
- assert_null(c);
- assert_int_equal(err->type, BC_ERROR_CONFIG_PARSER);
- assert_string_equal(err->msg,
- "Section names can't have new lines.\n"
- "Error occurred near line 1, position 5: [foo");
- bc_error_free(err);
-}
-
-
-static void
-test_config_error_key_without_value(void **state)
-{
- const char *a =
- "[foobar]\n"
- "asd = 12\n"
- "foo";
- bc_error_t *err = NULL;
- bc_config_t *c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_non_null(err);
- assert_null(c);
- assert_int_equal(err->type, BC_ERROR_CONFIG_PARSER);
- assert_string_equal(err->msg,
- "Key without value: foo.\n"
- "Error occurred near line 3, position 3: foo");
- bc_error_free(err);
- a =
- "[foobar]\n"
- "asd = 12\n"
- "foo\n";
- err = NULL;
- c = bc_config_parse(a, strlen(a), NULL, &err);
- assert_non_null(err);
- assert_null(c);
- assert_int_equal(err->type, BC_ERROR_CONFIG_PARSER);
- assert_string_equal(err->msg,
- "Key without value: foo.\n"
- "Error occurred near line 3, position 4: foo");
- bc_error_free(err);
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_config_empty),
- cmocka_unit_test(test_config_section_empty),
- cmocka_unit_test(test_config_section),
- cmocka_unit_test(test_config_section_multiple_keys),
- cmocka_unit_test(test_config_section_multiple_sections),
- cmocka_unit_test(test_config_section_list),
- cmocka_unit_test(test_config_quoted_values),
- cmocka_unit_test(test_config_empty_values),
- cmocka_unit_test(test_config_key_prefix),
- cmocka_unit_test(test_config_error_start),
- cmocka_unit_test(test_config_error_section_with_newline),
- cmocka_unit_test(test_config_error_key_without_value),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/common/check_sort.c b/tests/common/check_sort.c
deleted file mode 100644
index 2bc8751..0000000
--- a/tests/common/check_sort.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#include <stdlib.h>
-#include <string.h>
-#include "../../src/common/utils.h"
-#include "../../src/common/sort.h"
-
-
-static int
-sort_func(void *a, void *b)
-{
- return strcmp((char*) a, (char*) b);
-}
-
-
-static void
-test_slist_sort_empty(void **state)
-{
- bc_slist_t *l = NULL;
- assert_null(bc_slist_sort(l, (bc_sort_func_t) sort_func));
-}
-
-
-static void
-test_slist_sort_single(void **state)
-{
- bc_slist_t *l = NULL;
- l = bc_slist_append(l, bc_strdup("a"));
-
- l = bc_slist_sort(l, (bc_sort_func_t) sort_func);
-
- assert_non_null(l);
- assert_string_equal(l->data, "a");
- assert_null(l->next);
-
- bc_slist_free_full(l, free);
-}
-
-
-static void
-test_slist_sort_sorted(void **state)
-{
- bc_slist_t *l = NULL;
- l = bc_slist_append(l, bc_strdup("a"));
- l = bc_slist_append(l, bc_strdup("b"));
- l = bc_slist_append(l, bc_strdup("c"));
-
- l = bc_slist_sort(l, (bc_sort_func_t) sort_func);
-
- assert_non_null(l);
- assert_string_equal(l->data, "a");
- assert_string_equal(l->next->data, "b");
- assert_string_equal(l->next->next->data, "c");
- assert_null(l->next->next->next);
-
- bc_slist_free_full(l, free);
-}
-
-
-static void
-test_slist_sort_reverse(void **state)
-{
- bc_slist_t *l = NULL;
- l = bc_slist_append(l, bc_strdup("d"));
- l = bc_slist_append(l, bc_strdup("c"));
- l = bc_slist_append(l, bc_strdup("b"));
- l = bc_slist_append(l, bc_strdup("a"));
-
- l = bc_slist_sort(l, (bc_sort_func_t) sort_func);
-
- assert_non_null(l);
- assert_string_equal(l->data, "a");
- assert_string_equal(l->next->data, "b");
- assert_string_equal(l->next->next->data, "c");
- assert_string_equal(l->next->next->next->data, "d");
- assert_null(l->next->next->next->next);
-
- bc_slist_free_full(l, free);
-}
-
-
-static void
-test_slist_sort_mixed1(void **state)
-{
- bc_slist_t *l = NULL;
- l = bc_slist_append(l, bc_strdup("a"));
- l = bc_slist_append(l, bc_strdup("d"));
- l = bc_slist_append(l, bc_strdup("c"));
- l = bc_slist_append(l, bc_strdup("b"));
-
- l = bc_slist_sort(l, (bc_sort_func_t) sort_func);
-
- assert_non_null(l);
- assert_string_equal(l->data, "a");
- assert_string_equal(l->next->data, "b");
- assert_string_equal(l->next->next->data, "c");
- assert_string_equal(l->next->next->next->data, "d");
- assert_null(l->next->next->next->next);
-
- bc_slist_free_full(l, free);
-}
-
-
-static void
-test_slist_sort_mixed2(void **state)
-{
- bc_slist_t *l = NULL;
- l = bc_slist_append(l, bc_strdup("c"));
- l = bc_slist_append(l, bc_strdup("b"));
- l = bc_slist_append(l, bc_strdup("a"));
- l = bc_slist_append(l, bc_strdup("d"));
-
- l = bc_slist_sort(l, (bc_sort_func_t) sort_func);
-
- assert_non_null(l);
- assert_string_equal(l->data, "a");
- assert_string_equal(l->next->data, "b");
- assert_string_equal(l->next->next->data, "c");
- assert_string_equal(l->next->next->next->data, "d");
- assert_null(l->next->next->next->next);
-
- bc_slist_free_full(l, free);
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_slist_sort_empty),
- cmocka_unit_test(test_slist_sort_single),
- cmocka_unit_test(test_slist_sort_sorted),
- cmocka_unit_test(test_slist_sort_reverse),
- cmocka_unit_test(test_slist_sort_mixed1),
- cmocka_unit_test(test_slist_sort_mixed2),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/common/check_stdin.c b/tests/common/check_stdin.c
deleted file mode 100644
index 5616ee9..0000000
--- a/tests/common/check_stdin.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include "../../src/common/stdin.h"
-
-
-int
-__wrap_fgetc(FILE *stream)
-{
- assert_int_equal(fileno(stream), fileno(stdin));
- return mock_type(int);
-}
-
-
-static void
-test_read(void **state)
-{
- assert_null(bc_stdin_read(NULL));
- will_return(__wrap_fgetc, EOF);
- size_t len;
- char *t = bc_stdin_read(&len);
- assert_non_null(t);
- assert_string_equal(t, "");
- assert_int_equal(len, 0);
- free(t);
- will_return(__wrap_fgetc, 'b');
- will_return(__wrap_fgetc, 'o');
- will_return(__wrap_fgetc, 'l');
- will_return(__wrap_fgetc, 'a');
- will_return(__wrap_fgetc, EOF);
- t = bc_stdin_read(&len);
- assert_non_null(t);
- assert_string_equal(t, "bola");
- assert_int_equal(len, 4);
- free(t);
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_read),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/common/check_utf8.c b/tests/common/check_utf8.c
deleted file mode 100644
index 95e2eab..0000000
--- a/tests/common/check_utf8.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * blogc: A blog compiler.
- * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
- *
- * This program can be distributed under the terms of the BSD License.
- * See the file LICENSE.
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <string.h>
-#include "../../src/common/utf8.h"
-#include "../../src/common/utils.h"
-
-// this file MUST be ASCII
-
-
-static void
-test_utf8_valid(void **state)
-{
- const char *c = "<a href=\"{{ BASE_URL }}/page/{{ PREVIOUS_PAGE }}/\">"
- "\xc2\xab Newer posts</a>";
- assert_true(bc_utf8_validate((uint8_t*) c, strlen(c)));
- const uint8_t d[3] = {0xe2, 0x82, 0xac}; // euro sign
- assert_true(bc_utf8_validate(d, 3));
- const uint8_t e[3] = {0xef, 0xbb, 0xbf}; // utf-8 bom
- assert_true(bc_utf8_validate(e, 3));
-}
-
-
-static void
-test_utf8_invalid(void **state)
-{
- const uint8_t c[4] = {0xff, 0xfe, 0xac, 0x20}; // utf-16
- assert_false(bc_utf8_validate(c, 4));
- const uint8_t d[8] = {0xff, 0xfe, 0x00, 0x00, 0xac, 0x20, 0x00, 0x00}; // utf-32
- assert_false(bc_utf8_validate(d, 8));
- const uint8_t e[6] = {'a', 0xff, 0xfe, 0xac, 0x20, 'b'}; // utf-16
- assert_false(bc_utf8_validate(e, 6));
- const uint8_t f[10] = {'a', 0xff, 0xfe, 0x00, 0x00, 0xac, 0x20, 0x00, 0x00, 'b'}; // utf-32
- assert_false(bc_utf8_validate(f, 10));
-}
-
-
-static void
-test_utf8_valid_str(void **state)
-{
- bc_string_t *s = bc_string_new();
- bc_string_append(s,
- "<a href=\"{{ BASE_URL }}/page/{{ PREVIOUS_PAGE }}/\">\xc2\xab Newer "
- "posts</a>");
- assert_true(bc_utf8_validate_str(s));
- bc_string_free(s, true);
- s = bc_string_new();
- bc_string_append(s, "\xe2\x82\xac");
- assert_true(bc_utf8_validate_str(s));
- bc_string_free(s, true);
-}
-
-
-static void
-test_utf8_invalid_str(void **state)
-{
- bc_string_t *s = bc_string_new();
- bc_string_append(s, "\xff\xfe\xac\x20"); // utf-16
- assert_false(bc_utf8_validate_str(s));
- bc_string_free(s, true);
- s = bc_string_new();
- bc_string_append(s, "\xff\xfe\x00\x00\xac\x20\x00\x00"); // utf-32
- assert_false(bc_utf8_validate_str(s));
- bc_string_free(s, true);
-}
-
-
-static void
-test_utf8_skip_bom(void **state)
-{
- const uint8_t c[4] = {0xef, 0xbb, 0xbf, 0};
- assert_int_equal(bc_utf8_skip_bom(c, 2), 0);
- assert_int_equal(bc_utf8_skip_bom(c, 3), 3);
- assert_string_equal(c + 3, "");
- const uint8_t d[8] = {0xef, 0xbb, 0xbf, 'b', 'o', 'l', 'a', 0};
- assert_int_equal(bc_utf8_skip_bom(d, 7), 3);
- assert_string_equal(d + 3, "bola");
- const uint8_t e[5] = "bola";
- assert_int_equal(bc_utf8_skip_bom(e, 4), 0);
-}
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_utf8_valid),
- cmocka_unit_test(test_utf8_invalid),
- cmocka_unit_test(test_utf8_valid_str),
- cmocka_unit_test(test_utf8_invalid_str),
- cmocka_unit_test(test_utf8_skip_bom),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}