sudo: required
dist: trusty
+services:
+ - docker
language: c
compiler:
- gcc
- clang
-addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- packages:
- - clang-format-3.5
- - libllvm3.5
- - clang-3.5
- - gcc-5
-before_install:
- - sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-suggests --no-install-recommends devscripts equivs xdotool
+env:
+ global:
+ - BASENAME="i3wm/travis-base:$(date +'%Y-%m')-$(./travis/ha.sh)"
+ - secure: "B5IICA8MPx/FKaB50rTPqL8P1NU+Q0yuWl+lElL4+a9xSyLikfm3NzUPHoVwx8lNw2AVK6br7p0OmF7vMFjqAgrgc1cajTtEae5uFRKNUrWLpXM046YgNEYLLIHsQOjInxE+S4O6EFVzsUqsu8aeo2Xhq4sm4iUocG7e5isYgYo=" # DOCKER_PASS
+ - secure: "EIvrq8PG7lRjidppG0RCv4F0X4GP3DT9F5+ixVuGPfhK/hZT3jYC2AVY9G+NnUcXVwQEpW92rlqpftQ/qZ13FoyWokC8ZyoyD06fr5FPCfoFF3OczZwAJzZYkObI/hE9+/hXcylx/Os6N4INd2My1ntGk3JPsWL9riopod5EjSg=" # DOCKER_EMAIL
+ - secure: "hvhBunS4xXTgnIOsk/BPT7I7FrJhvVwCSt5PfxxvMqNaztOJI9BuK7ZrZ5Cy38KyHwlh3VHAH5AaCygJcPauoSQCV3bpnlbaWn3ruq2F0Q697Q5uNf73liXzyUqb9/Zvfvge4y4WWOhP5tVz1C6ZBe/NfhU7pqKLMA+6ads+99c=" # DOCKER_USER
install:
- - sudo DEBIAN_FRONTEND=noninteractive mk-build-deps --install --remove --tool 'apt-get -yq --no-install-suggests --no-install-recommends' debian/control
- # Install as many dependencies as possible via apt because cpanm is not very reliable/easy to debug.
- - sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-suggests --no-install-recommends libanyevent-perl libanyevent-i3-perl libextutils-pkgconfig-perl xcb-proto cpanminus xvfb xserver-xephyr xauth libinline-perl libxml-simple-perl libmouse-perl libmousex-nativetraits-perl libextutils-depends-perl perl-modules libtest-deep-perl libtest-exception-perl libxml-parser-perl libtest-simple-perl libtest-fatal-perl libdata-dump-perl libtest-differences-perl libxml-tokeparser-perl libtest-use-ok-perl libipc-run-perl libxcb-xtest0-dev
- - sudo /bin/sh -c 'cpanm -n -v X11::XCB || true'
- - sudo /bin/sh -c 'cpanm -n -v AnyEvent::I3 || true'
-script:
- if [ -a .git/shallow ]; then git fetch --unshallow; fi
- - if [ "$CC" = "clang" ]; then export CC="clang-3.5"; fi
- - if [ "$CC" = "gcc" ]; then export CC="gcc-5"; fi
- - CFLAGS="-Wformat -Wformat-security -Wextra -Wno-unused-parameter -Werror" make -j ASAN=1
- - (cd testcases && xvfb-run ./complete-run.pl --parallel=1 || (cat latest/complete-run.log; false))
- - clang-format-3.5 -i $(find . -name "*.[ch]" | tr '\n' ' ') && git diff --exit-code || (echo 'Code was not formatted using clang-format!'; false)
- - |
- funcs='malloc|calloc|realloc|strdup|strndup|asprintf|write'
- cstring='"([^"\\]|\\.)*"'
- cchar="'[^\\\\]'|'\\\\.[^']*'"
- regex="^([^'\"]|${cstring}|${cchar})*\<(${funcs})\>"
- detected=0
- while IFS= read -r file; do
- if { cpp -w -fpreprocessed "$file" || exit "$?"; } | grep -E -- "$regex"; then
- echo "^ $file calls a function that has a safe counterpart."
- detected=1
- fi
- done << EOF
- $(find -name '*.c' -not -name safewrappers.c -not -name strndup.c)
- EOF
- if [ "$detected" -ne 0 ]; then
- echo
- echo "Calls of functions that have safe counterparts were detected."
- exit 1
- fi
+ - docker pull ${BASENAME} || ./travis/docker-build-and-push.sh
+script:
+ - docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME} ./travis/check-safe-wrappers.sh
+ - docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME} ./travis/check-formatting.sh
+ - docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 -e CC -e CFLAGS="-Wformat -Wformat-security -Wextra -Wno-unused-parameter -Werror" ${BASENAME} make all mans -j ASAN=1
+ - docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME} ./travis/check-spelling.pl
+ - docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME} ./travis/run-tests.sh
# Second step: Generate the enum values for all states.
# It is important to keep the order the same, so we store the keys once.
-# We sort descendingly by length to be able to replace occurences of the state
+# We sort descendingly by length to be able to replace occurrences of the state
# name even when one state’s name is included in another one’s (like FOR_WINDOW
# is in FOR_WINDOW_COMMAND).
my @keys = sort { (length($b) <=> length($a)) or ($a cmp $b) } keys %states;
static void finish_input() {
char *command = (char *)concat_strings(glyphs_utf8, input_position);
- /* count the occurences of %s in the string */
+ /* count the occurrences of %s in the string */
int c;
int len = strlen(format);
int cnt = 0;
for (c = 0; c < (len - 1); c++)
if (format[c] == '%' && format[c + 1] == 's')
cnt++;
- printf("occurences = %d\n", cnt);
+ printf("occurrences = %d\n", cnt);
/* allocate space for the output */
int inputlen = strlen(command);
} placeholder_t;
/**
- * Replaces occurences of the defined placeholders in the format string.
+ * Replaces occurrences of the defined placeholders in the format string.
*
*/
char *format_placeholders(char *format, placeholder_t *placeholders, int num);
#endif
/*
- * Replaces occurences of the defined placeholders in the format string.
+ * Replaces occurrences of the defined placeholders in the format string.
*
*/
char *format_placeholders(char *format, placeholder_t *placeholders, int num) {
option, i3-input will figure out the path on its own).
-F <format>::
-Every occurence of "%s" in the <format> string is replaced by the user input,
+Every occurrence of "%s" in the <format> string is replaced by the user input,
and the result is sent to i3 as a command. Default value is "%s".
-l <limit>::
=== I3SOCK
If no ipc-socket is specified on the commandline, this variable is used
-to determine the path, at wich the unix domain socket is expected, on which
+to determine the path, at which the unix domain socket is expected, on which
to connect to i3.
== SEE ALSO
DLOG("matches window!\n");
accept_match = true;
} else {
- DLOG("doesnt match\n");
+ DLOG("doesn't match\n");
FREE(current);
continue;
}
FREE(bufcopy);
/* Then, allocate a new buffer and copy the file over to the new one,
- * but replace occurences of our variables */
+ * but replace occurrences of our variables */
char *walk = buf, *destwalk;
char *new = smalloc(stbuf.st_size + extra_bytes + 1);
destwalk = new;
--- /dev/null
+# vim:ft=Dockerfile
+FROM debian:sid
+
+RUN echo force-unsafe-io > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup
+# Paper over occasional network flakiness of some mirrors.
+RUN echo 'APT::Acquire::Retries "5";' > /etc/apt/apt.conf.d/80retry
+
+# NOTE: I tried exclusively using gce_debian_mirror.storage.googleapis.com
+# instead of httpredir.debian.org, but the results (Fetched 123 MB in 36s (3357
+# kB/s)) are not any better than httpredir.debian.org (Fetched 123 MB in 34s
+# (3608 kB/s)). Hence, let’s stick with httpredir.debian.org (default) for now.
+
+# Install mk-build-deps (for installing the i3 build dependencies),
+# clang and clang-format-3.5 (for checking formatting and building with clang),
+# lintian (for checking spelling errors),
+# test suite dependencies (for running tests)
+RUN apt-get update && \
+ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
+ dpkg-dev devscripts git equivs \
+ clang clang-format-3.5 \
+ lintian \
+ libanyevent-perl libanyevent-i3-perl libextutils-pkgconfig-perl xcb-proto cpanminus xvfb xserver-xephyr xauth libinline-perl libinline-c-perl libxml-simple-perl libmouse-perl libmousex-nativetraits-perl libextutils-depends-perl perl-modules libtest-deep-perl libtest-exception-perl libxml-parser-perl libtest-simple-perl libtest-fatal-perl libdata-dump-perl libtest-differences-perl libxml-tokeparser-perl libipc-run-perl libxcb-xtest0-dev libx11-xcb-perl libanyevent-i3-perl && \
+ rm -rf /var/lib/apt/lists/*
+
+# Install i3 build dependencies.
+COPY debian/control /usr/src/i3-debian-packaging/control
+RUN apt-get update && \
+ DEBIAN_FRONTEND=noninteractive mk-build-deps --install --remove --tool 'apt-get --no-install-recommends -y' /usr/src/i3-debian-packaging/control && \
+ rm -rf /var/lib/apt/lists/*
--- /dev/null
+#!/bin/sh
+clang-format-3.5 -i $(find . -name "*.[ch]" | tr '\n' ' ') && git diff --exit-code || (echo 'Code was not formatted using clang-format!'; false)
--- /dev/null
+#!/bin/sh
+funcs='malloc|calloc|realloc|strdup|strndup|asprintf|write'
+cstring='"([^"\\]|\\.)*"'
+cchar="'[^\\\\]'|'\\\\.[^']*'"
+regex="^([^'\"]|${cstring}|${cchar})*\<(${funcs})\>"
+detected=0
+while IFS= read -r file; do
+ if { cpp -w -fpreprocessed "$file" || exit "$?"; } | grep -E -- "$regex"; then
+ echo "^ $file calls a function that has a safe counterpart."
+ detected=1
+ fi
+done << EOF
+$(find -name '*.c' -not -name safewrappers.c -not -name strndup.c)
+EOF
+if [ "$detected" -ne 0 ]; then
+ echo
+ echo "Calls of functions that have safe counterparts were detected."
+ exit 1
+fi
--- /dev/null
+#!/usr/bin/env perl
+# vim:ts=4:sw=4:expandtab
+#
+# © 2016 Michael Stapelberg
+#
+# Checks for spelling errors in binaries and manpages (to be run by continuous
+# integration to point out spelling errors before accepting contributions).
+
+use strict;
+use warnings;
+use v5.10;
+use autodie;
+use lib 'testcases/lib';
+use i3test::Util qw(slurp);
+use Lintian::Check qw(check_spelling);
+
+# Lintian complains if we don’t set a vendor.
+use Lintian::Data;
+use Lintian::Profile;
+Lintian::Data->set_vendor(
+ Lintian::Profile->new('debian', ['/usr/share/lintian'], {}));
+
+my $exitcode = 0;
+
+# Whitelist for spelling errors in manpages, in case the spell checker has
+# false-positives.
+my $binary_spelling_exceptions = {
+ #'exmaple' => 1, # Example for how to add entries to this whitelist.
+ 'betwen' => 1, # asan_flags.inc contains this spelling error.
+};
+my @binaries = qw(
+ i3
+ i3-config-wizard/i3-config-wizard
+ i3-dump-log/i3-dump-log
+ i3-input/i3-input
+ i3-msg/i3-msg
+ i3-nagbar/i3-nagbar
+ i3bar/i3bar
+);
+for my $binary (@binaries) {
+ check_spelling(slurp($binary), $binary_spelling_exceptions, sub {
+ my ($current, $fixed) = @_;
+ say STDERR qq|Binary "$binary" contains a spelling error: "$current" should be "$fixed"|;
+ $exitcode = 1;
+ });
+}
+
+# Whitelist for spelling errors in manpages, in case the spell checker has
+# false-positives.
+my $manpage_spelling_exceptions = {
+};
+
+for my $name (glob('man/*.1')) {
+ for my $line (split(/\n/, slurp($name))) {
+ next if $line =~ /^\.\\\"/o;
+ check_spelling($line, $manpage_spelling_exceptions, sub {
+ my ($current, $fixed) = @_;
+ say STDERR qq|Manpage "$name" contains a spelling error: "$current" should be "$fixed"|;
+ $exitcode = 1;
+ });
+ }
+}
+
+exit $exitcode;
--- /dev/null
+#!/bin/sh
+
+set -e
+
+# .dockerignore is created on demand so that release.sh and other scripts are
+# not influenced by our travis setup.
+echo .git > .dockerignore
+
+docker build --pull --no-cache --rm -t=${BASENAME} -f travis-build.Dockerfile .
+docker login -e ${DOCKER_EMAIL} -u ${DOCKER_USER} -p ${DOCKER_PASS}
+docker push ${BASENAME}
--- /dev/null
+#!/bin/sh
+# Returns a hash to be used as version number suffix for the i3/travis-base
+# docker container. The hash is over all files which influence what gets
+# installed in the container, so that any changes in what needs to be installed
+# will result in a cache invalidation.
+
+cat debian/control travis-build.Dockerfile | sha256sum | dd bs=1 count=8 status=none
--- /dev/null
+#!/bin/sh
+cd testcases
+# Try running the tests in parallel so that the common case (tests pass) is
+# quick, but fall back to running them in sequence to make debugging easier.
+if ! xvfb-run ./complete-run.pl
+then
+ xvfb-run ./complete-run.pl --parallel=1 || (cat latest/complete-run.log; false)
+fi