From a839c1be33ece587f0cb9746a79dd1b704b34d3c Mon Sep 17 00:00:00 2001 From: Davide Scola Date: Thu, 5 Oct 2017 11:04:20 +0000 Subject: [PATCH] Initial import --- .gitignore | 43 +++++ .gitmodules | 3 + ChangeLog | 2 + Makefile.am | 50 ++++++ README.md | 126 ++++++++++++++- autogen.sh | 34 ++++ configure.ac | 212 +++++++++++++++++++++++++ ed25519 | 1 + include/Makefile.am | 22 +++ include/common.h | 40 +++++ include/encode.h | 41 +++++ include/io.h | 34 ++++ m4/Makefile.am | 54 +++++++ m4/ax_append_compile_flags.m4 | 67 ++++++++ m4/ax_append_flag.m4 | 71 +++++++++ m4/ax_append_link_flags.m4 | 65 ++++++++ m4/ax_c99_inline.m4 | 64 ++++++++ m4/ax_check_compile_flag.m4 | 74 +++++++++ m4/ax_check_enable_debug.m4 | 124 +++++++++++++++ m4/ax_check_link_flag.m4 | 74 +++++++++ m4/ax_check_x86_features.m4 | 77 +++++++++ m4/ax_compiler_flags.m4 | 158 +++++++++++++++++++ m4/ax_compiler_flags_cflags.m4 | 140 ++++++++++++++++ m4/ax_compiler_flags_cxxflags.m4 | 136 ++++++++++++++++ m4/ax_compiler_flags_gir.m4 | 60 +++++++ m4/ax_compiler_flags_ldflags.m4 | 92 +++++++++++ m4/ax_compiler_vendor.m4 | 87 ++++++++++ m4/ax_define_descriptor.m4 | 43 +++++ m4/ax_define_size.m4 | 43 +++++ m4/ax_gcc_archflag.m4 | 263 +++++++++++++++++++++++++++++++ m4/ax_gcc_func_attribute.m4 | 226 ++++++++++++++++++++++++++ m4/ax_gcc_x86_cpu_supports.m4 | 104 ++++++++++++ m4/ax_gcc_x86_cpuid.m4 | 89 +++++++++++ m4/ax_generate_changelog.m4 | 99 ++++++++++++ m4/ax_is_release.m4 | 80 ++++++++++ m4/ax_msg_bold.m4 | 29 ++++ m4/ax_require_defined.m4 | 37 +++++ m4/ax_require_prog.m4 | 81 ++++++++++ m4/ax_restore_flags.m4 | 52 ++++++ m4/ax_save_flags.m4 | 71 +++++++++ m4/ax_with_prog.m4 | 70 ++++++++ src/Makefile.am | 118 ++++++++++++++ src/encode.c | 109 +++++++++++++ src/grc-keygen.c | 104 ++++++++++++ src/grc-sign.c | 115 ++++++++++++++ src/grc-verify.c | 104 ++++++++++++ src/grenache-get.in | 178 +++++++++++++++++++++ src/grenache-keygen.in | 100 ++++++++++++ src/grenache-put.in | 245 ++++++++++++++++++++++++++++ src/io.c | 93 +++++++++++ tests/Makefile.am | 43 +++++ tests/sign-test-vector-1.sh.in | 29 ++++ tests/sign-test-vector-2.sh.in | 29 ++++ tests/verify-test-vector-1.sh.in | 28 ++++ tests/verify-test-vector-2.sh.in | 28 ++++ 55 files changed, 4559 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 ChangeLog create mode 100644 Makefile.am create mode 100755 autogen.sh create mode 100644 configure.ac create mode 160000 ed25519 create mode 100644 include/Makefile.am create mode 100644 include/common.h create mode 100644 include/encode.h create mode 100644 include/io.h create mode 100644 m4/Makefile.am create mode 100644 m4/ax_append_compile_flags.m4 create mode 100644 m4/ax_append_flag.m4 create mode 100644 m4/ax_append_link_flags.m4 create mode 100644 m4/ax_c99_inline.m4 create mode 100644 m4/ax_check_compile_flag.m4 create mode 100644 m4/ax_check_enable_debug.m4 create mode 100644 m4/ax_check_link_flag.m4 create mode 100644 m4/ax_check_x86_features.m4 create mode 100644 m4/ax_compiler_flags.m4 create mode 100644 m4/ax_compiler_flags_cflags.m4 create mode 100644 m4/ax_compiler_flags_cxxflags.m4 create mode 100644 m4/ax_compiler_flags_gir.m4 create mode 100644 m4/ax_compiler_flags_ldflags.m4 create mode 100644 m4/ax_compiler_vendor.m4 create mode 100644 m4/ax_define_descriptor.m4 create mode 100644 m4/ax_define_size.m4 create mode 100644 m4/ax_gcc_archflag.m4 create mode 100644 m4/ax_gcc_func_attribute.m4 create mode 100644 m4/ax_gcc_x86_cpu_supports.m4 create mode 100644 m4/ax_gcc_x86_cpuid.m4 create mode 100644 m4/ax_generate_changelog.m4 create mode 100644 m4/ax_is_release.m4 create mode 100644 m4/ax_msg_bold.m4 create mode 100644 m4/ax_require_defined.m4 create mode 100644 m4/ax_require_prog.m4 create mode 100644 m4/ax_restore_flags.m4 create mode 100644 m4/ax_save_flags.m4 create mode 100644 m4/ax_with_prog.m4 create mode 100644 src/Makefile.am create mode 100644 src/encode.c create mode 100644 src/grc-keygen.c create mode 100644 src/grc-sign.c create mode 100644 src/grc-verify.c create mode 100644 src/grenache-get.in create mode 100644 src/grenache-keygen.in create mode 100644 src/grenache-put.in create mode 100644 src/io.c create mode 100644 tests/Makefile.am create mode 100644 tests/sign-test-vector-1.sh.in create mode 100644 tests/sign-test-vector-2.sh.in create mode 100644 tests/verify-test-vector-1.sh.in create mode 100644 tests/verify-test-vector-2.sh.in diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a20b623 --- /dev/null +++ b/.gitignore @@ -0,0 +1,43 @@ +# +# Compile time +# +*.o +.deps/ +.libs/ +*.l[ao] + +# +# Tests +# +*-test-vector-*.sh + +# +# Autotools +# +lt*.m4 +shtool +stamp-h1 +libtool* +Makefile +config.h* +configure +build-aux/ +aclocal.m4 +config.log +Makefile.in +config.status + +# +# Generated binaries +# +grc-sign +grc-verify +grc-keygen +grenache-get +grenache-put +grenache-keygen + +# +# Distribution +# +*.tar.* diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..3b84183 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "ed25519"] + path = ed25519 + url = https://github.com/orlp/ed25519.git diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..92bcb9b --- /dev/null +++ b/ChangeLog @@ -0,0 +1,2 @@ +The ChangeLog is auto-generated when releasing. +If you are seeing this, use 'git log' for a detailed list of changes. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..9358875 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,50 @@ +############################################################################ +# This file is part of Grenache Command Line Interface. # +# # +# Copyright (C) 2017 Davide Scola # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # +# implied. See the License for the specific language governing permissions # +# and limitations under the License. # +############################################################################ + +ACLOCAL_AMFLAGS = -I m4 + +GRC_SUBDIRS = . src tests + +SUBDIRS = $(GRC_SUBDIRS) +DIST_SUBDIRS = $(GRC_SUBDIRS) include m4 + +@GENERATE_CHANGELOG_RULES@ + +EXTRA_DIST = \ +LICENSE \ +README.md \ +autogen.sh \ +shtool + +DISTCLEANFILES = \ +config.h.in~ + +MAINTAINERCLEANFILES = \ +$(DISTCLEANFILES) \ +README + +dist-hook: dist-ChangeLog + cp -fpR $(top_srcdir)/ed25519 $(distdir) + $(RM) -rf $(distdir)/ed25519/.git + +maintainer-clean-local: maintainer-clean-local-check + +maintainer-clean-local-check: + -$(RM) $(distdir).tar.xz + +.PHONY: maintainer-clean-local-check diff --git a/README.md b/README.md index 6ec13be..a9debce 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,124 @@ -# grenache-cli -The Grenache Command Line Interface. +# Grenache CLI + +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) + + * [Introduction](#introduction) + * [Prerequisites](#prerequisites) + * [Install](#install) + * [Initialize](#initialize) + * [Store items to the DHT](#store-items-to-the-dht) + * [Immutable items](#immutable-items) + * [Mutable items](#mutable-items) + * [Retreive items from the DHT](#retreive-items-from-the-dht) + * [Lookup peers](#lookup-peers) + * [Announce services](#announce-services) + * [Maintainers](#maintainers) + + +## Introduction + +The **Grenache** **C**ommand **L**ine **I**nterface is a set of tools to use the [grenache-grape](https://github.com/bitfinexcom/grenache-grape) suite directly from your command line. Using this set of tools you can create fancy scripts that communicate directly with the DHT. + + +## Prerequisites + +Be sure that your version of [grenache-grape](https://github.com/bitfinexcom/grenache-grape) supports the mutable items (see pull request [#35](https://github.com/bitfinexcom/grenache-grape/pull/35)). + + +## Install + +Briefly, the shell command + +```bash +./configure && make && make install +``` + +should configure, build and install this package. + + +## Initialize + +Before start using this set of tools you need to initialize the `granache-cli` environment; use: + +```bash +grenache-keygen +``` + +This will also generate your key pair that will be used when _mutable_ items are stored to the DHT. This is a one time only task but you can regenerate your key pair at any time if you want to. + + +## Store items to the DHT + +The `grenache-put` command writes an arbitrary payload to the DHT (see [BEP 44](http://bittorrent.org/beps/bep_0044.html) for more information). There are two types of items you can store to the DHT; the _immutable_ items and the _mutable_ ones. In any case, you will get the key under which the item has been stored. + +### Immutable items + +_Immutable_ items cannot be modified, thus there is no need to authenticate the origin of them. This makes _immutable_ items simple. To write an _immutable_ item to the DHT simply run something like this: + +```bash +grenache-put "$(uname -n)" +``` + +### Mutable items + +_Mutable_ items can be updated, without changing their DHT keys. In order to create your key pair, see `grenache-keygen`. To write a _mutable_ item to the DHT simply run something like this: + +```bash +grenache-put --mutable "$(uptime -p)" +``` + +In order to support a single key being used to store separate items in the DHT, an optional salt can be specified in the put request of _mutable_ items: + +```bash +grenache-put --mutable --salt 'sys:mem:available' "$(awk '/^MemAvailable:/ { print $2 "Ki" }' < /proc/meminfo)" +``` + +Note that `grenache-put` is agnostic and it will treat your payload as a **single string**. Other useful options are `-n` or `--number` that will let you set the _sequence number_ to use in your request and `-c` or `--cas` that let you use the _compare and swap_ feature. See + +```bash +grenache-put --help +``` + +to retrieve the complete options list. + + +## Retreive items from the DHT + +The `grenache-get` command reads a data record from the DHT (see [BEP 44](http://bittorrent.org/beps/bep_0044.html) for more information). There is no differences in retreiving a _mutable_ or an _immutable_ item; on both cases the key returned by the *PUT* request must be provided. In any case, `grenache-get` validates the payload it receive; this will ensure that the _key_ provided really match the payload and, in case of a _mutable_ item, that the signature is correct. This will protect you from evil nodes on the network. To read an item from the DHT simply run something like this: + +```bash +grenache-get '81c2a8157780989af9a16661324fafbd7803877d' +``` + +For example, you can format the previously stored available memory amount using something like this: + +```bash +numfmt --from=auto --to=iec-i < <( + grenache-get '81c2a8157780989af9a16661324fafbd7803877d' +) +``` + +You can also retrieve the raw packet received from the network using the `-r` switch or its long form `--raw`. See + +```bash +grenache-get --help +``` + +to retrieve the complete options list. + + +## Lookup peers + +Coming soon... + + +## Announce services + +Coming soon... + + +## Maintainers + +Current maintainers: + +* Davide Scola - davide@bitfinex.com diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..523584b --- /dev/null +++ b/autogen.sh @@ -0,0 +1,34 @@ +#!/bin/bash +############################################################################ +# This file is part of Grenache Command Line Interface. # +# # +# Copyright (C) 2017 Davide Scola # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # +# implied. See the License for the specific language governing permissions # +# and limitations under the License. # +############################################################################ + +case "${1}" in + '--reverse') + [[ -x configure ]] && ./configure --enable-maintainer-mode + [[ -f Makefile ]] && make maintainer-clean + rm -rf build-aux/ + rm -f {aclocal.m4,config.h.in,configure,shtool} + find . -type f -iregex '.*Makefile\.in$' -print0 | xargs -r0 rm -f + ;; + * ) + autoreconf --force --install --include 'm4' + [[ -x shtool ]] || shtoolize -q 'echo' + [[ -d autom4te.cache ]] && rm -rf autom4te.cache + ;; +esac + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..444ce75 --- /dev/null +++ b/configure.ac @@ -0,0 +1,212 @@ +dnl This file is part of Grenache Command Line Interface. +dnl +dnl Copyright (C) 2017 Davide Scola +dnl +dnl Licensed under the Apache License, Version 2.0 (the "License"); you may +dnl not use this file except in compliance with the License. You may obtain +dnl a copy of the License at +dnl +dnl http://www.apache.org/licenses/LICENSE-2.0 +dnl +dnl Unless required by applicable law or agreed to in writing, software +dnl distributed under the License is distributed on an "AS IS" BASIS, +dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +dnl implied. See the License for the specific language governing permissions +dnl and limitations under the License. + +AC_PREREQ(2.69) +AC_INIT([grenache-cli], [0.1.0], [davide@bitfinex.com]) + +AC_SUBST([VERSION], [0.1.0]) +AC_SUBST([SB], [`$srcdir/shtool echo -n -e %B`]) +AC_SUBST([EB], [`$srcdir/shtool echo -n -e %b`]) + +AC_COPYRIGHT([Copyright (c) 2017 Davide Scola, +This configure script may be copied, distributed and modified under the +terms of the Apache License 2.0 license; see LICENSE for more details.]) + +dnl -------------------------------------------------------------------- +dnl Basic configuration +dnl -------------------------------------------------------------------- +AX_MSG_BOLD([Configuring grenache-cli $VERSION]) + +AC_CONFIG_MACRO_DIRS([m4]) +AC_CONFIG_AUX_DIR([build-aux]) + +AC_CONFIG_SRCDIR([include/io.h]) +AC_CONFIG_HEADERS([config.h]) + +AC_CANONICAL_SYSTEM +AM_INIT_AUTOMAKE([foreign no-dist-gzip dist-xz]) + +AX_IS_RELEASE([git-directory]) +AX_CHECK_ENABLE_DEBUG +AM_MAINTAINER_MODE +AX_GENERATE_CHANGELOG + +dnl -------------------------------------------------------------------- +dnl Checks for programs. +dnl -------------------------------------------------------------------- +AX_MSG_BOLD([Checking for required programs]) + +LT_INIT +AC_PROG_CC +AC_PROG_CPP +AM_PROG_CC_C_O +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_MAKE_SET +AC_PROG_LIBTOOL +AC_PROG_AWK + +AX_PROG_JQ +AX_PROG_CAT +AX_PROG_XXD +AX_PROG_DATE +AX_PROG_CURL +AX_PROG_MKDIR +AX_PROG_GETOPT +AX_PROG_UUIDGEN +AX_PROG_SHA1SUM +AX_PROG_READLINK + +dnl -------------------------------------------------------------------- +dnl Checks for libraries. +dnl -------------------------------------------------------------------- +AX_MSG_BOLD([Checking for required libraries]) + +PKG_CHECK_MODULES([libbsd], [libbsd], [ + AX_SAVE_FLAGS([ac_cv_libbsd]) + + AX_APPEND_FLAG([${libbsd_LIBS}], [LIBS]) + AX_APPEND_FLAG([${libbsd_CFLAGS}], [CFLAGS]) + + AC_MSG_CHECKING([if libbsd can be linked correctly]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main() { return 0; }]])], [ + AC_MSG_RESULT(yes) + + AX_APPEND_FLAG([${libbsd_LIBS}], [LLDP_LDFLAGS]) + AX_APPEND_FLAG([${libbsd_CFLAGS}], [LLDP_CFLAGS]) + ], [ + AC_MSG_RESULT(no) + AX_RESTORE_FLAGS([ac_cv_libbsd]) + ]) +]) + +dnl -------------------------------------------------------------------- +dnl Checks for header files. +dnl -------------------------------------------------------------------- +AX_MSG_BOLD([Checking for required header files]) + +AC_HEADER_STDC +AC_CHECK_HEADERS([fcntl.h unistd.h bsd/string.h], [], [ + AC_MSG_ERROR([missing $ac_header vital header file]) +]) + +dnl -------------------------------------------------------------------- +dnl Checks for typedefs, structures, and compiler characteristics. +dnl -------------------------------------------------------------------- +AX_MSG_BOLD([Checking for compiler characteristics]) + +AC_C_CONST +AC_C_INLINE +AC_TYPE_SIZE_T +AC_TYPE_INT32_T +AC_TYPE_INT64_T +AC_TYPE_UINT32_T +AC_TYPE_UINT64_T +AX_C99_INLINE +AX_GCC_FUNC_ATTRIBUTE([always_inline]) +AX_COMPILER_FLAGS +AX_GCC_ARCHFLAG +AX_CHECK_X86_FEATURES + +dnl -------------------------------------------------------------------- +dnl Checks for library functions. +dnl -------------------------------------------------------------------- +AX_MSG_BOLD([Checking for required library functions]) + +AC_CHECK_FUNCS([explicit_bzero], [], [ + AC_MSG_ERROR([missing $ac_func vital function]) +]) + +dnl -------------------------------------------------------------------- +dnl Checks for user defined options. +dnl -------------------------------------------------------------------- +AX_MSG_BOLD([Checking user defined options]) + +AX_DEFINE_DESCRIPTOR([SKEY_FILENO], [secret key], [6]) +AX_DEFINE_DESCRIPTOR([PKEY_FILENO], [public key], [7]) +AX_DEFINE_DESCRIPTOR([SIGN_FILENO], [signature], [8]) +AX_DEFINE_SIZE([ED25519_SEED_SIZE], [ed25519 seed], [32]) +AX_DEFINE_SIZE([ED25519_SIGNATURE_SIZE], [ed25519 signature], [64]) +AX_DEFINE_SIZE([ED25519_PUBLIC_KEY_SIZE], [ed25519 public key], [32]) +AX_DEFINE_SIZE([ED25519_SECRET_KEY_SIZE], [ed25519 secret key], [64]) + +dnl -------------------------------------------------------------------- +dnl Output. +dnl -------------------------------------------------------------------- +AX_MSG_BOLD([Writing output files]) + +AC_CONFIG_FILES([ \ + Makefile \ + m4/Makefile \ + include/Makefile \ + src/Makefile \ + src/grenache-put \ + src/grenache-get \ + src/grenache-keygen \ + tests/Makefile \ + tests/sign-test-vector-1.sh \ + tests/sign-test-vector-2.sh \ + tests/verify-test-vector-1.sh \ + tests/verify-test-vector-2.sh \ +]) + +AC_OUTPUT + +dnl -------------------------------------------------------------------- +dnl Output the configuration summary +dnl -------------------------------------------------------------------- +AX_MSG_BOLD([grenache-cli $VERSION has been configured as follow]) +AX_MSG_OPTION([Configure finished: to build type], [make]) +AC_MSG_RESULT([==================================================]) +AC_MSG_RESULT + AX_MSG_OPTION([ Install prefix: ], [${prefix}]) +AC_MSG_RESULT +AC_MSG_RESULT + AX_MSG_OPTION([Functions :]) +AC_MSG_RESULT + AX_MSG_OPTION([ explicit_bzero .......... ], [${ac_cv_func_explicit_bzero}]) +AC_MSG_RESULT + AX_MSG_OPTION([Functionalities :]) +AC_MSG_RESULT + AX_MSG_OPTION([ Release ................. ], [${ax_is_release}]) + AX_MSG_OPTION([ Debug code .............. ], [${ax_enable_debug}]) + AX_MSG_OPTION([ Warnings ................ ], [${ax_enable_compile_warnings}]) + AX_MSG_OPTION([ Secret Key Descriptor ... ], [${SKEY_FILENO}]) + AX_MSG_OPTION([ Public Key Descriptor ... ], [${PKEY_FILENO}]) + AX_MSG_OPTION([ Signature Descriptor .... ], [${SIGN_FILENO}]) + AX_MSG_OPTION([ Ed25519 Seed Size ....... ], [${ED25519_SEED_SIZE} bytes]) + AX_MSG_OPTION([ Ed25519 Signature Size .. ], [${ED25519_SIGNATURE_SIZE} bytes]) + AX_MSG_OPTION([ Ed25519 Public Key Size . ], [${ED25519_PUBLIC_KEY_SIZE} bytes]) + AX_MSG_OPTION([ Ed25519 Secret Key Size . ], [${ED25519_SECRET_KEY_SIZE} bytes]) +AC_MSG_RESULT + AX_MSG_OPTION([Tools :]) +AC_MSG_RESULT + AX_MSG_OPTION([ jq ...................... ], [${JQ}]) + AX_MSG_OPTION([ cat ..................... ], [${CAT}]) + AX_MSG_OPTION([ xxd ..................... ], [${XXD}]) + AX_MSG_OPTION([ date .................... ], [${DATE}]) + AX_MSG_OPTION([ curl .................... ], [${CURL}]) + AX_MSG_OPTION([ mkdir ................... ], [${MKDIR}]) + AX_MSG_OPTION([ getopt .................. ], [${GETOPT}]) + AX_MSG_OPTION([ uuidgen ................. ], [${UUIDGEN}]) + AX_MSG_OPTION([ sha1sum ................. ], [${SHA1SUM}]) + AX_MSG_OPTION([ readlink ................ ], [${READLINK}]) +AC_MSG_RESULT +AC_MSG_RESULT([==================================================]) +AX_MSG_OPTION([The binary will be optimized using], [${ax_cv_gcc_archflag}]) +AX_MSG_OPTION([This version was configured for], [${target}]) +AC_MSG_RESULT diff --git a/ed25519 b/ed25519 new file mode 160000 index 0000000..7fa6712 --- /dev/null +++ b/ed25519 @@ -0,0 +1 @@ +Subproject commit 7fa6712ef5d581a6981ec2b08ee623314cd1d1c4 diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 0000000..22eca0b --- /dev/null +++ b/include/Makefile.am @@ -0,0 +1,22 @@ +############################################################################ +# This file is part of Grenache Command Line Interface. # +# # +# Copyright (C) 2017 Davide Scola # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # +# implied. See the License for the specific language governing permissions # +# and limitations under the License. # +############################################################################ + +noinst_HEADERS = \ +io.h \ +common.h \ +encode.h diff --git a/include/common.h b/include/common.h new file mode 100644 index 0000000..81e2692 --- /dev/null +++ b/include/common.h @@ -0,0 +1,40 @@ +/** + * @file + * This file is part of Grenache Command Line Interface. + * + * Copyright (C) 2017 Davide Scola + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +#ifndef _COMMON_H +#define _COMMON_H + + +#ifdef HAVE_C99_INLINE +# define INLINE inline +#else +# define INLINE static inline +#endif + +#ifdef HAVE_FUNC_ATTRIBUTE_ALWAYS_INLINE +# define ALWAYS_INLINE __attribute__ ((__always_inline__)) +#else +# define ALWAYS_INLINE +#endif + +#undef MAX +#define MAX(x,y) ((x) > (y) ? (x) : (y)) + + +#endif /* _COMMON_H */ diff --git a/include/encode.h b/include/encode.h new file mode 100644 index 0000000..95f0e9e --- /dev/null +++ b/include/encode.h @@ -0,0 +1,41 @@ +/** + * @file + * This file is part of Grenache Command Line Interface. + * + * Copyright (C) 2017 Davide Scola + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +#ifndef _ENCODE_H +#define _ENCODE_H + + +#undef ED25519_MAX_KEY_SIZE +#define ED25519_MAX_KEY_SIZE (MAX(ED25519_SECRET_KEY_SIZE,ED25519_PUBLIC_KEY_SIZE)) + +#undef ED25519_MAX_HEX_SIZE +#define ED25519_MAX_HEX_SIZE (MAX(ED25519_MAX_KEY_SIZE,ED25519_SIGNATURE_SIZE) << 1) + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + char * encode(const unsigned char *, size_t, char *); + unsigned char * decode(const char *, size_t, unsigned char *); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ENCODE_H */ diff --git a/include/io.h b/include/io.h new file mode 100644 index 0000000..1231c53 --- /dev/null +++ b/include/io.h @@ -0,0 +1,34 @@ +/** + * @file + * This file is part of Grenache Command Line Interface. + * + * Copyright (C) 2017 Davide Scola + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +#ifndef _IO_H +#define _IO_H + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + int ioread(int, char *, size_t); + int iowrite(int, char *, size_t); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _IO_H */ diff --git a/m4/Makefile.am b/m4/Makefile.am new file mode 100644 index 0000000..0b23b1c --- /dev/null +++ b/m4/Makefile.am @@ -0,0 +1,54 @@ +############################################################################ +# This file is part of Grenache Command Line Interface. # +# # +# Copyright (C) 2017 Davide Scola # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # +# implied. See the License for the specific language governing permissions # +# and limitations under the License. # +############################################################################ + +EXTRA_DIST = \ +ax_msg_bold.m4 \ +ax_require_prog.m4 \ +ax_define_size.m4 \ +ax_define_descriptor.m4 \ +ax_with_prog.m4 \ +ax_generate_changelog.m4 \ +ax_is_release.m4 \ +ax_check_enable_debug.m4 \ +ax_save_flags.m4 \ +ax_restore_flags.m4 \ +ax_require_defined.m4 \ +ax_append_flag.m4 \ +ax_c99_inline.m4 \ +ax_gcc_func_attribute.m4 \ +ax_compiler_flags_gir.m4 \ +ax_check_compile_flag.m4 \ +ax_check_link_flag.m4 \ +ax_append_compile_flags.m4 \ +ax_append_link_flags.m4 \ +ax_compiler_flags_cflags.m4 \ +ax_compiler_flags_cxxflags.m4 \ +ax_compiler_flags_ldflags.m4 \ +ax_compiler_flags.m4 \ +ax_gcc_x86_cpuid.m4 \ +ax_compiler_vendor.m4 \ +ax_gcc_archflag.m4 \ +ax_gcc_x86_cpu_supports.m4 \ +ax_check_x86_features.m4 + +MAINTAINERCLEANFILES = \ +libtool.m4 \ +lt~obsolete.m4 \ +ltoptions.m4 \ +ltsugar.m4 \ +ltversion.m4 diff --git a/m4/ax_append_compile_flags.m4 b/m4/ax_append_compile_flags.m4 new file mode 100644 index 0000000..5b6f1af --- /dev/null +++ b/m4/ax_append_compile_flags.m4 @@ -0,0 +1,67 @@ +# ============================================================================ +# https://www.gnu.org/software/autoconf-archive/ax_append_compile_flags.html +# ============================================================================ +# +# SYNOPSIS +# +# AX_APPEND_COMPILE_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# For every FLAG1, FLAG2 it is checked whether the compiler works with the +# flag. If it does, the flag is added FLAGS-VARIABLE +# +# If FLAGS-VARIABLE is not specified, the current language's flags (e.g. +# CFLAGS) is used. During the check the flag is always added to the +# current language's flags. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# +# NOTE: This macro depends on the AX_APPEND_FLAG and +# AX_CHECK_COMPILE_FLAG. Please keep this macro in sync with +# AX_APPEND_LINK_FLAGS. +# +# LICENSE +# +# Copyright (c) 2011 Maarten Bosmans +# +# 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 . +# +# 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 6 + +AC_DEFUN([AX_APPEND_COMPILE_FLAGS], +[AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG]) +AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) +for flag in $1; do + AX_CHECK_COMPILE_FLAG([$flag], [AX_APPEND_FLAG([$flag], [$2])], [], [$3], [$4]) +done +])dnl AX_APPEND_COMPILE_FLAGS diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4 new file mode 100644 index 0000000..e8c5312 --- /dev/null +++ b/m4/ax_append_flag.m4 @@ -0,0 +1,71 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_append_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE]) +# +# DESCRIPTION +# +# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space +# added in between. +# +# If FLAGS-VARIABLE is not specified, the current language's flags (e.g. +# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains +# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly +# FLAG. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# 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 . +# +# 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 7 + +AC_DEFUN([AX_APPEND_FLAG], +[dnl +AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF +AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])]) +AS_VAR_SET_IF(FLAGS,[ + AS_CASE([" AS_VAR_GET(FLAGS) "], + [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])], + [ + AS_VAR_APPEND(FLAGS,[" $1"]) + AC_RUN_LOG([: FLAGS="$FLAGS"]) + ]) + ], + [ + AS_VAR_SET(FLAGS,[$1]) + AC_RUN_LOG([: FLAGS="$FLAGS"]) + ]) +AS_VAR_POPDEF([FLAGS])dnl +])dnl AX_APPEND_FLAG diff --git a/m4/ax_append_link_flags.m4 b/m4/ax_append_link_flags.m4 new file mode 100644 index 0000000..6f7f174 --- /dev/null +++ b/m4/ax_append_link_flags.m4 @@ -0,0 +1,65 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_append_link_flags.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_APPEND_LINK_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# For every FLAG1, FLAG2 it is checked whether the linker works with the +# flag. If it does, the flag is added FLAGS-VARIABLE +# +# If FLAGS-VARIABLE is not specified, the linker's flags (LDFLAGS) is +# used. During the check the flag is always added to the linker's flags. +# +# If EXTRA-FLAGS is defined, it is added to the linker's default flags +# when the check is done. The check is thus made with the flags: "LDFLAGS +# EXTRA-FLAGS FLAG". This can for example be used to force the linker to +# issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# +# NOTE: This macro depends on the AX_APPEND_FLAG and AX_CHECK_LINK_FLAG. +# Please keep this macro in sync with AX_APPEND_COMPILE_FLAGS. +# +# LICENSE +# +# Copyright (c) 2011 Maarten Bosmans +# +# 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 . +# +# 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 6 + +AC_DEFUN([AX_APPEND_LINK_FLAGS], +[AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) +AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) +for flag in $1; do + AX_CHECK_LINK_FLAG([$flag], [AX_APPEND_FLAG([$flag], [m4_default([$2], [LDFLAGS])])], [], [$3], [$4]) +done +])dnl AX_APPEND_LINK_FLAGS diff --git a/m4/ax_c99_inline.m4 b/m4/ax_c99_inline.m4 new file mode 100644 index 0000000..6675e02 --- /dev/null +++ b/m4/ax_c99_inline.m4 @@ -0,0 +1,64 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_c99_inline.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_C99_INLINE +# +# DESCRIPTION +# +# This macro defines HAVE_C99_INLINE if the C compiler supports "inline" +# and "extern inline" correctly. An application may replace "inline" with +# "static inline" as a workaround for older compilers. +# +# LICENSE +# +# Copyright (c) 2009 Michael McMaster +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 8 + +AC_DEFUN([AX_C99_INLINE], [ + AC_MSG_CHECKING([whether the compiler supports C99 inline functions]) + AC_REQUIRE([AC_PROG_CC_C99]) + + AC_LANG_PUSH([C]) + + dnl In a conforming C99 implementation a function marked "inline" will not + dnl be compiled into the translation unit if the compiler was not able to + dnl inline the function. + dnl GCC versions before 4.3 would output the inline functions into all + dnl translation units that could require the definition. + AC_LINK_IFELSE( + AC_LANG_SOURCE([ + inline void* foo() { foo(); return &foo; } + int main() { return foo() != 0;} + ]), + + dnl the invalid source compiled, so the inline keyword does not work + dnl correctly. + AC_MSG_RESULT([no]), + + dnl Secondary test of valid source. + AC_LINK_IFELSE( + AC_LANG_SOURCE([ + extern inline void* foo() { foo(); return &foo; } + int main() { return foo() != 0;} + ]), + + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_C99_INLINE], [1], + [Define to 1 if the "extern" keyword controls whether an inline function appears in a translation unit.]), + + dnl Perhaps inline functions aren't supported at all ? + AC_MSG_RESULT([no]) + ) + ) + + AC_LANG_POP([C]) + ]); diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4 new file mode 100644 index 0000000..dcabb92 --- /dev/null +++ b/m4/ax_check_compile_flag.m4 @@ -0,0 +1,74 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's compiler +# or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# 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 . +# +# 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 5 + +AC_DEFUN([AX_CHECK_COMPILE_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ + ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_COMPILE_FLAGS diff --git a/m4/ax_check_enable_debug.m4 b/m4/ax_check_enable_debug.m4 new file mode 100644 index 0000000..d36bcdf --- /dev/null +++ b/m4/ax_check_enable_debug.m4 @@ -0,0 +1,124 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_enable_debug.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_ENABLE_DEBUG([enable by default=yes/info/profile/no], [ENABLE DEBUG VARIABLES ...], [DISABLE DEBUG VARIABLES NDEBUG ...], [IS-RELEASE]) +# +# DESCRIPTION +# +# Check for the presence of an --enable-debug option to configure, with +# the specified default value used when the option is not present. Return +# the value in the variable $ax_enable_debug. +# +# Specifying 'yes' adds '-g -O0' to the compilation flags for all +# languages. Specifying 'info' adds '-g' to the compilation flags. +# Specifying 'profile' adds '-g -pg' to the compilation flags and '-pg' to +# the linking flags. Otherwise, nothing is added. +# +# Define the variables listed in the second argument if debug is enabled, +# defaulting to no variables. Defines the variables listed in the third +# argument if debug is disabled, defaulting to NDEBUG. All lists of +# variables should be space-separated. +# +# If debug is not enabled, ensure AC_PROG_* will not add debugging flags. +# Should be invoked prior to any AC_PROG_* compiler checks. +# +# IS-RELEASE can be used to change the default to 'no' when making a +# release. Set IS-RELEASE to 'yes' or 'no' as appropriate. By default, it +# uses the value of $ax_is_release, so if you are using the AX_IS_RELEASE +# macro, there is no need to pass this parameter. +# +# AX_IS_RELEASE([git-directory]) +# AX_CHECK_ENABLE_DEBUG() +# +# LICENSE +# +# Copyright (c) 2011 Rhys Ulerich +# Copyright (c) 2014, 2015 Philip Withnall +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +#serial 8 + +AC_DEFUN([AX_CHECK_ENABLE_DEBUG],[ + AC_BEFORE([$0],[AC_PROG_CC])dnl + AC_BEFORE([$0],[AC_PROG_CXX])dnl + AC_BEFORE([$0],[AC_PROG_F77])dnl + AC_BEFORE([$0],[AC_PROG_FC])dnl + + AC_MSG_CHECKING(whether to enable debugging) + + ax_enable_debug_default=m4_tolower(m4_normalize(ifelse([$1],,[no],[$1]))) + ax_enable_debug_is_release=m4_tolower(m4_normalize(ifelse([$4],, + [$ax_is_release], + [$4]))) + + # If this is a release, override the default. + AS_IF([test "$ax_enable_debug_is_release" = "yes"], + [ax_enable_debug_default="no"]) + + m4_define(ax_enable_debug_vars,[m4_normalize(ifelse([$2],,,[$2]))]) + m4_define(ax_disable_debug_vars,[m4_normalize(ifelse([$3],,[NDEBUG],[$3]))]) + + AC_ARG_ENABLE(debug, + [AS_HELP_STRING([--enable-debug=]@<:@yes/info/profile/no@:>@,[compile with debugging])], + [],enable_debug=$ax_enable_debug_default) + + # empty mean debug yes + AS_IF([test "x$enable_debug" = "x"], + [enable_debug="yes"]) + + # case of debug + AS_CASE([$enable_debug], + [yes],[ + AC_MSG_RESULT(yes) + CFLAGS="${CFLAGS} -g -O0" + CXXFLAGS="${CXXFLAGS} -g -O0" + FFLAGS="${FFLAGS} -g -O0" + FCFLAGS="${FCFLAGS} -g -O0" + OBJCFLAGS="${OBJCFLAGS} -g -O0" + ], + [info],[ + AC_MSG_RESULT(info) + CFLAGS="${CFLAGS} -g" + CXXFLAGS="${CXXFLAGS} -g" + FFLAGS="${FFLAGS} -g" + FCFLAGS="${FCFLAGS} -g" + OBJCFLAGS="${OBJCFLAGS} -g" + ], + [profile],[ + AC_MSG_RESULT(profile) + CFLAGS="${CFLAGS} -g -pg" + CXXFLAGS="${CXXFLAGS} -g -pg" + FFLAGS="${FFLAGS} -g -pg" + FCFLAGS="${FCFLAGS} -g -pg" + OBJCFLAGS="${OBJCFLAGS} -g -pg" + LDFLAGS="${LDFLAGS} -pg" + ], + [ + AC_MSG_RESULT(no) + dnl Ensure AC_PROG_CC/CXX/F77/FC/OBJC will not enable debug flags + dnl by setting any unset environment flag variables + AS_IF([test "x${CFLAGS+set}" != "xset"], + [CFLAGS=""]) + AS_IF([test "x${CXXFLAGS+set}" != "xset"], + [CXXFLAGS=""]) + AS_IF([test "x${FFLAGS+set}" != "xset"], + [FFLAGS=""]) + AS_IF([test "x${FCFLAGS+set}" != "xset"], + [FCFLAGS=""]) + AS_IF([test "x${OBJCFLAGS+set}" != "xset"], + [OBJCFLAGS=""]) + ]) + + dnl Define various variables if debugging is disabled. + dnl assert.h is a NOP if NDEBUG is defined, so define it by default. + AS_IF([test "x$enable_debug" = "xyes"], + [m4_map_args_w(ax_enable_debug_vars, [AC_DEFINE(], [,,[Define if debugging is enabled])])], + [m4_map_args_w(ax_disable_debug_vars, [AC_DEFINE(], [,,[Define if debugging is disabled])])]) + ax_enable_debug=$enable_debug +]) diff --git a/m4/ax_check_link_flag.m4 b/m4/ax_check_link_flag.m4 new file mode 100644 index 0000000..819409a --- /dev/null +++ b/m4/ax_check_link_flag.m4 @@ -0,0 +1,74 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the linker or gives an error. +# (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the linker's default flags +# when the check is done. The check is thus made with the flags: "LDFLAGS +# EXTRA-FLAGS FLAG". This can for example be used to force the linker to +# issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_LINK_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# 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 . +# +# 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 5 + +AC_DEFUN([AX_CHECK_LINK_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl +AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ + ax_check_save_flags=$LDFLAGS + LDFLAGS="$LDFLAGS $4 $1" + AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + LDFLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_LINK_FLAGS diff --git a/m4/ax_check_x86_features.m4 b/m4/ax_check_x86_features.m4 new file mode 100644 index 0000000..87aa62b --- /dev/null +++ b/m4/ax_check_x86_features.m4 @@ -0,0 +1,77 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_x86_features.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_X86_FEATURES([ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) +# +# DESCRIPTION +# +# Checks if the host cpu supports various x86 instruction set, the +# instructions that will get tested are "mmx, popcnt, sse, sse2, sse3, +# sse4.1, sse4.2, sse4a, avx, avx2, avx512f, fma, fma4, bmi, bmi2". If the +# instruction set is supported by the host cpu, the C preprocessor macro +# HAVE_XXX_INSTRUCTIONS is set to 1. The XXX is up-cased instruction case +# with dot replaced by underscore. For example, the test for "sse4.2" +# would export HAVE_SSE4_2_INSTRUCTIONS=1. Also the compiler flag +# "-msse4.2" would be added to X86_FEATURE_CFLAGS variable, that can be +# obtained in Makefile.am using @X86_FEATURE_CFLAGS@. +# +# If any of the test for the instruction set were succeeded, the configure +# script would run ACTION-IF-FOUND if it is specified, or append +# X86_FEATURE_CFLAGS to CFLAGS. If none of the instruction were found, +# ACTION-IF-NOT-FOUND hook is triggered. +# +# This macro requires gcc extended builtin function "__builtin_cpu_init" +# and "__builtin_cpu_supports" to detect the cpu features. It will error +# out if the compiler doesn't has these builtins. +# +# See also AX_GCC_X86_CPU_SUPPORTS, which is the actual macro that perform +# the checks for the instruction sets. +# +# LICENSE +# +# Copyright (c) 2016 Felix Chern +# +# 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 2 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 . +# +# 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 2 + +AC_DEFUN([AX_CHECK_X86_FEATURES], + [m4_foreach_w( + [ax_x86_feature], + [mmx popcnt sse sse2 sse3 sse4.1 sse4.2 sse4a avx avx2 avx512f fma fma4 bmi bmi2], + [AX_GCC_X86_CPU_SUPPORTS(ax_x86_feature, + [X86_FEATURE_CFLAGS="$X86_FEATURE_CFLAGS -m[]ax_x86_feature"], + []) + ]) + AC_SUBST([X86_FEATURE_CFLAGS]) + m4_ifval([$1],[$1], + [CFLAGS="$CFLAGS $X86_FEATURE_CFLAGS"]) + $2 +]) diff --git a/m4/ax_compiler_flags.m4 b/m4/ax_compiler_flags.m4 new file mode 100644 index 0000000..ddb0456 --- /dev/null +++ b/m4/ax_compiler_flags.m4 @@ -0,0 +1,158 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_compiler_flags.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_COMPILER_FLAGS([CFLAGS-VARIABLE], [LDFLAGS-VARIABLE], [IS-RELEASE], [EXTRA-BASE-CFLAGS], [EXTRA-YES-CFLAGS], [UNUSED], [UNUSED], [UNUSED], [EXTRA-BASE-LDFLAGS], [EXTRA-YES-LDFLAGS], [UNUSED], [UNUSED], [UNUSED]) +# +# DESCRIPTION +# +# Check for the presence of an --enable-compile-warnings option to +# configure, defaulting to "error" in normal operation, or "yes" if +# IS-RELEASE is equal to "yes". Return the value in the variable +# $ax_enable_compile_warnings. +# +# Depending on the value of --enable-compile-warnings, different compiler +# warnings are checked to see if they work with the current compiler and, +# if so, are appended to CFLAGS-VARIABLE and LDFLAGS-VARIABLE. This +# allows a consistent set of baseline compiler warnings to be used across +# a code base, irrespective of any warnings enabled locally by individual +# developers. By standardising the warnings used by all developers of a +# project, the project can commit to a zero-warnings policy, using -Werror +# to prevent compilation if new warnings are introduced. This makes +# catching bugs which are flagged by warnings a lot easier. +# +# By providing a consistent --enable-compile-warnings argument across all +# projects using this macro, continuous integration systems can easily be +# configured the same for all projects. Automated systems or build +# systems aimed at beginners may want to pass the --disable-Werror +# argument to unconditionally prevent warnings being fatal. +# +# --enable-compile-warnings can take the values: +# +# * no: Base compiler warnings only; not even -Wall. +# * yes: The above, plus a broad range of useful warnings. +# * error: The above, plus -Werror so that all warnings are fatal. +# Use --disable-Werror to override this and disable fatal +# warnings. +# +# The set of base and enabled flags can be augmented using the +# EXTRA-*-CFLAGS and EXTRA-*-LDFLAGS variables, which are tested and +# appended to the output variable if --enable-compile-warnings is not +# "no". Flags should not be disabled using these arguments, as the entire +# point of AX_COMPILER_FLAGS is to enforce a consistent set of useful +# compiler warnings on code, using warnings which have been chosen for low +# false positive rates. If a compiler emits false positives for a +# warning, a #pragma should be used in the code to disable the warning +# locally. See: +# +# https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragmas +# +# The EXTRA-* variables should only be used to supply extra warning flags, +# and not general purpose compiler flags, as they are controlled by +# configure options such as --disable-Werror. +# +# IS-RELEASE can be used to disable -Werror when making a release, which +# is useful for those hairy moments when you just want to get the release +# done as quickly as possible. Set it to "yes" to disable -Werror. By +# default, it uses the value of $ax_is_release, so if you are using the +# AX_IS_RELEASE macro, there is no need to pass this parameter. For +# example: +# +# AX_IS_RELEASE([git-directory]) +# AX_COMPILER_FLAGS() +# +# CFLAGS-VARIABLE defaults to WARN_CFLAGS, and LDFLAGS-VARIABLE defaults +# to WARN_LDFLAGS. Both variables are AC_SUBST-ed by this macro, but must +# be manually added to the CFLAGS and LDFLAGS variables for each target in +# the code base. +# +# If C++ language support is enabled with AC_PROG_CXX, which must occur +# before this macro in configure.ac, warning flags for the C++ compiler +# are AC_SUBST-ed as WARN_CXXFLAGS, and must be manually added to the +# CXXFLAGS variables for each target in the code base. EXTRA-*-CFLAGS can +# be used to augment the base and enabled flags. +# +# Warning flags for g-ir-scanner (from GObject Introspection) are +# AC_SUBST-ed as WARN_SCANNERFLAGS. This variable must be manually added +# to the SCANNERFLAGS variable for each GIR target in the code base. If +# extra g-ir-scanner flags need to be enabled, the AX_COMPILER_FLAGS_GIR +# macro must be invoked manually. +# +# AX_COMPILER_FLAGS may add support for other tools in future, in addition +# to the compiler and linker. No extra EXTRA-* variables will be added +# for those tools, and all extra support will still use the single +# --enable-compile-warnings configure option. For finer grained control +# over the flags for individual tools, use AX_COMPILER_FLAGS_CFLAGS, +# AX_COMPILER_FLAGS_LDFLAGS and AX_COMPILER_FLAGS_* for new tools. +# +# The UNUSED variables date from a previous version of this macro, and are +# automatically appended to the preceding non-UNUSED variable. They should +# be left empty in new uses of the macro. +# +# LICENSE +# +# Copyright (c) 2014, 2015 Philip Withnall +# Copyright (c) 2015 David King +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 14 + +# _AX_COMPILER_FLAGS_LANG([LANGNAME]) +m4_defun([_AX_COMPILER_FLAGS_LANG], +[m4_ifdef([_AX_COMPILER_FLAGS_LANG_]$1[_enabled], [], + [m4_define([_AX_COMPILER_FLAGS_LANG_]$1[_enabled], [])dnl + AX_REQUIRE_DEFINED([AX_COMPILER_FLAGS_]$1[FLAGS])])dnl +]) + +AC_DEFUN([AX_COMPILER_FLAGS],[ + # C support is enabled by default. + _AX_COMPILER_FLAGS_LANG([C]) + # Only enable C++ support if AC_PROG_CXX is called. The redefinition of + # AC_PROG_CXX is so that a fatal error is emitted if this macro is called + # before AC_PROG_CXX, which would otherwise cause no C++ warnings to be + # checked. + AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AX_COMPILER_FLAGS_LANG([CXX])], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AX_COMPILER_FLAGS_LANG([CXX])])]) + AX_REQUIRE_DEFINED([AX_COMPILER_FLAGS_LDFLAGS]) + + # Default value for IS-RELEASE is $ax_is_release + ax_compiler_flags_is_release=m4_tolower(m4_normalize(ifelse([$3],, + [$ax_is_release], + [$3]))) + + AC_ARG_ENABLE([compile-warnings], + AS_HELP_STRING([--enable-compile-warnings=@<:@no/yes/error@:>@], + [Enable compiler warnings and errors]),, + [AS_IF([test "$ax_compiler_flags_is_release" = "yes"], + [enable_compile_warnings="yes"], + [enable_compile_warnings="error"])]) + AC_ARG_ENABLE([Werror], + AS_HELP_STRING([--disable-Werror], + [Unconditionally make all compiler warnings non-fatal]),, + [enable_Werror=maybe]) + + # Return the user's chosen warning level + AS_IF([test "$enable_Werror" = "no" -a \ + "$enable_compile_warnings" = "error"],[ + enable_compile_warnings="yes" + ]) + + ax_enable_compile_warnings=$enable_compile_warnings + + AX_COMPILER_FLAGS_CFLAGS([$1],[$ax_compiler_flags_is_release], + [$4],[$5 $6 $7 $8]) + m4_ifdef([_AX_COMPILER_FLAGS_LANG_CXX_enabled], + [AX_COMPILER_FLAGS_CXXFLAGS([WARN_CXXFLAGS], + [$ax_compiler_flags_is_release], + [$4],[$5 $6 $7 $8])]) + AX_COMPILER_FLAGS_LDFLAGS([$2],[$ax_compiler_flags_is_release], + [$9],[$10 $11 $12 $13]) + AX_COMPILER_FLAGS_GIR([WARN_SCANNERFLAGS],[$ax_compiler_flags_is_release]) +])dnl AX_COMPILER_FLAGS diff --git a/m4/ax_compiler_flags_cflags.m4 b/m4/ax_compiler_flags_cflags.m4 new file mode 100644 index 0000000..aeb16e3 --- /dev/null +++ b/m4/ax_compiler_flags_cflags.m4 @@ -0,0 +1,140 @@ +# ============================================================================= +# https://www.gnu.org/software/autoconf-archive/ax_compiler_flags_cflags.html +# ============================================================================= +# +# SYNOPSIS +# +# AX_COMPILER_FLAGS_CFLAGS([VARIABLE], [IS-RELEASE], [EXTRA-BASE-FLAGS], [EXTRA-YES-FLAGS]) +# +# DESCRIPTION +# +# Add warning flags for the C compiler to VARIABLE, which defaults to +# WARN_CFLAGS. VARIABLE is AC_SUBST-ed by this macro, but must be +# manually added to the CFLAGS variable for each target in the code base. +# +# This macro depends on the environment set up by AX_COMPILER_FLAGS. +# Specifically, it uses the value of $ax_enable_compile_warnings to decide +# which flags to enable. +# +# LICENSE +# +# Copyright (c) 2014, 2015 Philip Withnall +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 14 + +AC_DEFUN([AX_COMPILER_FLAGS_CFLAGS],[ + AC_REQUIRE([AC_PROG_SED]) + AX_REQUIRE_DEFINED([AX_APPEND_COMPILE_FLAGS]) + AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) + AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG]) + + # Variable names + m4_define([ax_warn_cflags_variable], + [m4_normalize(ifelse([$1],,[WARN_CFLAGS],[$1]))]) + + AC_LANG_PUSH([C]) + + # Always pass -Werror=unknown-warning-option to get Clang to fail on bad + # flags, otherwise they are always appended to the warn_cflags variable, and + # Clang warns on them for every compilation unit. + # If this is passed to GCC, it will explode, so the flag must be enabled + # conditionally. + AX_CHECK_COMPILE_FLAG([-Werror=unknown-warning-option],[ + ax_compiler_flags_test="-Werror=unknown-warning-option" + ],[ + ax_compiler_flags_test="" + ]) + + # Check that -Wno-suggest-attribute=format is supported + AX_CHECK_COMPILE_FLAG([-Wno-suggest-attribute=format],[ + ax_compiler_no_suggest_attribute_flags="-Wno-suggest-attribute=format" + ],[ + ax_compiler_no_suggest_attribute_flags="" + ]) + + # Base flags + AX_APPEND_COMPILE_FLAGS([ dnl + -fno-strict-aliasing dnl + $3 dnl + ],ax_warn_cflags_variable,[$ax_compiler_flags_test]) + + AS_IF([test "$ax_enable_compile_warnings" != "no"],[ + # "yes" flags + AX_APPEND_COMPILE_FLAGS([ dnl + -Wall dnl + -Wextra dnl + -Wundef dnl + -Wnested-externs dnl + -Wwrite-strings dnl + -Wpointer-arith dnl + -Wmissing-declarations dnl + -Wmissing-prototypes dnl + -Wstrict-prototypes dnl + -Wredundant-decls dnl + -Wno-unused-parameter dnl + -Wno-missing-field-initializers dnl + -Wdeclaration-after-statement dnl + -Wformat=2 dnl + -Wold-style-definition dnl + -Wcast-align dnl + -Wformat-nonliteral dnl + -Wformat-security dnl + -Wsign-compare dnl + -Wstrict-aliasing dnl + -Wshadow dnl + -Winline dnl + -Wpacked dnl + -Wmissing-format-attribute dnl + -Wmissing-noreturn dnl + -Winit-self dnl + -Wredundant-decls dnl + -Wmissing-include-dirs dnl + -Wunused-but-set-variable dnl + -Warray-bounds dnl + -Wimplicit-function-declaration dnl + -Wreturn-type dnl + -Wswitch-enum dnl + -Wswitch-default dnl + $4 dnl + $5 dnl + $6 dnl + $7 dnl + ],ax_warn_cflags_variable,[$ax_compiler_flags_test]) + ]) + AS_IF([test "$ax_enable_compile_warnings" = "error"],[ + # "error" flags; -Werror has to be appended unconditionally because + # it's not possible to test for + # + # suggest-attribute=format is disabled because it gives too many false + # positives + AX_APPEND_FLAG([-Werror],ax_warn_cflags_variable) + + AX_APPEND_COMPILE_FLAGS([ dnl + [$ax_compiler_no_suggest_attribute_flags] dnl + ],ax_warn_cflags_variable,[$ax_compiler_flags_test]) + ]) + + # In the flags below, when disabling specific flags, always add *both* + # -Wno-foo and -Wno-error=foo. This fixes the situation where (for example) + # we enable -Werror, disable a flag, and a build bot passes CFLAGS=-Wall, + # which effectively turns that flag back on again as an error. + for flag in $ax_warn_cflags_variable; do + AS_CASE([$flag], + [-Wno-*=*],[], + [-Wno-*],[ + AX_APPEND_COMPILE_FLAGS([-Wno-error=$(AS_ECHO([$flag]) | $SED 's/^-Wno-//')], + ax_warn_cflags_variable, + [$ax_compiler_flags_test]) + ]) + done + + AC_LANG_POP([C]) + + # Substitute the variables + AC_SUBST(ax_warn_cflags_variable) +])dnl AX_COMPILER_FLAGS diff --git a/m4/ax_compiler_flags_cxxflags.m4 b/m4/ax_compiler_flags_cxxflags.m4 new file mode 100644 index 0000000..3067d9b --- /dev/null +++ b/m4/ax_compiler_flags_cxxflags.m4 @@ -0,0 +1,136 @@ +# =============================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_compiler_flags_cxxflags.html +# =============================================================================== +# +# SYNOPSIS +# +# AX_COMPILER_FLAGS_CXXFLAGS([VARIABLE], [IS-RELEASE], [EXTRA-BASE-FLAGS], [EXTRA-YES-FLAGS]) +# +# DESCRIPTION +# +# Add warning flags for the C++ compiler to VARIABLE, which defaults to +# WARN_CXXFLAGS. VARIABLE is AC_SUBST-ed by this macro, but must be +# manually added to the CXXFLAGS variable for each target in the code +# base. +# +# This macro depends on the environment set up by AX_COMPILER_FLAGS. +# Specifically, it uses the value of $ax_enable_compile_warnings to decide +# which flags to enable. +# +# LICENSE +# +# Copyright (c) 2015 David King +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 10 + +AC_DEFUN([AX_COMPILER_FLAGS_CXXFLAGS],[ + AC_REQUIRE([AC_PROG_SED]) + AX_REQUIRE_DEFINED([AX_APPEND_COMPILE_FLAGS]) + AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) + AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG]) + + # Variable names + m4_define([ax_warn_cxxflags_variable], + [m4_normalize(ifelse([$1],,[WARN_CXXFLAGS],[$1]))]) + + AC_LANG_PUSH([C++]) + + # Always pass -Werror=unknown-warning-option to get Clang to fail on bad + # flags, otherwise they are always appended to the warn_cxxflags variable, + # and Clang warns on them for every compilation unit. + # If this is passed to GCC, it will explode, so the flag must be enabled + # conditionally. + AX_CHECK_COMPILE_FLAG([-Werror=unknown-warning-option],[ + ax_compiler_flags_test="-Werror=unknown-warning-option" + ],[ + ax_compiler_flags_test="" + ]) + + # Check that -Wno-suggest-attribute=format is supported + AX_CHECK_COMPILE_FLAG([-Wno-suggest-attribute=format],[ + ax_compiler_no_suggest_attribute_flags="-Wno-suggest-attribute=format" + ],[ + ax_compiler_no_suggest_attribute_flags="" + ]) + + # Base flags + AX_APPEND_COMPILE_FLAGS([ dnl + -fno-strict-aliasing dnl + $3 dnl + ],ax_warn_cxxflags_variable,[$ax_compiler_flags_test]) + + AS_IF([test "$ax_enable_compile_warnings" != "no"],[ + # "yes" flags + AX_APPEND_COMPILE_FLAGS([ dnl + -Wall dnl + -Wextra dnl + -Wundef dnl + -Wwrite-strings dnl + -Wpointer-arith dnl + -Wmissing-declarations dnl + -Wredundant-decls dnl + -Wno-unused-parameter dnl + -Wno-missing-field-initializers dnl + -Wformat=2 dnl + -Wcast-align dnl + -Wformat-nonliteral dnl + -Wformat-security dnl + -Wsign-compare dnl + -Wstrict-aliasing dnl + -Wshadow dnl + -Winline dnl + -Wpacked dnl + -Wmissing-format-attribute dnl + -Wmissing-noreturn dnl + -Winit-self dnl + -Wredundant-decls dnl + -Wmissing-include-dirs dnl + -Wunused-but-set-variable dnl + -Warray-bounds dnl + -Wreturn-type dnl + -Wno-overloaded-virtual dnl + -Wswitch-enum dnl + -Wswitch-default dnl + $4 dnl + $5 dnl + $6 dnl + $7 dnl + ],ax_warn_cxxflags_variable,[$ax_compiler_flags_test]) + ]) + AS_IF([test "$ax_enable_compile_warnings" = "error"],[ + # "error" flags; -Werror has to be appended unconditionally because + # it's not possible to test for + # + # suggest-attribute=format is disabled because it gives too many false + # positives + AX_APPEND_FLAG([-Werror],ax_warn_cxxflags_variable) + + AX_APPEND_COMPILE_FLAGS([ dnl + [$ax_compiler_no_suggest_attribute_flags] dnl + ],ax_warn_cxxflags_variable,[$ax_compiler_flags_test]) + ]) + + # In the flags below, when disabling specific flags, always add *both* + # -Wno-foo and -Wno-error=foo. This fixes the situation where (for example) + # we enable -Werror, disable a flag, and a build bot passes CXXFLAGS=-Wall, + # which effectively turns that flag back on again as an error. + for flag in $ax_warn_cxxflags_variable; do + AS_CASE([$flag], + [-Wno-*=*],[], + [-Wno-*],[ + AX_APPEND_COMPILE_FLAGS([-Wno-error=$(AS_ECHO([$flag]) | $SED 's/^-Wno-//')], + ax_warn_cxxflags_variable, + [$ax_compiler_flags_test]) + ]) + done + + AC_LANG_POP([C++]) + + # Substitute the variables + AC_SUBST(ax_warn_cxxflags_variable) +])dnl AX_COMPILER_FLAGS_CXXFLAGS diff --git a/m4/ax_compiler_flags_gir.m4 b/m4/ax_compiler_flags_gir.m4 new file mode 100644 index 0000000..5b4924a --- /dev/null +++ b/m4/ax_compiler_flags_gir.m4 @@ -0,0 +1,60 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_compiler_flags_gir.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_COMPILER_FLAGS_GIR([VARIABLE], [IS-RELEASE], [EXTRA-BASE-FLAGS], [EXTRA-YES-FLAGS]) +# +# DESCRIPTION +# +# Add warning flags for the g-ir-scanner (from GObject Introspection) to +# VARIABLE, which defaults to WARN_SCANNERFLAGS. VARIABLE is AC_SUBST-ed +# by this macro, but must be manually added to the SCANNERFLAGS variable +# for each GIR target in the code base. +# +# This macro depends on the environment set up by AX_COMPILER_FLAGS. +# Specifically, it uses the value of $ax_enable_compile_warnings to decide +# which flags to enable. +# +# LICENSE +# +# Copyright (c) 2015 Philip Withnall +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 6 + +AC_DEFUN([AX_COMPILER_FLAGS_GIR],[ + AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) + + # Variable names + m4_define([ax_warn_scannerflags_variable], + [m4_normalize(ifelse([$1],,[WARN_SCANNERFLAGS],[$1]))]) + + # Base flags + AX_APPEND_FLAG([$3],ax_warn_scannerflags_variable) + + AS_IF([test "$ax_enable_compile_warnings" != "no"],[ + # "yes" flags + AX_APPEND_FLAG([ dnl + --warn-all dnl + $4 dnl + $5 dnl + $6 dnl + $7 dnl + ],ax_warn_scannerflags_variable) + ]) + AS_IF([test "$ax_enable_compile_warnings" = "error"],[ + # "error" flags + AX_APPEND_FLAG([ dnl + --warn-error dnl + ],ax_warn_scannerflags_variable) + ]) + + # Substitute the variables + AC_SUBST(ax_warn_scannerflags_variable) +])dnl AX_COMPILER_FLAGS diff --git a/m4/ax_compiler_flags_ldflags.m4 b/m4/ax_compiler_flags_ldflags.m4 new file mode 100644 index 0000000..842e329 --- /dev/null +++ b/m4/ax_compiler_flags_ldflags.m4 @@ -0,0 +1,92 @@ +# ============================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_compiler_flags_ldflags.html +# ============================================================================== +# +# SYNOPSIS +# +# AX_COMPILER_FLAGS_LDFLAGS([VARIABLE], [IS-RELEASE], [EXTRA-BASE-FLAGS], [EXTRA-YES-FLAGS]) +# +# DESCRIPTION +# +# Add warning flags for the linker to VARIABLE, which defaults to +# WARN_LDFLAGS. VARIABLE is AC_SUBST-ed by this macro, but must be +# manually added to the LDFLAGS variable for each target in the code base. +# +# This macro depends on the environment set up by AX_COMPILER_FLAGS. +# Specifically, it uses the value of $ax_enable_compile_warnings to decide +# which flags to enable. +# +# LICENSE +# +# Copyright (c) 2014, 2015 Philip Withnall +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 8 + +AC_DEFUN([AX_COMPILER_FLAGS_LDFLAGS],[ + AX_REQUIRE_DEFINED([AX_APPEND_LINK_FLAGS]) + AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) + AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG]) + AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) + + # Variable names + m4_define([ax_warn_ldflags_variable], + [m4_normalize(ifelse([$1],,[WARN_LDFLAGS],[$1]))]) + + # Always pass -Werror=unknown-warning-option to get Clang to fail on bad + # flags, otherwise they are always appended to the warn_ldflags variable, + # and Clang warns on them for every compilation unit. + # If this is passed to GCC, it will explode, so the flag must be enabled + # conditionally. + AX_CHECK_COMPILE_FLAG([-Werror=unknown-warning-option],[ + ax_compiler_flags_test="-Werror=unknown-warning-option" + ],[ + ax_compiler_flags_test="" + ]) + + # macOS linker does not have --as-needed + AX_CHECK_LINK_FLAG([-Wl,--no-as-needed], [ + ax_compiler_flags_as_needed_option="-Wl,--no-as-needed" + ], [ + ax_compiler_flags_as_needed_option="" + ]) + + # macOS linker speaks with a different accent + ax_compiler_flags_fatal_warnings_option="" + AX_CHECK_LINK_FLAG([-Wl,--fatal-warnings], [ + ax_compiler_flags_fatal_warnings_option="-Wl,--fatal-warnings" + ]) + AX_CHECK_LINK_FLAG([-Wl,-fatal_warnings], [ + ax_compiler_flags_fatal_warnings_option="-Wl,-fatal_warnings" + ]) + + # Base flags + AX_APPEND_LINK_FLAGS([ dnl + $ax_compiler_flags_as_needed_option dnl + $3 dnl + ],ax_warn_ldflags_variable,[$ax_compiler_flags_test]) + + AS_IF([test "$ax_enable_compile_warnings" != "no"],[ + # "yes" flags + AX_APPEND_LINK_FLAGS([$4 $5 $6 $7], + ax_warn_ldflags_variable, + [$ax_compiler_flags_test]) + ]) + AS_IF([test "$ax_enable_compile_warnings" = "error"],[ + # "error" flags; -Werror has to be appended unconditionally because + # it's not possible to test for + # + # suggest-attribute=format is disabled because it gives too many false + # positives + AX_APPEND_LINK_FLAGS([ dnl + $ax_compiler_flags_fatal_warnings_option dnl + ],ax_warn_ldflags_variable,[$ax_compiler_flags_test]) + ]) + + # Substitute the variables + AC_SUBST(ax_warn_ldflags_variable) +])dnl AX_COMPILER_FLAGS diff --git a/m4/ax_compiler_vendor.m4 b/m4/ax_compiler_vendor.m4 new file mode 100644 index 0000000..4ca8089 --- /dev/null +++ b/m4/ax_compiler_vendor.m4 @@ -0,0 +1,87 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_compiler_vendor.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_COMPILER_VENDOR +# +# DESCRIPTION +# +# Determine the vendor of the C/C++ compiler, e.g., gnu, intel, ibm, sun, +# hp, borland, comeau, dec, cray, kai, lcc, metrowerks, sgi, microsoft, +# watcom, etc. The vendor is returned in the cache variable +# $ax_cv_c_compiler_vendor for C and $ax_cv_cxx_compiler_vendor for C++. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2008 Matteo Frigo +# +# 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 . +# +# 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 16 + +AC_DEFUN([AX_COMPILER_VENDOR], +[AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor, + dnl Please add if possible support to ax_compiler_version.m4 + [# note: don't check for gcc first since some other compilers define __GNUC__ + vendors="intel: __ICC,__ECC,__INTEL_COMPILER + ibm: __xlc__,__xlC__,__IBMC__,__IBMCPP__ + pathscale: __PATHCC__,__PATHSCALE__ + clang: __clang__ + cray: _CRAYC + fujitsu: __FUJITSU + gnu: __GNUC__ + sun: __SUNPRO_C,__SUNPRO_CC + hp: __HP_cc,__HP_aCC + dec: __DECC,__DECCXX,__DECC_VER,__DECCXX_VER + borland: __BORLANDC__,__CODEGEARC__,__TURBOC__ + comeau: __COMO__ + kai: __KCC + lcc: __LCC__ + sgi: __sgi,sgi + microsoft: _MSC_VER + metrowerks: __MWERKS__ + watcom: __WATCOMC__ + portland: __PGI + tcc: __TINYC__ + unknown: UNKNOWN" + for ventest in $vendors; do + case $ventest in + *:) vendor=$ventest; continue ;; + *) vencpp="defined("`echo $ventest | sed 's/,/) || defined(/g'`")" ;; + esac + AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[ + #if !($vencpp) + thisisanerror; + #endif + ])], [break]) + done + ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=`echo $vendor | cut -d: -f1` + ]) +]) diff --git a/m4/ax_define_descriptor.m4 b/m4/ax_define_descriptor.m4 new file mode 100644 index 0000000..15e3670 --- /dev/null +++ b/m4/ax_define_descriptor.m4 @@ -0,0 +1,43 @@ +dnl @synopsis AX_DEFINE_DESCRIPTOR([NAME], [DESCRIPTION], [DEFAULT-VALUE]) +dnl +dnl Macro to define a file descriptor; it must be a non-negative number and +dnl greater than 2. If a value greater than 1023 is given, a warning message +dnl will be issued that informs user about ulimits. +dnl +dnl Examples: +dnl AX_DEFINE_DESCRIPTOR([FOO_FILENO], [wonderful foo], [99]) +dnl +dnl @category Misc +dnl @author Davide Scola +dnl @version 2017-08-28 +dnl @license AllPermissive + +AC_DEFUN([AX_DEFINE_DESCRIPTOR], [ + AS_LITERAL_IF([$1], [], [AC_FATAL([$0: requires literal arguments])]) + AS_LITERAL_IF([$2], [], [AC_FATAL([$0: requires literal arguments])]) + AS_LITERAL_IF([$3], [], [AC_FATAL([$0: requires literal arguments])]) + + AC_ARG_WITH(m4_tolower($1), AC_HELP_STRING(m4_tolower(--with-$1), + [Set the $2 file descriptor @<:@default=$3@:>@]), + ac_cv_[]m4_tolower($1)="${withval:-yes}", ac_cv_[]m4_tolower($1)="$3") + + AC_MSG_CHECKING([whether you want to set the $2 file descriptor]) + + AS_IF([test "x${ac_cv_[]m4_tolower($1)[]}" = "x$3"], + [AC_MSG_RESULT([no])], [AC_MSG_RESULT([yes])]) + + echo "${ac_cv_[]m4_tolower($1)[]}" | grep ['[^0123456789]'] >/dev/null 2>&1 && + AC_MSG_ERROR([the $2 file descriptor must be a non negative integer]) + + AS_IF([test "$(( 10[#]${ac_cv_[]m4_tolower($1)[]} ))" -lt 3], + [AC_MSG_ERROR([the $2 file descriptor cannot be STDIN, STDOUT or STDERR.])]) + + AS_IF([test "$(( 10[#]${ac_cv_[]m4_tolower($1)[]} ))" -gt 1023], + [AC_MSG_WARN([the $2 file descriptor can be out of your available descriptors; check your ulimits.])]) + + AC_SUBST(m4_toupper($1), [$(( 10[#]${ac_cv_[]m4_tolower($1)[]} ))]) + + AH_TEMPLATE(m4_toupper($1), [Define the $2 file descriptor.]) + AC_DEFINE_UNQUOTED(m4_toupper($1), [($(( 10[#]${ac_cv_[]m4_tolower($1)[]} )))], [Define the $2 file descriptor.]) +])dnl AX_DEFINE_DESCRIPTOR + diff --git a/m4/ax_define_size.m4 b/m4/ax_define_size.m4 new file mode 100644 index 0000000..fefeb1b --- /dev/null +++ b/m4/ax_define_size.m4 @@ -0,0 +1,43 @@ +dnl @synopsis AX_DEFINE_SIZE([NAME], [DESCRIPTION], [DEFAULT-VALUE]) +dnl +dnl Macro to define a buffer size; it must be a non-negative number and a +dnl power of 2. If a value below 16 or higher than 512 is given, an error +dnl message will be displayed. +dnl +dnl Examples: +dnl AX_DEFINE_SIZE([FOO_SIZE], [foo], [1024]) +dnl +dnl @category Misc +dnl @author Davide Scola +dnl @version 2017-08-28 +dnl @license AllPermissive + +AC_DEFUN([AX_DEFINE_SIZE], [ + AS_LITERAL_IF([$1], [], [AC_FATAL([$0: requires literal arguments])]) + AS_LITERAL_IF([$2], [], [AC_FATAL([$0: requires literal arguments])]) + AS_LITERAL_IF([$3], [], [AC_FATAL([$0: requires literal arguments])]) + + AC_ARG_WITH(m4_tolower($1), AC_HELP_STRING(m4_tolower(--with-$1), + [Set the $2 size in bytes @<:@default=$3@:>@]), + ac_cv_[]m4_tolower($1)="${withval:-yes}", ac_cv_[]m4_tolower($1)="$3") + + AC_MSG_CHECKING([whether you want to set the $2 size in bytes]) + + AS_IF([test "x${ac_cv_[]m4_tolower($1)[]}" = "x$3"], + [AC_MSG_RESULT([no])], [AC_MSG_RESULT([yes])]) + + echo "${ac_cv_[]m4_tolower($1)[]}" | grep ['[^0123456789]'] >/dev/null 2>&1 && + AC_MSG_ERROR([the $2 size in bytes must be a non negative integer]) + + AS_IF([test "$(( 10[#]${ac_cv_[]m4_tolower($1)[]} & -10[#]${ac_cv_[]m4_tolower($1)[]} ))" -ne "$(( 10[#]${ac_cv_[]m4_tolower($1)[]} ))"], + [AC_MSG_ERROR([the $2 size in bytes must be a power of two])]) + + AS_IF([test "$(( 10[#]${ac_cv_[]m4_tolower($1)[]} ))" -lt 16 -o "$(( 10[#]${ac_cv_[]m4_tolower($1)[]} ))" -gt 512], + [AC_MSG_ERROR([the $2 size in bytes out of a reasonable range])]) + + AC_SUBST(m4_toupper($1), [$(( 10[#]${ac_cv_[]m4_tolower($1)[]} ))]) + + AH_TEMPLATE(m4_toupper($1), [Define the $2 size in bytes.]) + AC_DEFINE_UNQUOTED(m4_toupper($1), [($(( 10[#]${ac_cv_[]m4_tolower($1)[]} ))UL)], [Define the $2 size in bytes.]) +])dnl AX_DEFINE_SIZE + diff --git a/m4/ax_gcc_archflag.m4 b/m4/ax_gcc_archflag.m4 new file mode 100644 index 0000000..d4a37f8 --- /dev/null +++ b/m4/ax_gcc_archflag.m4 @@ -0,0 +1,263 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_gcc_archflag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_GCC_ARCHFLAG([PORTABLE?], [ACTION-SUCCESS], [ACTION-FAILURE]) +# +# DESCRIPTION +# +# This macro tries to guess the "native" arch corresponding to the target +# architecture for use with gcc's -march=arch or -mtune=arch flags. If +# found, the cache variable $ax_cv_gcc_archflag is set to this flag and +# ACTION-SUCCESS is executed; otherwise $ax_cv_gcc_archflag is set to +# "unknown" and ACTION-FAILURE is executed. The default ACTION-SUCCESS is +# to add $ax_cv_gcc_archflag to the end of $CFLAGS. +# +# PORTABLE? should be either [yes] (default) or [no]. In the former case, +# the flag is set to -mtune (or equivalent) so that the architecture is +# only used for tuning, but the instruction set used is still portable. In +# the latter case, the flag is set to -march (or equivalent) so that +# architecture-specific instructions are enabled. +# +# The user can specify --with-gcc-arch= in order to override the +# macro's choice of architecture, or --without-gcc-arch to disable this. +# +# When cross-compiling, or if $CC is not gcc, then ACTION-FAILURE is +# called unless the user specified --with-gcc-arch manually. +# +# Requires macros: AX_CHECK_COMPILE_FLAG, AX_GCC_X86_CPUID +# +# (The main emphasis here is on recent CPUs, on the principle that doing +# high-performance computing on old hardware is uncommon.) +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2008 Matteo Frigo +# Copyright (c) 2014 Tsukasa Oi +# Copyright (c) 2017 Alexey Kopytov +# +# 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 . +# +# 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 20 + +AC_DEFUN([AX_GCC_ARCHFLAG], +[AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_SED]) +AC_REQUIRE([AX_COMPILER_VENDOR]) + +AC_ARG_WITH(gcc-arch, [AS_HELP_STRING([--with-gcc-arch=], [use architecture for gcc -march/-mtune, instead of guessing])], + ax_gcc_arch=$withval, ax_gcc_arch=yes) + +AC_MSG_CHECKING([for gcc architecture flag]) +AC_MSG_RESULT([]) +AC_CACHE_VAL(ax_cv_gcc_archflag, +[ +ax_cv_gcc_archflag="unknown" + +if test "$GCC" = yes; then + +if test "x$ax_gcc_arch" = xyes; then +ax_gcc_arch="" +if test "$cross_compiling" = no; then +case $host_cpu in + i[[3456]]86*|x86_64*|amd64*) # use cpuid codes + AX_GCC_X86_CPUID(0) + AX_GCC_X86_CPUID(1) + case $ax_cv_gcc_x86_cpuid_0 in + *:756e6547:6c65746e:49656e69) # Intel + case $ax_cv_gcc_x86_cpuid_1 in + *5[[4578]]?:*:*:*) ax_gcc_arch="pentium-mmx pentium" ;; + *5[[123]]?:*:*:*) ax_gcc_arch=pentium ;; + *0?61?:*:*:*|?61?:*:*:*|61?:*:*:*) ax_gcc_arch=pentiumpro ;; + *0?6[[356]]?:*:*:*|?6[[356]]?:*:*:*|6[[356]]?:*:*:*) ax_gcc_arch="pentium2 pentiumpro" ;; + *0?6[[78ab]]?:*:*:*|?6[[78ab]]?:*:*:*|6[[78ab]]?:*:*:*) ax_gcc_arch="pentium3 pentiumpro" ;; + *0?6[[9d]]?:*:*:*|?6[[9d]]?:*:*:*|6[[9d]]?:*:*:*|*1?65?:*:*:*) ax_gcc_arch="pentium-m pentium3 pentiumpro" ;; + *0?6e?:*:*:*|?6e?:*:*:*|6e?:*:*:*) ax_gcc_arch="yonah pentium-m pentium3 pentiumpro" ;; + *0?6f?:*:*:*|?6f?:*:*:*|6f?:*:*:*|*1?66?:*:*:*) ax_gcc_arch="core2 pentium-m pentium3 pentiumpro" ;; + *1?6[[7d]]?:*:*:*) ax_gcc_arch="penryn core2 pentium-m pentium3 pentiumpro" ;; + *1?6[[aef]]?:*:*:*|*2?6e?:*:*:*) ax_gcc_arch="nehalem corei7 core2 pentium-m pentium3 pentiumpro" ;; + *2?6[[5cf]]?:*:*:*) ax_gcc_arch="westmere corei7 core2 pentium-m pentium3 pentiumpro" ;; + *2?6[[ad]]?:*:*:*) ax_gcc_arch="sandybridge corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; + *3?6[[ae]]?:*:*:*) ax_gcc_arch="ivybridge core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; + *3?6[[cf]]?:*:*:*|*4?6[[56]]?:*:*:*) ax_gcc_arch="haswell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; + *3?6d?:*:*:*) ax_gcc_arch="broadwell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; + *1?6c?:*:*:*|*2?6[[67]]?:*:*:*|*3?6[[56]]?:*:*:*) ax_gcc_arch="bonnell atom core2 pentium-m pentium3 pentiumpro" ;; + *3?67?:*:*:*|*[[45]]?6[[ad]]?:*:*:*) ax_gcc_arch="silvermont atom core2 pentium-m pentium3 pentiumpro" ;; + *000?f[[012]]?:*:*:*|?f[[012]]?:*:*:*|f[[012]]?:*:*:*) ax_gcc_arch="pentium4 pentiumpro" ;; + *000?f[[346]]?:*:*:*|?f[[346]]?:*:*:*|f[[346]]?:*:*:*) ax_gcc_arch="nocona prescott pentium4 pentiumpro" ;; + # fallback + *5??:*:*:*) ax_gcc_arch=pentium ;; + *??6??:*:*:*) ax_gcc_arch="core2 pentiumpro" ;; + *6??:*:*:*) ax_gcc_arch=pentiumpro ;; + *00??f??:*:*:*|??f??:*:*:*|?f??:*:*:*|f??:*:*:*) ax_gcc_arch="pentium4 pentiumpro" ;; + esac ;; + *:68747541:444d4163:69746e65) # AMD + case $ax_cv_gcc_x86_cpuid_1 in + *5[[67]]?:*:*:*) ax_gcc_arch=k6 ;; + *5[[8]]?:*:*:*) ax_gcc_arch="k6-2 k6" ;; + *5[[9d]]?:*:*:*) ax_gcc_arch="k6-3 k6" ;; + *6[[12]]?:*:*:*) ax_gcc_arch="athlon k7" ;; + *6[[34]]?:*:*:*) ax_gcc_arch="athlon-tbird k7" ;; + *6[[678a]]?:*:*:*) ax_gcc_arch="athlon-xp athlon-4 athlon k7" ;; + *000?f[[4578bcef]]?:*:*:*|?f[[4578bcef]]?:*:*:*|f[[4578bcef]]?:*:*:*|*001?f[[4578bcf]]?:*:*:*|1?f[[4578bcf]]?:*:*:*) ax_gcc_arch="athlon64 k8" ;; + *002?f[[13457bcf]]?:*:*:*|2?f[[13457bcf]]?:*:*:*|*004?f[[138bcf]]?:*:*:*|4?f[[138bcf]]?:*:*:*|*005?f[[df]]?:*:*:*|5?f[[df]]?:*:*:*|*006?f[[8bcf]]?:*:*:*|6?f[[8bcf]]?:*:*:*|*007?f[[cf]]?:*:*:*|7?f[[cf]]?:*:*:*|*00c?f1?:*:*:*|c?f1?:*:*:*|*020?f3?:*:*:*|20?f3?:*:*:*) ax_gcc_arch="athlon64-sse3 k8-sse3 athlon64 k8" ;; + *010?f[[245689a]]?:*:*:*|10?f[[245689a]]?:*:*:*|*030?f1?:*:*:*|30?f1?:*:*:*) ax_gcc_arch="barcelona amdfam10 k8" ;; + *050?f[[12]]?:*:*:*|50?f[[12]]?:*:*:*) ax_gcc_arch="btver1 amdfam10 k8" ;; + *060?f1?:*:*:*|60?f1?:*:*:*) ax_gcc_arch="bdver1 amdfam10 k8" ;; + *060?f2?:*:*:*|60?f2?:*:*:*|*061?f[[03]]?:*:*:*|61?f[[03]]?:*:*:*) ax_gcc_arch="bdver2 bdver1 amdfam10 k8" ;; + *063?f0?:*:*:*|63?f0?:*:*:*) ax_gcc_arch="bdver3 bdver2 bdver1 amdfam10 k8" ;; + *07[[03]]?f0?:*:*:*|7[[03]]?f0?:*:*:*) ax_gcc_arch="btver2 btver1 amdfam10 k8" ;; + # fallback + *0[[13]]??f??:*:*:*|[[13]]??f??:*:*:*) ax_gcc_arch="barcelona amdfam10 k8" ;; + *020?f??:*:*:*|20?f??:*:*:*) ax_gcc_arch="athlon64-sse3 k8-sse3 athlon64 k8" ;; + *05??f??:*:*:*|5??f??:*:*:*) ax_gcc_arch="btver1 amdfam10 k8" ;; + *060?f??:*:*:*|60?f??:*:*:*) ax_gcc_arch="bdver1 amdfam10 k8" ;; + *061?f??:*:*:*|61?f??:*:*:*) ax_gcc_arch="bdver2 bdver1 amdfam10 k8" ;; + *06??f??:*:*:*|6??f??:*:*:*) ax_gcc_arch="bdver3 bdver2 bdver1 amdfam10 k8" ;; + *070?f??:*:*:*|70?f??:*:*:*) ax_gcc_arch="btver2 btver1 amdfam10 k8" ;; + *???f??:*:*:*) ax_gcc_arch="amdfam10 k8" ;; + esac ;; + *:746e6543:736c7561:48727561) # IDT / VIA (Centaur) + case $ax_cv_gcc_x86_cpuid_1 in + *54?:*:*:*) ax_gcc_arch=winchip-c6 ;; + *5[[89]]?:*:*:*) ax_gcc_arch=winchip2 ;; + *66?:*:*:*) ax_gcc_arch=winchip2 ;; + *6[[78]]?:*:*:*) ax_gcc_arch=c3 ;; + *6[[9adf]]?:*:*:*) ax_gcc_arch="c3-2 c3" ;; + esac ;; + esac + if test x"$ax_gcc_arch" = x; then # fallback + case $host_cpu in + i586*) ax_gcc_arch=pentium ;; + i686*) ax_gcc_arch=pentiumpro ;; + esac + fi + ;; + + sparc*) + AC_PATH_PROG([PRTDIAG], [prtdiag], [prtdiag], [$PATH:/usr/platform/`uname -i`/sbin/:/usr/platform/`uname -m`/sbin/]) + cputype=`(((grep cpu /proc/cpuinfo | cut -d: -f2) ; ($PRTDIAG -v |grep -i sparc) ; grep -i cpu /var/run/dmesg.boot ) | head -n 1) 2> /dev/null` + cputype=`echo "$cputype" | tr -d ' -' | $SED 's/SPARCIIi/SPARCII/' |tr $as_cr_LETTERS $as_cr_letters` + case $cputype in + *ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;; + *ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;; + *ultrasparc*) ax_gcc_arch="ultrasparc v9" ;; + *supersparc*|*tms390z5[[05]]*) ax_gcc_arch="supersparc v8" ;; + *hypersparc*|*rt62[[056]]*) ax_gcc_arch="hypersparc v8" ;; + *cypress*) ax_gcc_arch=cypress ;; + esac ;; + + alphaev5) ax_gcc_arch=ev5 ;; + alphaev56) ax_gcc_arch=ev56 ;; + alphapca56) ax_gcc_arch="pca56 ev56" ;; + alphapca57) ax_gcc_arch="pca57 pca56 ev56" ;; + alphaev6) ax_gcc_arch=ev6 ;; + alphaev67) ax_gcc_arch=ev67 ;; + alphaev68) ax_gcc_arch="ev68 ev67" ;; + alphaev69) ax_gcc_arch="ev69 ev68 ev67" ;; + alphaev7) ax_gcc_arch="ev7 ev69 ev68 ev67" ;; + alphaev79) ax_gcc_arch="ev79 ev7 ev69 ev68 ev67" ;; + + powerpc*) + cputype=`((grep cpu /proc/cpuinfo | head -n 1 | cut -d: -f2 | cut -d, -f1 | $SED 's/ //g') ; /usr/bin/machine ; /bin/machine; grep CPU /var/run/dmesg.boot | head -n 1 | cut -d" " -f2) 2> /dev/null` + cputype=`echo $cputype | $SED -e 's/ppc//g;s/ *//g'` + case $cputype in + *750*) ax_gcc_arch="750 G3" ;; + *740[[0-9]]*) ax_gcc_arch="$cputype 7400 G4" ;; + *74[[4-5]][[0-9]]*) ax_gcc_arch="$cputype 7450 G4" ;; + *74[[0-9]][[0-9]]*) ax_gcc_arch="$cputype G4" ;; + *970*) ax_gcc_arch="970 G5 power4";; + *POWER4*|*power4*|*gq*) ax_gcc_arch="power4 970";; + *POWER5*|*power5*|*gr*|*gs*) ax_gcc_arch="power5 power4 970";; + 603ev|8240) ax_gcc_arch="$cputype 603e 603";; + *) ax_gcc_arch=$cputype ;; + esac + ax_gcc_arch="$ax_gcc_arch powerpc" + ;; + aarch64) + cpuimpl=`grep 'CPU implementer' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1` + cpuarch=`grep 'CPU architecture' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1` + cpuvar=`grep 'CPU variant' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1` + case $cpuimpl in + 0x42) case $cpuarch in + 8) case $cpuvar in + 0x0) ax_gcc_arch="thunderx2t99 vulcan armv8.1-a armv8-a+lse armv8-a native" ;; + esac + ;; + esac + ;; + 0x43) case $cpuarch in + 8) case $cpuvar in + 0x0) ax_gcc_arch="thunderx armv8-a native" ;; + 0x1) ax_gcc_arch="thunderx+lse armv8.1-a armv8-a+lse armv8-a native" ;; + esac + ;; + esac + ;; + esac + ;; +esac +fi # not cross-compiling +fi # guess arch + +if test "x$ax_gcc_arch" != x -a "x$ax_gcc_arch" != xno; then +if test "x[]m4_default([$1],yes)" = xyes; then # if we require portable code + flag_prefixes="-mtune=" + if test "x$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor" = xclang; then flag_prefixes="-march="; fi + # -mcpu=$arch and m$arch generate nonportable code on every arch except + # x86. And some other arches (e.g. Alpha) don't accept -mtune. Grrr. + case $host_cpu in i*86|x86_64*|amd64*) flag_prefixes="$flag_prefixes -mcpu= -m";; esac +else + flag_prefixes="-march= -mcpu= -m" +fi +for flag_prefix in $flag_prefixes; do + for arch in $ax_gcc_arch; do + flag="$flag_prefix$arch" + AX_CHECK_COMPILE_FLAG($flag, [if test "x$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor" = xclang; then + if test "x[]m4_default([$1],yes)" = xyes; then + if test "x$flag" = "x-march=$arch"; then flag=-mtune=$arch; fi + fi + fi; ax_cv_gcc_archflag=$flag; break]) + done + test "x$ax_cv_gcc_archflag" = xunknown || break +done +fi + +fi # $GCC=yes +]) +AC_MSG_CHECKING([for gcc architecture flag]) +AC_MSG_RESULT($ax_cv_gcc_archflag) +if test "x$ax_cv_gcc_archflag" = xunknown; then + m4_default([$3],:) +else + m4_default([$2], [CFLAGS="$CFLAGS $ax_cv_gcc_archflag"]) +fi +]) diff --git a/m4/ax_gcc_func_attribute.m4 b/m4/ax_gcc_func_attribute.m4 new file mode 100644 index 0000000..077962f --- /dev/null +++ b/m4/ax_gcc_func_attribute.m4 @@ -0,0 +1,226 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_gcc_func_attribute.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_GCC_FUNC_ATTRIBUTE(ATTRIBUTE) +# +# DESCRIPTION +# +# This macro checks if the compiler supports one of GCC's function +# attributes; many other compilers also provide function attributes with +# the same syntax. Compiler warnings are used to detect supported +# attributes as unsupported ones are ignored by default so quieting +# warnings when using this macro will yield false positives. +# +# The ATTRIBUTE parameter holds the name of the attribute to be checked. +# +# If ATTRIBUTE is supported define HAVE_FUNC_ATTRIBUTE_. +# +# The macro caches its result in the ax_cv_have_func_attribute_ +# variable. +# +# The macro currently supports the following function attributes: +# +# alias +# aligned +# alloc_size +# always_inline +# artificial +# cold +# const +# constructor +# constructor_priority for constructor attribute with priority +# deprecated +# destructor +# dllexport +# dllimport +# error +# externally_visible +# flatten +# format +# format_arg +# gnu_inline +# hot +# ifunc +# leaf +# malloc +# noclone +# noinline +# nonnull +# noreturn +# nothrow +# optimize +# pure +# unused +# used +# visibility +# warning +# warn_unused_result +# weak +# weakref +# +# Unsupported function attributes will be tested with a prototype +# returning an int and not accepting any arguments and the result of the +# check might be wrong or meaningless so use with care. +# +# LICENSE +# +# Copyright (c) 2013 Gabriele Svelto +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 7 + +AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [ + AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1]) + + AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([ + m4_case([$1], + [alias], [ + int foo( void ) { return 0; } + int bar( void ) __attribute__(($1("foo"))); + ], + [aligned], [ + int foo( void ) __attribute__(($1(32))); + ], + [alloc_size], [ + void *foo(int a) __attribute__(($1(1))); + ], + [always_inline], [ + inline __attribute__(($1)) int foo( void ) { return 0; } + ], + [artificial], [ + inline __attribute__(($1)) int foo( void ) { return 0; } + ], + [cold], [ + int foo( void ) __attribute__(($1)); + ], + [const], [ + int foo( void ) __attribute__(($1)); + ], + [constructor_priority], [ + int foo( void ) __attribute__((__constructor__(65535/2))); + ], + [constructor], [ + int foo( void ) __attribute__(($1)); + ], + [deprecated], [ + int foo( void ) __attribute__(($1(""))); + ], + [destructor], [ + int foo( void ) __attribute__(($1)); + ], + [dllexport], [ + __attribute__(($1)) int foo( void ) { return 0; } + ], + [dllimport], [ + int foo( void ) __attribute__(($1)); + ], + [error], [ + int foo( void ) __attribute__(($1(""))); + ], + [externally_visible], [ + int foo( void ) __attribute__(($1)); + ], + [flatten], [ + int foo( void ) __attribute__(($1)); + ], + [format], [ + int foo(const char *p, ...) __attribute__(($1(printf, 1, 2))); + ], + [format_arg], [ + char *foo(const char *p) __attribute__(($1(1))); + ], + [gnu_inline], [ + inline __attribute__(($1)) int foo( void ) { return 0; } + ], + [hot], [ + int foo( void ) __attribute__(($1)); + ], + [ifunc], [ + int my_foo( void ) { return 0; } + static int (*resolve_foo(void))(void) { return my_foo; } + int foo( void ) __attribute__(($1("resolve_foo"))); + ], + [leaf], [ + __attribute__(($1)) int foo( void ) { return 0; } + ], + [malloc], [ + void *foo( void ) __attribute__(($1)); + ], + [noclone], [ + int foo( void ) __attribute__(($1)); + ], + [noinline], [ + __attribute__(($1)) int foo( void ) { return 0; } + ], + [nonnull], [ + int foo(char *p) __attribute__(($1(1))); + ], + [noreturn], [ + void foo( void ) __attribute__(($1)); + ], + [nothrow], [ + int foo( void ) __attribute__(($1)); + ], + [optimize], [ + __attribute__(($1(3))) int foo( void ) { return 0; } + ], + [pure], [ + int foo( void ) __attribute__(($1)); + ], + [returns_nonnull], [ + void *foo( void ) __attribute__(($1)); + ], + [unused], [ + int foo( void ) __attribute__(($1)); + ], + [used], [ + int foo( void ) __attribute__(($1)); + ], + [visibility], [ + int foo_def( void ) __attribute__(($1("default"))); + int foo_hid( void ) __attribute__(($1("hidden"))); + int foo_int( void ) __attribute__(($1("internal"))); + int foo_pro( void ) __attribute__(($1("protected"))); + ], + [warning], [ + int foo( void ) __attribute__(($1(""))); + ], + [warn_unused_result], [ + int foo( void ) __attribute__(($1)); + ], + [weak], [ + int foo( void ) __attribute__(($1)); + ], + [weakref], [ + static int foo( void ) { return 0; } + static int bar( void ) __attribute__(($1("foo"))); + ], + [ + m4_warn([syntax], [Unsupported attribute $1, the test may fail]) + int foo( void ) __attribute__(($1)); + ] + )], []) + ], + dnl GCC doesn't exit with an error if an unknown attribute is + dnl provided but only outputs a warning, so accept the attribute + dnl only if no warning were issued. + [AS_IF([test -s conftest.err], + [AS_VAR_SET([ac_var], [no])], + [AS_VAR_SET([ac_var], [yes])])], + [AS_VAR_SET([ac_var], [no])]) + ]) + + AS_IF([test yes = AS_VAR_GET([ac_var])], + [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_FUNC_ATTRIBUTE_$1), 1, + [Define to 1 if the system has the `$1' function attribute])], []) + + AS_VAR_POPDEF([ac_var]) +]) diff --git a/m4/ax_gcc_x86_cpu_supports.m4 b/m4/ax_gcc_x86_cpu_supports.m4 new file mode 100644 index 0000000..fd37b4f --- /dev/null +++ b/m4/ax_gcc_x86_cpu_supports.m4 @@ -0,0 +1,104 @@ +# ============================================================================ +# https://www.gnu.org/software/autoconf-archive/ax_gcc_x86_cpu_supports.html +# ============================================================================ +# +# SYNOPSIS +# +# AX_GCC_X86_CPU_SUPPORTS(X86-INSTRUCTION-SET, +# [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) +# +# DESCRIPTION +# +# Checks if the host cpu supports X86-INSTRUCTION-SET. The instruction set +# that can be tested are "mmx, popcnt, sse, sse2, sse3, sse4.1, sse4.2, +# sse4a, avx, avx2, avx512f, fma, fma4, bmi, bmi2". If the instruction set +# is supported by the host cpu, the C preprocessor macro +# HAVE_XXX_INSTRUCTIONS is set to 1. The XXX is up-cased instruction case +# with dot replaced by underscore. For example, the test for "sse4.2" +# would export HAVE_SSE4_2_INSTRUCTIONS=1. This macro requires gcc +# extended builtin function "__builtin_cpu_init" and +# "__builtin_cpu_supports" to detect the cpu features. It will error out +# if the compiler doesn't has these builtins. +# +# If the test for the instruction set succeeded, the hook ACTION-IF-FOUND +# would run. Otherwise the hook ACTION-IF-NOT-FOUND would run if +# specified. +# +# See also AX_CHECK_X86_FEATURES, which checks all the possible +# instruction set and export the corresponding CFLAGS. +# +# LICENSE +# +# Copyright (c) 2016 Felix Chern +# +# 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 2 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 . +# +# 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 3 + +AC_DEFUN_ONCE([_AX_GCC_X86_CPU_INIT], + [AC_LANG_PUSH([C]) + AC_CACHE_CHECK([for gcc __builtin_cpu_init function], + [ax_cv_gcc_check_x86_cpu_init], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM([#include ], + [__builtin_cpu_init ();]) + ], + [ax_cv_gcc_check_x86_cpu_init=yes], + [ax_cv_gcc_check_x86_cpu_init=no])]) + AS_IF([test "X$ax_cv_gcc_check_x86_cpu_init" = "Xno"], + [AC_MSG_ERROR([Need GCC to support X86 CPU features tests])]) +]) + +AC_DEFUN([AX_GCC_X86_CPU_SUPPORTS], + [AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([_AX_GCC_X86_CPU_INIT]) + AC_LANG_PUSH([C]) + AS_VAR_PUSHDEF([gcc_x86_feature], [AS_TR_SH([ax_cv_gcc_x86_cpu_supports_$1])]) + AC_CACHE_CHECK([for x86 $1 instruction support], + [gcc_x86_feature], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM( [#include ], + [ __builtin_cpu_init (); + if (__builtin_cpu_supports("$1")) + return 0; + return 1; + ])], + [gcc_x86_feature=yes], + [gcc_x86_feature=no] + )] + ) + AC_LANG_POP([C]) + AS_VAR_IF([gcc_x86_feature],[yes], + [AC_DEFINE( + AS_TR_CPP([HAVE_$1_INSTRUCTIONS]), + [1], + [Define if $1 instructions are supported]) + $2], + [$3] + ) + AS_VAR_POPDEF([gcc_x86_feature]) +]) diff --git a/m4/ax_gcc_x86_cpuid.m4 b/m4/ax_gcc_x86_cpuid.m4 new file mode 100644 index 0000000..df95465 --- /dev/null +++ b/m4/ax_gcc_x86_cpuid.m4 @@ -0,0 +1,89 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_gcc_x86_cpuid.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_GCC_X86_CPUID(OP) +# AX_GCC_X86_CPUID_COUNT(OP, COUNT) +# +# DESCRIPTION +# +# On Pentium and later x86 processors, with gcc or a compiler that has a +# compatible syntax for inline assembly instructions, run a small program +# that executes the cpuid instruction with input OP. This can be used to +# detect the CPU type. AX_GCC_X86_CPUID_COUNT takes an additional COUNT +# parameter that gets passed into register ECX before calling cpuid. +# +# On output, the values of the eax, ebx, ecx, and edx registers are stored +# as hexadecimal strings as "eax:ebx:ecx:edx" in the cache variable +# ax_cv_gcc_x86_cpuid_OP. +# +# If the cpuid instruction fails (because you are running a +# cross-compiler, or because you are not using gcc, or because you are on +# a processor that doesn't have this instruction), ax_cv_gcc_x86_cpuid_OP +# is set to the string "unknown". +# +# This macro mainly exists to be used in AX_GCC_ARCHFLAG. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2008 Matteo Frigo +# Copyright (c) 2015 Michael Petch +# +# 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 . +# +# 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 10 + +AC_DEFUN([AX_GCC_X86_CPUID], +[AX_GCC_X86_CPUID_COUNT($1, 0) +]) + +AC_DEFUN([AX_GCC_X86_CPUID_COUNT], +[AC_REQUIRE([AC_PROG_CC]) +AC_LANG_PUSH([C]) +AC_CACHE_CHECK(for x86 cpuid $1 output, ax_cv_gcc_x86_cpuid_$1, + [AC_RUN_IFELSE([AC_LANG_PROGRAM([#include ], [ + int op = $1, level = $2, eax, ebx, ecx, edx; + FILE *f; + __asm__ __volatile__ ("xchg %%ebx, %1\n" + "cpuid\n" + "xchg %%ebx, %1\n" + : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) + : "a" (op), "2" (level)); + + f = fopen("conftest_cpuid", "w"); if (!f) return 1; + fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx); + fclose(f); + return 0; +])], + [ax_cv_gcc_x86_cpuid_$1=`cat conftest_cpuid`; rm -f conftest_cpuid], + [ax_cv_gcc_x86_cpuid_$1=unknown; rm -f conftest_cpuid], + [ax_cv_gcc_x86_cpuid_$1=unknown])]) +AC_LANG_POP([C]) +]) diff --git a/m4/ax_generate_changelog.m4 b/m4/ax_generate_changelog.m4 new file mode 100644 index 0000000..e2f0c54 --- /dev/null +++ b/m4/ax_generate_changelog.m4 @@ -0,0 +1,99 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_generate_changelog.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_GENERATE_CHANGELOG() +# +# DESCRIPTION +# +# Builds a rule for generating a ChangeLog file from version control +# system commit messages. Currently, the only supported VCS is git, but +# support for others could be added in future. +# +# Defines GENERATE_CHANGELOG_RULES which should be substituted in your +# Makefile. +# +# Usage example: +# +# configure.ac: +# +# AX_GENERATE_CHANGELOG +# +# Makefile.am: +# +# @GENERATE_CHANGELOG_RULES@ +# CHANGELOG_START = 0.2.3^ +# dist-hook: dist-ChangeLog +# +# ChangeLog (stub committed to VCS): +# +# The ChangeLog is auto-generated when releasing. +# If you are seeing this, use 'git log' for a detailed list of changes. +# +# This results in a "dist-ChangeLog" rule being added to the Makefile. +# When run, "dist-ChangeLog" will generate a ChangeLog in the +# $(top_distdir), using $(CHANGELOG_GIT_FLAGS) to format the output from +# "git log" being run in $(CHANGELOG_GIT_DIR). +# +# Unless Automake is initialised with the 'foreign' option, a dummy +# ChangeLog file must be committed to VCS in $(top_srcdir), containing the +# text above (for example). It will be substituted by the automatically +# generated ChangeLog during "make dist". +# +# LICENSE +# +# Copyright (c) 2015 David King +# Copyright (c) 2015 Philip Withnall +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 3 + +AC_DEFUN([AX_GENERATE_CHANGELOG],[ + # Find git, defaulting to the 'missing' script so the user gets a nice + # message if git is missing, rather than a plain 'command not found'. + AC_PATH_PROG([GIT],[git],[${am_missing_run}git]) + AC_SUBST([GIT]) + + # Build the ChangeLog rules. + m4_pattern_allow([AM_V_GEN]) +GENERATE_CHANGELOG_RULES=' +# Generate ChangeLog +# +# Optional: +# - CHANGELOG_START: git commit ID or tag name to output changelogs from +# (exclusive). (Default: include all commits) +# - CHANGELOG_GIT_FLAGS: General flags to pass to git-log when generating the +# ChangeLog. (Default: various) +# - CHANGELOG_GIT_DIR: .git directory to use. (Default: $(top_srcdir)/.git) + +# git-specific +CHANGELOG_GIT_FLAGS ?= --stat -M -C --name-status --no-color --no-decorate +CHANGELOG_GIT_DIR ?= $(top_srcdir)/.git + +ifeq ($(CHANGELOG_START),) +CHANGELOG_GIT_RANGE = +else +CHANGELOG_GIT_RANGE = $(CHANGELOG_START).. +endif + +# Generate a ChangeLog in $(top_distdir) +dist-ChangeLog: + $(AM_V_GEN)if $(GIT) \ + --git-dir=$(CHANGELOG_GIT_DIR) --work-tree=$(top_srcdir) log \ + $(CHANGELOG_GIT_FLAGS) $(CHANGELOG_GIT_RANGE) \ + | fmt --split-only >.ChangeLog.tmp; \ + then mv -f .ChangeLog.tmp "$(top_distdir)/ChangeLog"; \ + else rm -f .ChangeLog.tmp; exit 1; fi + +.PHONY: dist-ChangeLog +' + + AC_SUBST([GENERATE_CHANGELOG_RULES]) + m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([GENERATE_CHANGELOG_RULES])]) +]) diff --git a/m4/ax_is_release.m4 b/m4/ax_is_release.m4 new file mode 100644 index 0000000..9097ddb --- /dev/null +++ b/m4/ax_is_release.m4 @@ -0,0 +1,80 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_is_release.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_IS_RELEASE(POLICY) +# +# DESCRIPTION +# +# Determine whether the code is being configured as a release, or from +# git. Set the ax_is_release variable to 'yes' or 'no'. +# +# If building a release version, it is recommended that the configure +# script disable compiler errors and debug features, by conditionalising +# them on the ax_is_release variable. If building from git, these +# features should be enabled. +# +# The POLICY parameter specifies how ax_is_release is determined. It can +# take the following values: +# +# * git-directory: ax_is_release will be 'no' if a '.git' directory exists +# * minor-version: ax_is_release will be 'no' if the minor version number +# in $PACKAGE_VERSION is odd; this assumes +# $PACKAGE_VERSION follows the 'major.minor.micro' scheme +# * micro-version: ax_is_release will be 'no' if the micro version number +# in $PACKAGE_VERSION is odd; this assumes +# $PACKAGE_VERSION follows the 'major.minor.micro' scheme +# * dash-version: ax_is_release will be 'no' if there is a dash '-' +# in $PACKAGE_VERSION, for example 1.2-pre3, 1.2.42-a8b9 +# or 2.0-dirty (in particular this is suitable for use +# with git-version-gen) +# * always: ax_is_release will always be 'yes' +# * never: ax_is_release will always be 'no' +# +# Other policies may be added in future. +# +# LICENSE +# +# Copyright (c) 2015 Philip Withnall +# Copyright (c) 2016 Collabora Ltd. +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +#serial 7 + +AC_DEFUN([AX_IS_RELEASE],[ + AC_BEFORE([AC_INIT],[$0]) + + m4_case([$1], + [git-directory],[ + # $is_release = (.git directory does not exist) + AS_IF([test -d ${srcdir}/.git],[ax_is_release=no],[ax_is_release=yes]) + ], + [minor-version],[ + # $is_release = ($minor_version is even) + minor_version=`echo "$PACKAGE_VERSION" | sed 's/[[^.]][[^.]]*.\([[^.]][[^.]]*\).*/\1/'` + AS_IF([test "$(( $minor_version % 2 ))" -ne 0], + [ax_is_release=no],[ax_is_release=yes]) + ], + [micro-version],[ + # $is_release = ($micro_version is even) + micro_version=`echo "$PACKAGE_VERSION" | sed 's/[[^.]]*\.[[^.]]*\.\([[^.]]*\).*/\1/'` + AS_IF([test "$(( $micro_version % 2 ))" -ne 0], + [ax_is_release=no],[ax_is_release=yes]) + ], + [dash-version],[ + # $is_release = ($PACKAGE_VERSION has a dash) + AS_CASE([$PACKAGE_VERSION], + [*-*], [ax_is_release=no], + [*], [ax_is_release=yes]) + ], + [always],[ax_is_release=yes], + [never],[ax_is_release=no], + [ + AC_MSG_ERROR([Invalid policy. Valid policies: git-directory, minor-version, micro-version, dash-version, always, never.]) + ]) +]) diff --git a/m4/ax_msg_bold.m4 b/m4/ax_msg_bold.m4 new file mode 100644 index 0000000..5162773 --- /dev/null +++ b/m4/ax_msg_bold.m4 @@ -0,0 +1,29 @@ +dnl @synopsis AX_MSG_BOLD([BOLD_TEXT]) +dnl @synopsis AX_MSG_OPTION([NORMAL TEXT], [BOLD_TEXT]) +dnl +dnl Prints messages using a nice visual effect; you should set the +dnl (shell) variables SB and EB in your configure.{ac,in} file using +dnl something like this: +dnl +dnl SB=`$srcdir/shtool echo -n -e %B` +dnl EB=`$srcdir/shtool echo -n -e %b` +dnl +dnl Examples: +dnl AX_MSG_BOLD([foobar]) +dnl +dnl AX_MSG_OPTION([ foo .................... ], [${BAR}]) +dnl +dnl @category Misc +dnl @author Davide Scola +dnl @version 2017-04-20 +dnl @license AllPermissive + +AC_DEFUN([AX_MSG_BOLD], [ + AC_MSG_RESULT + AC_MSG_RESULT([${SB}$1...${EB}]) + AC_MSG_RESULT +])dnl AX_MSG_BOLD + +AC_DEFUN([AX_MSG_OPTION], [ + AC_MSG_RESULT([$1 ${SB}$2${EB}]) +])dnl AX_MSG_OPTION diff --git a/m4/ax_require_defined.m4 b/m4/ax_require_defined.m4 new file mode 100644 index 0000000..17c3eab --- /dev/null +++ b/m4/ax_require_defined.m4 @@ -0,0 +1,37 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_require_defined.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_REQUIRE_DEFINED(MACRO) +# +# DESCRIPTION +# +# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have +# been defined and thus are available for use. This avoids random issues +# where a macro isn't expanded. Instead the configure script emits a +# non-fatal: +# +# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found +# +# It's like AC_REQUIRE except it doesn't expand the required macro. +# +# Here's an example: +# +# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) +# +# LICENSE +# +# Copyright (c) 2014 Mike Frysinger +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 2 + +AC_DEFUN([AX_REQUIRE_DEFINED], [dnl + m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])]) +])dnl AX_REQUIRE_DEFINED diff --git a/m4/ax_require_prog.m4 b/m4/ax_require_prog.m4 new file mode 100644 index 0000000..51ff07c --- /dev/null +++ b/m4/ax_require_prog.m4 @@ -0,0 +1,81 @@ +dnl @synopsis AX_REQUIRE_PROG([name]) +dnl +dnl Macro to require system tools; a variable named as uppercase tool name +dnl will be created containing the absolute path of the program. +dnl +dnl Examples: +dnl AX_PROG_UUIDGEN +dnl AX_REQUIRE_PROG([foo]) +dnl +dnl @category Misc +dnl @author Davide Scola +dnl @version 2017-08-28 +dnl @license AllPermissive + +AC_DEFUN([AX_PROG_JQ], [ + AX_REQUIRE_PROG([jq]) +])dnl AX_PROG_JQ + +AC_DEFUN([AX_PROG_CAT], [ + AX_REQUIRE_PROG([cat]) +])dnl AX_PROG_CAT + +AC_DEFUN([AX_PROG_XXD], [ + AX_REQUIRE_PROG([xxd]) +])dnl AX_PROG_XXD + +AC_DEFUN([AX_PROG_DATE], [ + AX_REQUIRE_PROG([date]) +])dnl AX_PROG_DATE + +AC_DEFUN([AX_PROG_CURL], [ + AX_REQUIRE_PROG([curl]) +])dnl AX_PROG_CURL + +AC_DEFUN([AX_PROG_MKDIR], [ + AX_REQUIRE_PROG([mkdir]) +])dnl AX_PROG_MKDIR + +AC_DEFUN([AX_PROG_GETOPT], [ + AX_REQUIRE_PROG([getopt]) +])dnl AX_PROG_GETOPT + +AC_DEFUN([AX_PROG_UUIDGEN], [ + AX_WITH_PROG([UUIDGEN], [uuidgen]) + + AS_IF([test -z "${UUIDGEN}"], [ + AC_PATH_PROG([UUIDGEN], [dbus-uuidgen]) + + AS_IF([test -z "${UUIDGEN}"], [ + AC_MSG_CHECKING([whether your kernel provides an UUID generation mechanism]) + + AS_IF([test -f '/proc/sys/kernel/random/uuid'], [ + AC_MSG_RESULT([yes]) + + AX_PROG_CAT + UUIDGEN="${CAT} /proc/sys/kernel/random/uuid" + ], [ + AC_MSG_RESULT([no]) + AC_MSG_ERROR([unable to find the uuidgen application (or equivalent)]) + ]) + ]) + ]) +]) + +AC_DEFUN([AX_PROG_SHA1SUM], [ + AX_REQUIRE_PROG([sha1sum]) +])dnl AX_PROG_SHA1SUM + +AC_DEFUN([AX_PROG_READLINK], [ + AX_REQUIRE_PROG([readlink]) +])dnl AX_PROG_READLINK + +AC_DEFUN([AX_REQUIRE_PROG], [ + AS_LITERAL_IF([$1], [], [AC_FATAL([$0: requires literal arguments])]) + + AX_WITH_PROG(translit(m4_toupper($1), [-], [_]), [$1], [no]) + + AS_IF([test "x${translit(m4_toupper($1), [-], [_])[]}" = 'xno'], [ + AC_MSG_ERROR([$1 cannot be found, please provide the full path.]) + ]) +])dnl AX_REQUIRE_PROG diff --git a/m4/ax_restore_flags.m4 b/m4/ax_restore_flags.m4 new file mode 100644 index 0000000..8f2adf2 --- /dev/null +++ b/m4/ax_restore_flags.m4 @@ -0,0 +1,52 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_restore_flags.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_RESTORE_FLAGS([namespace]) +# +# DESCRIPTION +# +# Restore common compilation flags from temporary variables. +# +# Compilation flags includes: CPPFLAGS, CFLAGS, CXXFLAGS, LDFLAGS, LIBS, +# OBJCFLAGS. +# +# By default these flags are restored to a global (empty) namespace, but +# user could restore from specific NAMESPACE by using +# AX_RESTORE_FLAGS(NAMESPACE) macro. +# +# Typical usage is like: +# +# AX_SAVE_FLAGS(mypackage) +# CPPFLAGS="-Imypackagespath ${CPPFLAGS}" +# dnl ... do some detection ... +# AX_RESTORE_FLAGS(mypackage) +# +# LICENSE +# +# Copyright (c) 2009 Filippo Giunchedi +# Copyright (c) 2011 The Board of Trustees of the Leland Stanford Junior University +# Copyright (c) 2011 Russ Allbery +# Copyright (c) 2013 Bastien ROUCARIES +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 7 + +# save one flag in name space +AC_DEFUN([_AX_RESTORE_ONE_FLAG],[dnl + AS_VAR_PUSHDEF([_ax_restore_flag_var], [$2[]_$1[]_ax_save_flags]) + AS_VAR_COPY($2[],_ax_restore_flag_var) + AS_VAR_POPDEF([_ax_restore_flag_var]) +]) + +AC_DEFUN([AX_RESTORE_FLAGS], [dnl + m4_foreach([FLAG], dnl + [_AX_SAVE_FLAGS_LIST()], dnl + [_AX_RESTORE_ONE_FLAG([$1],FLAG)]) +]) diff --git a/m4/ax_save_flags.m4 b/m4/ax_save_flags.m4 new file mode 100644 index 0000000..5bc7c6c --- /dev/null +++ b/m4/ax_save_flags.m4 @@ -0,0 +1,71 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_save_flags.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_SAVE_FLAGS([NAMESPACE]) +# +# DESCRIPTION +# +# Save common compilation flags into temporary variables. +# +# Compilation flags includes: CPPFLAGS, CFLAGS, CXXFLAGS, LDFLAGS, LIBS, +# OBJCFLAGS. +# +# By default these flags are saved to a global (empty) namespace, but user +# could specify a specific NAMESPACE to AX_SAVE_FLAGS macro and latter +# restore it by using AX_RESTORE_FLAGS(NAMESPACE). +# +# AX_SAVE_FLAGS(mypackage) +# CPPFLAGS="-Imypackagespath ${CPPFLAGS}" +# dnl .. do some detection ... +# AX_RESTORE_FLAGS(mypackage) +# +# LICENSE +# +# Copyright (c) 2009 Filippo Giunchedi +# Copyright (c) 2011 The Board of Trustees of the Leland Stanford Junior University +# Copyright (c) 2011 Russ Allbery +# Copyright (c) 2013 Bastien ROUCARIES +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 8 + +# list of flag to save +AC_DEFUN([_AX_SAVE_FLAGS_LIST],[dnl +[CCASFLAGS],dnl +[CFLAGS],dnl +[CPPFLAGS],dnl +[CXXFLAGS],dnl +[ERLCFLAGS],dnl +[FCFLAGS],dnl +[FCLIBS],dnl +[FFLAGS],dnl +[FLIBS],dnl +[GCJFLAGS],dnl +[JAVACFLAGS],dnl +[LDFLAGS],dnl +[LIBS],dnl +[OBJCFLAGS],dnl +[OBJCXXFLAGS],dnl +[UPCFLAGS],dnl +[VALAFLAGS]dnl +]) + +# save one flag in name space +AC_DEFUN([_AX_SAVE_ONE_FLAG],[ + AS_VAR_PUSHDEF([_ax_save_flag_var], [$2[]_$1[]_ax_save_flags]) + AS_VAR_COPY(_ax_save_flag_var, $2[]) + AS_VAR_POPDEF([_ax_save_flag_var]) +]) + +AC_DEFUN([AX_SAVE_FLAGS],[dnl + m4_foreach([FLAG], dnl + [_AX_SAVE_FLAGS_LIST()], dnl + [_AX_SAVE_ONE_FLAG([$1],FLAG)]) +]) diff --git a/m4/ax_with_prog.m4 b/m4/ax_with_prog.m4 new file mode 100644 index 0000000..b3a881c --- /dev/null +++ b/m4/ax_with_prog.m4 @@ -0,0 +1,70 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_with_prog.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_WITH_PROG([VARIABLE],[program],[VALUE-IF-NOT-FOUND],[PATH]) +# +# DESCRIPTION +# +# Locates an installed program binary, placing the result in the precious +# variable VARIABLE. Accepts a present VARIABLE, then --with-program, and +# failing that searches for program in the given path (which defaults to +# the system path). If program is found, VARIABLE is set to the full path +# of the binary; if it is not found VARIABLE is set to VALUE-IF-NOT-FOUND +# if provided, unchanged otherwise. +# +# A typical example could be the following one: +# +# AX_WITH_PROG(PERL,perl) +# +# NOTE: This macro is based upon the original AX_WITH_PYTHON macro from +# Dustin J. Mitchell . +# +# LICENSE +# +# Copyright (c) 2008 Francesco Salvestrini +# Copyright (c) 2008 Dustin J. Mitchell +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 17 + +AC_DEFUN([AX_WITH_PROG],[ + AC_PREREQ([2.61]) + + pushdef([VARIABLE],$1) + pushdef([EXECUTABLE],$2) + pushdef([VALUE_IF_NOT_FOUND],$3) + pushdef([PATH_PROG],$4) + + AC_ARG_VAR(VARIABLE,Absolute path to EXECUTABLE executable) + + AS_IF(test -z "$VARIABLE",[ + AC_MSG_CHECKING(whether EXECUTABLE executable path has been provided) + AC_ARG_WITH(EXECUTABLE,AS_HELP_STRING([--with-EXECUTABLE=[[[PATH]]]],absolute path to EXECUTABLE executable), [ + AS_IF([test "$withval" != yes && test "$withval" != no],[ + VARIABLE="$withval" + AC_MSG_RESULT($VARIABLE) + ],[ + VARIABLE="" + AC_MSG_RESULT([no]) + AS_IF([test "$withval" != no], [ + AC_PATH_PROG([]VARIABLE[],[]EXECUTABLE[],[]VALUE_IF_NOT_FOUND[],[]PATH_PROG[]) + ]) + ]) + ],[ + AC_MSG_RESULT([no]) + AC_PATH_PROG([]VARIABLE[],[]EXECUTABLE[],[]VALUE_IF_NOT_FOUND[],[]PATH_PROG[]) + ]) + ]) + + popdef([PATH_PROG]) + popdef([VALUE_IF_NOT_FOUND]) + popdef([EXECUTABLE]) + popdef([VARIABLE]) +]) diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..b2aa675 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,118 @@ +############################################################################ +# This file is part of Grenache Command Line Interface. # +# # +# Copyright (C) 2017 Davide Scola # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # +# implied. See the License for the specific language governing permissions # +# and limitations under the License. # +############################################################################ + +bin_PROGRAMS = \ +grc-keygen \ +grc-sign \ +grc-verify + +bin_SCRIPTS = \ +grenache-put \ +grenache-get \ +grenache-keygen + +noinst_LTLIBRARIES = \ +libed25519.la \ +libcommon.la + + +libed25519_la_SOURCES = \ +$(top_srcdir)/ed25519/src/add_scalar.c \ +$(top_srcdir)/ed25519/src/fe.c \ +$(top_srcdir)/ed25519/src/ge.c \ +$(top_srcdir)/ed25519/src/key_exchange.c \ +$(top_srcdir)/ed25519/src/keypair.c \ +$(top_srcdir)/ed25519/src/sc.c \ +$(top_srcdir)/ed25519/src/seed.c \ +$(top_srcdir)/ed25519/src/sha512.c \ +$(top_srcdir)/ed25519/src/sign.c \ +$(top_srcdir)/ed25519/src/verify.c + +libed25519_la_CFLAGS = \ +$(WARN_CFLAGS) + +libed25519_la_LDFLAGS = \ +$(WARN_LDFLAGS) + + +libcommon_la_SOURCES = \ +io.c \ +encode.c + +libcommon_la_CPPFLAGS = \ +-I$(top_srcdir)/include + +libcommon_la_CFLAGS = \ +$(WARN_CFLAGS) + +libcommon_la_LDFLAGS = \ +$(WARN_LDFLAGS) + + +grc_keygen_SOURCES = \ +grc-keygen.c + +grc_keygen_CPPFLAGS = \ +-I$(top_srcdir)/include \ +-I$(top_srcdir)/ed25519/src + +grc_keygen_LDADD = \ +libcommon.la \ +libed25519.la + +grc_keygen_CFLAGS = \ +$(WARN_CFLAGS) + +grc_keygen_LDFLAGS = \ +$(WARN_LDFLAGS) + + +grc_sign_SOURCES = \ +grc-sign.c + +grc_sign_CPPFLAGS = \ +-I$(top_srcdir)/include \ +-I$(top_srcdir)/ed25519/src + +grc_sign_LDADD = \ +libcommon.la \ +libed25519.la + +grc_sign_CFLAGS = \ +$(WARN_CFLAGS) + +grc_sign_LDFLAGS = \ +$(WARN_LDFLAGS) + + +grc_verify_SOURCES = \ +grc-verify.c + +grc_verify_CPPFLAGS = \ +-I$(top_srcdir)/include \ +-I$(top_srcdir)/ed25519/src + +grc_verify_LDADD = \ +libcommon.la \ +libed25519.la + +grc_verify_CFLAGS = \ +$(WARN_CFLAGS) + +grc_verify_LDFLAGS = \ +$(WARN_LDFLAGS) diff --git a/src/encode.c b/src/encode.c new file mode 100644 index 0000000..ad2b5bb --- /dev/null +++ b/src/encode.c @@ -0,0 +1,109 @@ +/** + * @file + * This file is part of Grenache Command Line Interface. + * + * Copyright (C) 2017 Davide Scola + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "common.h" +#include "encode.h" + + +/** + * Return decimal value from hexadecimal character. + * + * @param char ch + * The hexadecimal character (lowercase). + * + * @return unsigned char + * The decimal value or 0 in case of error. + */ +INLINE ALWAYS_INLINE unsigned char ord(char ch) { + return (ch >= L'0' && ch <= L'9') ? (ch - L'0') : ( + (ch >= L'a' && ch <= L'f') ? (ch - L'a' + 10) : 0 + ); +} + +/** + * Return hexadecimal character from decimal value. + * + * @param unsigned char ord + * The decimal value. + * + * @return char + * The hexadecimal character (lowercase). + */ +INLINE ALWAYS_INLINE char ch(unsigned char ord) { + return ((ord & 0x0F) >= 0 && (ord & 0x0F) <= 9) ? ((ord & 0x0F) + L'0') : ( + (ord & 0x0F) + L'a' - 10 + ); +} + +/** + * Encode byte string to hexadecimal sequence. + * + * @param const unsigned char *binary + * The input buffer of the binary string. + * @param size_t length + * The size of the input buffer. + * @param char *buffer + * The output buffer of the hexadecimal string. + * + * @return unsigned char * + * A pointer to the output buffer. + */ +char *encode(const unsigned char *binary, size_t length, char *buffer) { + char *ptr_out = buffer; + unsigned char *ptr_in = (unsigned char *)binary; + + while (ptr_in < binary + length) { + *ptr_out++ = ch(*ptr_in >> 4); + *ptr_out++ = ch(*ptr_in++); + } + + *ptr_out = '\0'; + return buffer; +} + +/** + * Decode hexadecimal sequence to byte string. + * + * @param const char *buffer + * The input buffer of the hexadecimal string. + * @param size_t length + * The size of the input buffer. + * @param unsigned char *binary + * The output buffer of the binary string. + * + * @return unsigned char * + * A pointer to the output buffer. + */ +unsigned char *decode(const char *buffer, size_t length, unsigned char *binary) { + char *ptr_in = (char *)buffer; + unsigned char *ptr_out = binary; + + while (ptr_out < binary + (length >> 1)) { + *ptr_out = (ord(*ptr_in++) << 4); + *ptr_out++ |= ord(*ptr_in++); + } + + return binary; +} diff --git a/src/grc-keygen.c b/src/grc-keygen.c new file mode 100644 index 0000000..67ea65a --- /dev/null +++ b/src/grc-keygen.c @@ -0,0 +1,104 @@ +/** + * @file + * This file is part of Grenache Command Line Interface. + * + * Copyright (C) 2017 Davide Scola + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#ifdef HAVE_FCNTL_H +# include +#endif + +#ifdef HAVE_BSD_STRING_H +# include +#endif + +#include +#include "common.h" +#include "io.h" +#include "encode.h" + + +static char buffer[ + ED25519_MAX_HEX_SIZE + + ED25519_SEED_SIZE + + ED25519_PUBLIC_KEY_SIZE + + ED25519_SECRET_KEY_SIZE + + 1 +]; + +int main(void) { + unsigned char *seed = (unsigned char *) (buffer + ED25519_MAX_HEX_SIZE + 1), + *public_key = (unsigned char *) (seed + ED25519_SEED_SIZE), + *private_key = (unsigned char *) (public_key + ED25519_PUBLIC_KEY_SIZE); + + if (fcntl(SKEY_FILENO, F_GETFD) < 0 && errno == EBADF) { +#if !defined(NDEBUG) + (void) fprintf(stderr, "error: cannot access file descriptor %d\n", SKEY_FILENO); +#endif + + exit(EXIT_FAILURE); + } + + if (fcntl(PKEY_FILENO, F_GETFD) < 0 && errno == EBADF) { +#if !defined(NDEBUG) + (void) fprintf(stderr, "error: cannot access file descriptor %d\n", PKEY_FILENO); +#endif + + exit(EXIT_FAILURE); + } + + if (ed25519_create_seed(seed) != 0) { +#if !defined(NDEBUG) + (void) fprintf(stderr, "error: cannot initialize ed25519 seeder.\n"); +#endif + + exit(EXIT_FAILURE); + } + + ed25519_create_keypair(public_key, private_key, seed); + explicit_bzero(seed, ED25519_SEED_SIZE); + + (void) encode(private_key, ED25519_SECRET_KEY_SIZE, buffer); + + if (iowrite(SKEY_FILENO, buffer, ED25519_SECRET_KEY_SIZE << 1) < 0) { +#if !defined(NDEBUG) + (void) fprintf(stderr, "error: cannot write secret key to descriptor %d\n", SKEY_FILENO); +#endif + + exit(EXIT_FAILURE); + } + + explicit_bzero(private_key, ED25519_SECRET_KEY_SIZE); + (void) encode(public_key, ED25519_PUBLIC_KEY_SIZE, buffer); + + if (iowrite(PKEY_FILENO, buffer, ED25519_PUBLIC_KEY_SIZE << 1) < 0) { +#if !defined(NDEBUG) + (void) fprintf(stderr, "error: cannot write public key to descriptor %d\n", PKEY_FILENO); +#endif + + exit(EXIT_FAILURE); + } + + exit(EXIT_SUCCESS); +} diff --git a/src/grc-sign.c b/src/grc-sign.c new file mode 100644 index 0000000..2772de5 --- /dev/null +++ b/src/grc-sign.c @@ -0,0 +1,115 @@ +/** + * @file + * This file is part of Grenache Command Line Interface. + * + * Copyright (C) 2017 Davide Scola + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#ifdef HAVE_FCNTL_H +# include +#endif + +#ifdef HAVE_BSD_STRING_H +# include +#endif + +#include +#include "common.h" +#include "io.h" +#include "encode.h" + + +static char buffer[ + ED25519_MAX_HEX_SIZE + + ED25519_SIGNATURE_SIZE + + ED25519_PUBLIC_KEY_SIZE + + ED25519_SECRET_KEY_SIZE + + 1 +]; + + +int main(int argc, char *argv[]) { + unsigned char *signature = (unsigned char *) (buffer + ED25519_MAX_HEX_SIZE + 1), + *public_key = (unsigned char *) (signature + ED25519_SIGNATURE_SIZE), + *private_key = (unsigned char *) (public_key + ED25519_PUBLIC_KEY_SIZE); + + if (argc < 2) { +#if !defined(NDEBUG) + (void) fprintf(stderr, "usage: grc-sign [, message[, message[, ...]]]\n"); +#endif + + exit(EXIT_FAILURE); + } + + if (fcntl(SKEY_FILENO, F_GETFD) < 0 && errno == EBADF) { +#if !defined(NDEBUG) + (void) fprintf(stderr, "error: cannot access file descriptor %d\n", SKEY_FILENO); +#endif + + exit(EXIT_FAILURE); + } + + if (fcntl(PKEY_FILENO, F_GETFD) < 0 && errno == EBADF) { +#if !defined(NDEBUG) + (void) fprintf(stderr, "error: cannot access file descriptor %d\n", PKEY_FILENO); +#endif + + exit(EXIT_FAILURE); + } + + if (ioread(SKEY_FILENO, buffer, ED25519_SECRET_KEY_SIZE << 1) < 0) { +#if !defined(NDEBUG) + (void) fprintf(stderr, "error: cannot read secret key from descriptor %d\n", SKEY_FILENO); +#endif + + exit(EXIT_FAILURE); + } + + (void) decode(buffer, ED25519_SECRET_KEY_SIZE << 1, private_key); + explicit_bzero(buffer, ED25519_SECRET_KEY_SIZE << 1); + + if (ioread(PKEY_FILENO, buffer, ED25519_PUBLIC_KEY_SIZE << 1) < 0) { +#if !defined(NDEBUG) + (void) fprintf(stderr, "error: cannot read public key from descriptor %d\n", PKEY_FILENO); +#endif + + exit(EXIT_FAILURE); + } + + (void) decode(buffer, ED25519_PUBLIC_KEY_SIZE << 1, public_key); + + while (*++argv != NULL) { + if (**argv != '\0') { + ed25519_sign(signature, (unsigned char *)*argv, strlen(*argv), public_key, private_key); + iowrite(STDOUT_FILENO, encode(signature, ED25519_SIGNATURE_SIZE, buffer), ED25519_SIGNATURE_SIZE << 1); + } + } + + explicit_bzero(private_key, ED25519_SECRET_KEY_SIZE); + exit(EXIT_SUCCESS); +} diff --git a/src/grc-verify.c b/src/grc-verify.c new file mode 100644 index 0000000..61b152a --- /dev/null +++ b/src/grc-verify.c @@ -0,0 +1,104 @@ +/** + * @file + * This file is part of Grenache Command Line Interface. + * + * Copyright (C) 2017 Davide Scola + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#ifdef HAVE_FCNTL_H +# include +#endif + +#include +#include "common.h" +#include "io.h" +#include "encode.h" + + +static char buffer[ + ED25519_MAX_HEX_SIZE + + ED25519_SIGNATURE_SIZE + + ED25519_PUBLIC_KEY_SIZE + + 1 +]; + + +int main(int argc, char *argv[]) { + unsigned char *signature = (unsigned char *) (buffer + ED25519_MAX_HEX_SIZE + 1), + *public_key = (unsigned char *) (signature + ED25519_SIGNATURE_SIZE); + + if (fcntl(SIGN_FILENO, F_GETFD) < 0 && errno == EBADF) { +#if !defined(NDEBUG) + (void) fprintf(stderr, "error: cannot access file descriptor %d\n", SIGN_FILENO); +#endif + + exit(EXIT_FAILURE); + } + + if (fcntl(PKEY_FILENO, F_GETFD) < 0 && errno == EBADF) { +#if !defined(NDEBUG) + (void) fprintf(stderr, "error: cannot access file descriptor %d\n", PKEY_FILENO); +#endif + + exit(EXIT_FAILURE); + } + + if (ioread(SIGN_FILENO, buffer, ED25519_SIGNATURE_SIZE << 1) < 0) { +#if !defined(NDEBUG) + (void) fprintf(stderr, "error: cannot read signature from descriptor %d\n", SIGN_FILENO); +#endif + + exit(EXIT_FAILURE); + } + + (void) decode(buffer, ED25519_SIGNATURE_SIZE << 1, signature); + + if (ioread(PKEY_FILENO, buffer, ED25519_PUBLIC_KEY_SIZE << 1) < 0) { +#if !defined(NDEBUG) + (void) fprintf(stderr, "error: cannot read public key from descriptor %d\n", PKEY_FILENO); +#endif + + exit(EXIT_FAILURE); + } + + (void) decode(buffer, ED25519_PUBLIC_KEY_SIZE << 1, public_key); + + while (*++argv != NULL) { + if (**argv != '\0') { + if (!ed25519_verify(signature, (unsigned char *)*argv, strlen(*argv), public_key)) { +#if !defined(NDEBUG) + (void) fprintf(stderr, "NOT OK\n"); +#endif + + exit(EXIT_FAILURE); + } + } + } + +#if !defined(NDEBUG) + (void) fprintf(stdout, "OK\n"); +#endif + + exit(EXIT_SUCCESS); +} diff --git a/src/grenache-get.in b/src/grenache-get.in new file mode 100644 index 0000000..46bfc07 --- /dev/null +++ b/src/grenache-get.in @@ -0,0 +1,178 @@ +#!/bin/bash +############################################################################ +# This file is part of Grenache Command Line Interface. # +# # +# Copyright (C) 2017 Davide Scola # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # +# implied. See the License for the specific language governing permissions # +# and limitations under the License. # +############################################################################ + +ME="${BASH_SOURCE[0]}" +WHOAMI="$(@READLINK@ -snf "${ME}")" +ARGV=$(@GETOPT@ -o 'g:hip:trvw' --long 'grape:,help,id,port:,tls,raw,value,write' -n "${ME##*/}" -- "$@") || exit 1 + +TLS='' +PORT=30001 +HOSTNAME='127.0.0.1' +QUERY='select(.v) | .v' + + +# Show program's help. +function show_help { + @CAT@ <<_EOF +Usage: + ${ME##*/} [OPTIONS] ... -- send a GET request to the DHT + + Options: + + -g, --grape Set the Grape hostname + -i. --id Get the id of sending node + -p, --port Set the Grape port number + -t, --tls Enable TLS + -r, --raw Get the raw response message + -v, --value Get the stored value + -w, --write Get the write token + + -h, --help Show this message + + The order of the specified options is not relevant. +_EOF + + exit 1 +} + + +while true; do + case "$1" in + -g | --grape ) + [[ -z "${2}" ]] && { + echo "${ME##*/}: error: empty Grape hostname." >&2 + exit 1 + } + + HOSTNAME="${2}"; shift 2 + ;; + -h | --help ) + show_help; shift 1 + ;; + -i | --id ) + QUERY='select(.id) | .id'; shift 1 + ;; + -p | --port ) + [[ "${2}" =~ ^[0-9]+$ ]] || { + echo "${ME##*/}: error: invalid Grape port number." >&2 + exit 1 + } + + [[ "$((${2} & 0xFFFF))" -eq 0 ]] && { + echo "${ME##*/}: error: Grape port number must be greater than zero." >&2 + exit 1 + } + + [[ "${2}" -ne "$((${2} & 0xFFFF))" ]] && { + echo "${ME##*/}: error: Grape port number too big." >&2 + exit 1 + } + + PORT="$((${2} & 0xFFFF))"; shift 2 + ;; + -t | --tls ) + TLS='yes'; shift 1 + ;; + -r | --raw ) + QUERY='select(.)'; shift 1 + ;; + -v | --value ) + QUERY='select(.v) | .v'; shift 1 + ;; + -w | --write ) + QUERY='select(.token) | .token'; shift 1 + ;; + -- ) shift; break ;; + * ) break ;; + esac +done + + +[[ "${#}" -lt 1 ]] && { + show_help +} + +[[ -f "${HOME}/.grenache-cli/grenache-cli.conf" ]] || { + echo "${ME##*/}: error: you need to run \`grenache-keygen' first." >&2 + exit 1 +} + +exec {debug}>>/dev/null + +for hash in "${@}" +do + [[ "${hash}" =~ ^[a-fA-F0-9]{40}$ ]] || { + echo "${ME##*/}: error: invalid hash provided: ${hash}." >&2 + + exec {debug}>&- + exit 1 + } + + JSON="$(@CURL@ -qK "${HOME}/.grenache-cli/grenache-cli.conf" "http${TLS:+s}://${HOSTNAME}:${PORT}/get" < <( \ + @JQ@ -cnM \ + --arg 'data' "${hash}" \ + --arg 'rid' "$(@UUIDGEN@)" \ + '{ "data": $data, "rid": $rid }' 2>&"${debug}" \ + ) 2>&"${debug}")" + + @JQ@ -e 'has("k")' >/dev/null 2>&"${debug}" <<<"${JSON}" && { + CHALLENGE='' + + @JQ@ -e 'has("salt")' >/dev/null 2>&"${debug}" <<<"${JSON}" && { + CHALLENGE+="$(@JQ@ -cMjr '"4:salt\(.salt.data | implode | length):\(.salt.data | implode)"' 2>&"${debug}" <<<"${JSON}")" + } + + CHALLENGE+="$(@JQ@ -cMjr '"3:seqi" + "\(.seq)" + "e1:v" + "\(.v | length):\(.v)"' 2>&"${debug}" <<<"${JSON}")" + + ${WHOAMI%/*}/grc-verify "${CHALLENGE}" \ + @PKEY_FILENO@< <( \ + printf '%02x' $(@JQ@ -cMr 'select(.k.data) | @sh "\(.k.data)"' <<<"${JSON}" 2>&"${debug}") + ) \ + @SIGN_FILENO@< <( \ + printf '%02x' $(@JQ@ -cMr 'select(.sig.data) | @sh "\(.sig.data)"' <<<"${JSON}" 2>&"${debug}") + ) >/dev/null 2>&"${debug}" || { + echo "${ME##*/}: error: cannot verify challenge buffer." >&2 + + exec {debug}>&- + exit 1 + } + + CHECK="$(@SHA1SUM@ < <( \ + @XXD@ -r -p < <( \ + printf '%02x' $(@JQ@ -cMr 'select(.k.data) | @sh "\(.k.data + .salt.data)"' <<<"${JSON}" 2>&"${debug}") + ) 2>&"${debug}" \ + ) 2>&"${debug}")" + } || { + CHECK="$(@SHA1SUM@ < <( \ + @JQ@ -cMjr 'select(.v) | "\(.v | length):\(.v)"' <<<"${JSON}" 2>&"${debug}" + ) 2>&"${debug}")" + } + + [[ "x${hash}" = "x${CHECK%% *}" ]] || { + echo "${ME##*/}: error: unexpected value." >&2 + + exec {debug}>&- + exit 1 + } + + @JQ@ -cMr "${QUERY}" <<<"${JSON}" 2>&"${debug}" +done + +exec {debug}>&- +exit 0 diff --git a/src/grenache-keygen.in b/src/grenache-keygen.in new file mode 100644 index 0000000..8335be6 --- /dev/null +++ b/src/grenache-keygen.in @@ -0,0 +1,100 @@ +#!/bin/bash +############################################################################ +# This file is part of Grenache Command Line Interface. # +# # +# Copyright (C) 2017 Davide Scola # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # +# implied. See the License for the specific language governing permissions # +# and limitations under the License. # +############################################################################ + +ME="${BASH_SOURCE[0]}" +WHOAMI="$(@READLINK@ -snf "${ME}")" +ARGV=$(@GETOPT@ -o 'fh' --long 'force,help' -n "${ME##*/}" -- "$@") || exit 1 + +OVERWRITE='no' + + +# Show program's help. +function show_help { + @CAT@ <<_EOF +Usage: + ${ME##*/} [OPTIONS] -- creates your grenache-cli keypair. + + Options: + + -f, --force Overwrite existing keypair + + -h, --help Show this message + + The order of the specified options is not relevant. +_EOF + + exit 1 +} + + +while true; do + case "$1" in + -f | --force ) + OVERWRITE='yes'; shift 1 + ;; + -h | --help ) + show_help; shift 1 + ;; + -- ) shift; break ;; + * ) break ;; + esac +done + + +umask 0077 +exec {debug}>>/dev/null + +[[ "x${OVERWRITE}" = 'xno' ]] && { + set -o noclobber +} + +@MKDIR@ "${HOME}/.grenache-cli" 2>&"${debug}" && { + @CAT@ > "${HOME}/.grenache-cli/grenache-cli.conf" 2>&"${debug}" <<_EOF +# +# General +# +silent +compress +user-agent "@PACKAGE@/@PACKAGE_VERSION@" + +# +# Request +# +data "@-" + +# +# Headers +# +header = "Connection:close" +header = "Accept:application/json" +header = "Content-Type:application/json; charset=UTF-8" +_EOF +} + +${WHOAMI%/*}/grc-keygen 2>&"${debug}" \ + @SKEY_FILENO@> "${HOME}/.grenache-cli/key" \ + @PKEY_FILENO@> "${HOME}/.grenache-cli/key.pub" || { \ + echo "${ME##*/}: error: cannot create new keypair." >&2 + exit 1 +} + +echo "${ME##*/}: keypair generated successfully." + +exec {debug}>&- +exit 0 diff --git a/src/grenache-put.in b/src/grenache-put.in new file mode 100644 index 0000000..68051d0 --- /dev/null +++ b/src/grenache-put.in @@ -0,0 +1,245 @@ +#!/bin/bash +############################################################################ +# This file is part of Grenache Command Line Interface. # +# # +# Copyright (C) 2017 Davide Scola # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # +# implied. See the License for the specific language governing permissions # +# and limitations under the License. # +############################################################################ + +ME="${BASH_SOURCE[0]}" +WHOAMI="$(@READLINK@ -snf "${ME}")" +ARGV=$(@GETOPT@ -o 'c:g:hm:n:p:s:t' --long 'cas:,grape:,help,mutable,number:,port:,salt:,tls' -n "${ME##*/}" -- "$@") || exit 1 + +TLS='' +CAS='' +SALT='' +MUTABLE='' +PORT=30001 +HOSTNAME='127.0.0.1' +SEQUENCE="$(@DATE@ '+%s%6N')" + + +# Show program's help. +function show_help { + @CAT@ <<_EOF +Usage: + ${ME##*/} [OPTIONS] ... -- send a PUT request to the DHT + + Options: + + -c, --cas Set the compare and swap number + -g, --grape Set the Grape hostname + -m, --mutable Send a mutable PUT request + -n, --number Set the sequence number of this PUT request + -p, --port Set the Grape port number + -s, --salt Set salt for this request + -t, --tls Enable TLS + + -h, --help Show this message + + The order of the specified options is not relevant. +_EOF + + exit 1 +} + + +while true; do + case "$1" in + -c | --cas ) + [[ "${2}" =~ ^[0-9]+$ ]] || { + echo "${ME##*/}: error: invalid compare and swap number." >&2 + exit 1 + } + + [[ "${2}" -ne "$((${2} & 0x7FFFFFFFFFFFFFFF))" ]] && { + echo "${ME##*/}: error: compare and swap number too big." >&2 + exit 1 + } + + CAS="$((${2} & 0x7FFFFFFFFFFFFFFF))"; shift 2 + ;; + -g | --grape ) + [[ -z "${2}" ]] && { + echo "${ME##*/}: error: empty Grape hostname." >&2 + exit 1 + } + + HOSTNAME="${2}"; shift 2 + ;; + -h | --help ) + show_help; shift 1 + ;; + -m | --mutable ) + MUTABLE='yes'; shift 1 + ;; + -n | --number ) + [[ "${2}" =~ ^[0-9]+$ ]] || { + echo "${ME##*/}: error: invalid sequence number." >&2 + exit 1 + } + + [[ "${2}" -ne "$((${2} & 0x7FFFFFFFFFFFFFFF))" ]] && { + echo "${ME##*/}: error: sequence number too big." >&2 + exit 1 + } + + SEQUENCE="$((${2} & 0x7FFFFFFFFFFFFFFF))"; shift 2 + ;; + -p | --port ) + [[ "${2}" =~ ^[0-9]+$ ]] || { + echo "${ME##*/}: error: invalid Grape port number." >&2 + exit 1 + } + + [[ "$((${2} & 0xFFFF))" -eq 0 ]] && { + echo "${ME##*/}: error: Grape port number must be greater than zero." >&2 + exit 1 + } + + [[ "${2}" -ne "$((${2} & 0xFFFF))" ]] && { + echo "${ME##*/}: error: Grape port number too big." >&2 + exit 1 + } + + PORT="$((${2} & 0xFFFF))"; shift 2 + ;; + -s | --salt ) + [[ -z "${2}" ]] && { + echo "${ME##*/}: error: empty salt string." >&2 + exit 1 + } + + [[ "${#2}" -gt 64 ]] && { + echo "${ME##*/}: error: salt is too big." >&2 + exit 1 + } + + SALT="${2}"; shift 2 + ;; + -t | --tls ) + TLS='yes'; shift 1 + ;; + -- ) shift; break ;; + * ) break ;; + esac +done + + +[[ "${#}" -lt 1 ]] && { + show_help +} + +[[ -f "${HOME}/.grenache-cli/grenache-cli.conf" ]] || { + echo "${ME##*/}: error: you need to run \`grenache-keygen' first." >&2 + exit 1 +} + +exec {debug}>>/dev/null + +VALUE="${*}" + +[[ "${#VALUE}" -gt 1000 ]] && { + echo "${ME##*/}: warning: value is too big and it will be truncated." >&2 + VALUE="${VALUE:0:1000}" +} + +PROPERTIES='"v": $v' +ARGUMENTS=( + --arg 'v' "${VALUE}" +) + +[[ "x${MUTABLE}" == 'xyes' ]] && { + CHALLENGE='' + + PROPERTIES+=', "seq": $seq | tonumber, "k": $k' + ARGUMENTS+=( + --arg 'seq' "${SEQUENCE}" + --arg 'k' "$(@CAT@ ${HOME}/.grenache-cli/key.pub 2>&"${debug}")" + ) + + [[ "x${SALT}" != 'x' ]] && { + PROPERTIES+=', "salt": $salt' + ARGUMENTS+=( + --arg 'salt' "${SALT}" + ) + + CHALLENGE+="4:salt${#SALT}:${SALT}" + } + + CHALLENGE+="3:seqi${SEQUENCE}e1:v${#VALUE}:${VALUE}" + + SIGNATURE="$(${WHOAMI%/*}/grc-sign "${CHALLENGE}" \ + @SKEY_FILENO@< "${HOME}/.grenache-cli/key" \ + @PKEY_FILENO@< "${HOME}/.grenache-cli/key.pub" \ + 2>&"${debug}" + )" + + [[ "x${SIGNATURE}" = 'x' ]] && { + echo "${ME##*/}: error: cannot sign challenge buffer." >&2 + + exec {debug}>&- + exit 1 + } + + PROPERTIES+=', "sig": $sig' + ARGUMENTS+=( + --arg 'sig' "${SIGNATURE}" + ) + + [[ "x${CAS}" != 'x' ]] && { + PROPERTIES+=', "cas": $cas | tonumber' + ARGUMENTS+=( + --arg 'cas' "${CAS}" + ) + } +} + +HASH="$(@JQ@ -cMr '.' < <( + @CURL@ -qK "${HOME}/.grenache-cli/grenache-cli.conf" "http${TLS:+s}://${HOSTNAME}:${PORT}/put" < <( \ + @JQ@ -cnM \ + "${ARGUMENTS[@]}" \ + --arg 'rid' "$(@UUIDGEN@)" \ + "{ "data": { ${PROPERTIES} }, "rid": \$rid }" 2>&"${debug}" \ + ) 2>&"${debug}" \ +) 2>&"${debug}")" + +[[ "${HASH}" =~ ^[a-fA-F0-9]{40}$ ]] || { + echo "${ME##*/}: error: ${HASH:-empty response received from Grape}." >&2 + + exec {debug}>&- + exit 1 +} + +[[ "x${MUTABLE}" == 'xyes' ]] && { + CHECK="$(@SHA1SUM@ < <( \ + printf '%s%s' "$(@XXD@ -r -p < <(@CAT@ ${HOME}/.grenache-cli/key.pub 2>&"${debug}") 2>&"${debug}")" "${SALT}" 2>&"${debug}" \ + ) 2>&"${debug}")" +} || { + CHECK="$(@SHA1SUM@ < <( \ + printf '%d:%s' "${#VALUE}" "${VALUE}" 2>&"${debug}" \ + ) 2>&"${debug}")" +} + +[[ "x${HASH}" = "x${CHECK%% *}" ]] || { + echo "${ME##*/}: error: unexpected hash value." >&2 + + exec {debug}>&- + exit 1 +} + +echo "${HASH}" + +exec {debug}>&- +exit 0 diff --git a/src/io.c b/src/io.c new file mode 100644 index 0000000..361b9d9 --- /dev/null +++ b/src/io.c @@ -0,0 +1,93 @@ +/** + * @file + * This file is part of Grenache Command Line Interface. + * + * Copyright (C) 2017 Davide Scola + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include "common.h" +#include "io.h" + + +/** + * Read from a file descriptor. + * + * @param int fd + * The file descriptor. + * @param char *buffer + * The buffer to fill. + * @param size_t length + * How many bytes to read. + * + * @return int + * 0 if all the bytes have been read, -1 otherwise. + */ +int ioread(int fd, char *buffer, size_t length) { + size_t size; + size_t nread = 0; + + while (nread < length) { + if ((size = read(fd, buffer + nread, length - nread)) < 1) { + /* Return error even when EINTR. */ + return -1; + } + + nread += size; + } + + *(buffer + nread) = '\0'; + return 0; +} + +/** + * Write to a file descriptor. + * + * @param int fd + * The file descriptor. + * @param char *buffer + * The buffer to write. + * @param size_t length + * How many bytes to write. + * + * @return int + * 0 if all bytes have been written, -1 otherwise. + */ +int iowrite(int fd, char *buffer, size_t length) { + size_t size; + size_t nwrote = 0; + + while (nwrote < length) { + if ((size = write(fd, buffer + nwrote, length - nwrote)) < 1) { + /* Return error even when EINTR. */ + return -1; + } + + nwrote += size; + } + + (void) fsync(fd); + return 0; +} diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000..23e38eb --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,43 @@ +############################################################################ +# This file is part of Grenache Command Line Interface. # +# # +# Copyright (C) 2017 Davide Scola # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # +# implied. See the License for the specific language governing permissions # +# and limitations under the License. # +############################################################################ + +AM_TESTS_ENVIRONMENT = \ + export \ + AWK='$(AWK)' \ + EGREP='$(EGREP)' \ + GRENACHE_SIGN='$(abs_top_builddir)/src/grc-sign' \ + GRENACHE_VERIFY='$(abs_top_builddir)/src/grc-verify' \ + GRENACHE_KEYGEN='$(abs_top_builddir)/src/grc-keygen' \ + ; + +TESTS = \ +sign-test-vector-1.sh \ +sign-test-vector-2.sh \ +verify-test-vector-1.sh \ +verify-test-vector-2.sh + +TEST_EXTENSIONS = .sh + +SH_LOG_COMPILER = $(SHELL) +AM_SH_LOG_FLAGS = + +EXTRA_DIST = \ +sign-test-vector-1.sh.in \ +sign-test-vector-2.sh.in \ +verify-test-vector-1.sh.in \ +verify-test-vector-2.sh.in diff --git a/tests/sign-test-vector-1.sh.in b/tests/sign-test-vector-1.sh.in new file mode 100644 index 0000000..5dffae4 --- /dev/null +++ b/tests/sign-test-vector-1.sh.in @@ -0,0 +1,29 @@ +############################################################################ +# This file is part of Grenache Command Line Interface. # +# # +# Copyright (C) 2017 Davide Scola # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # +# implied. See the License for the specific language governing permissions # +# and limitations under the License. # +############################################################################ + +[ -x "${GRENACHE_SIGN}" ] || exit 77 + +SIGNATURE=$("${GRENACHE_SIGN}" '3:seqi1e1:v12:Hello World!' \ + @SKEY_FILENO@<<_EOS @PKEY_FILENO@<<_EOP 2>/dev/null +e06d3183d14159228433ed599221b80bd0a5ce8352e4bdf0262f76786ef1c74db7e7a9fea2c0eb269d61e3b38e450a22e754941ac78479d6c54e1faf6037881d +_EOS +77ff84905a91936367c01360803104f92432fcd904a43511876df5cdf3e7e548 +_EOP +) + +[ "x${SIGNATURE}" = 'x305ac8aeb6c9c151fa120f120ea2cfb923564e11552d06a5d856091e5e853cff1260d3f39e4999684aa92eb73ffd136e6f4f3ecbfda0ce53a1608ecd7ae21f01' ] && exit 0 || exit 99 diff --git a/tests/sign-test-vector-2.sh.in b/tests/sign-test-vector-2.sh.in new file mode 100644 index 0000000..59d3818 --- /dev/null +++ b/tests/sign-test-vector-2.sh.in @@ -0,0 +1,29 @@ +############################################################################ +# This file is part of Grenache Command Line Interface. # +# # +# Copyright (C) 2017 Davide Scola # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # +# implied. See the License for the specific language governing permissions # +# and limitations under the License. # +############################################################################ + +[ -x "${GRENACHE_SIGN}" ] || exit 77 + +SIGNATURE=$("${GRENACHE_SIGN}" '4:salt6:foobar3:seqi1e1:v12:Hello World!' \ + @SKEY_FILENO@<<_EOS @PKEY_FILENO@<<_EOP 2>/dev/null +e06d3183d14159228433ed599221b80bd0a5ce8352e4bdf0262f76786ef1c74db7e7a9fea2c0eb269d61e3b38e450a22e754941ac78479d6c54e1faf6037881d +_EOS +77ff84905a91936367c01360803104f92432fcd904a43511876df5cdf3e7e548 +_EOP +) + +[ "x${SIGNATURE}" = 'x6834284b6b24c3204eb2fea824d82f88883a3d95e8b4a21b8c0ded553d17d17ddf9a8a7104b1258f30bed3787e6cb896fca78c58f8e03b5f18f14951a87d9a08' ] && exit 0 || exit 99 diff --git a/tests/verify-test-vector-1.sh.in b/tests/verify-test-vector-1.sh.in new file mode 100644 index 0000000..70cb436 --- /dev/null +++ b/tests/verify-test-vector-1.sh.in @@ -0,0 +1,28 @@ +############################################################################ +# This file is part of Grenache Command Line Interface. # +# # +# Copyright (C) 2017 Davide Scola # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # +# implied. See the License for the specific language governing permissions # +# and limitations under the License. # +############################################################################ + +[ -x "${GRENACHE_VERIFY}" ] || exit 77 + +"${GRENACHE_VERIFY}" '3:seqi1e1:v12:Hello World!' \ + @PKEY_FILENO@<<_EOK @SIGN_FILENO@<<_EOS >/dev/null 2>/dev/null +77ff84905a91936367c01360803104f92432fcd904a43511876df5cdf3e7e548 +_EOK +305ac8aeb6c9c151fa120f120ea2cfb923564e11552d06a5d856091e5e853cff1260d3f39e4999684aa92eb73ffd136e6f4f3ecbfda0ce53a1608ecd7ae21f01 +_EOS + +[ "${?}" -eq 0 ] && exit 0 || exit 99 diff --git a/tests/verify-test-vector-2.sh.in b/tests/verify-test-vector-2.sh.in new file mode 100644 index 0000000..dfb001a --- /dev/null +++ b/tests/verify-test-vector-2.sh.in @@ -0,0 +1,28 @@ +############################################################################ +# This file is part of Grenache Command Line Interface. # +# # +# Copyright (C) 2017 Davide Scola # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # +# implied. See the License for the specific language governing permissions # +# and limitations under the License. # +############################################################################ + +[ -x "${GRENACHE_VERIFY}" ] || exit 77 + +"${GRENACHE_VERIFY}" '4:salt6:foobar3:seqi1e1:v12:Hello World!' \ + @PKEY_FILENO@<<_EOK @SIGN_FILENO@<<_EOS >/dev/null 2>/dev/null +77ff84905a91936367c01360803104f92432fcd904a43511876df5cdf3e7e548 +_EOK +6834284b6b24c3204eb2fea824d82f88883a3d95e8b4a21b8c0ded553d17d17ddf9a8a7104b1258f30bed3787e6cb896fca78c58f8e03b5f18f14951a87d9a08 +_EOS + +[ "${?}" -eq 0 ] && exit 0 || exit 99