fswatch-1.11.2/000755 000765 000024 00000000000 13175374112 013661 5ustar00enricostaff000000 000000 fswatch-1.11.2/man/000755 000765 000024 00000000000 13175374107 014440 5ustar00enricostaff000000 000000 fswatch-1.11.2/configure.ac000644 000765 000024 00000022512 13175367735 016166 0ustar00enricostaff000000 000000 # -*- Autoconf -*- # # Copyright (C) 2014-2017 Enrico M. Crisostomo # # 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, 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 . # # Process this file with autoconf to produce a configure script. # dnl Copyright (C) 2014-2017 Enrico M. Crisostomo AC_PREREQ([2.69]) m4_include([m4/fswatch_version.m4]) m4_include([m4/libfswatch_version.m4]) AC_INIT([fswatch], LIBFSWATCH_VERSION, [enrico.m.crisostomo@gmail.com], [], [https://github.com/emcrisostomo/fswatch]) AC_COPYRIGHT([2017 (C) Enrico M. Crisostomo]) AC_REVISION([$Revision: LIBFSWATCH_REVISION$]) AC_CONFIG_SRCDIR([fswatch/src/fswatch.cpp]) AC_CONFIG_AUX_DIR([config]) AC_CONFIG_HEADERS([libfswatch_config.h]) AC_CONFIG_FILES([Makefile]) AC_CONFIG_FILES([libfswatch/Makefile]) AC_CONFIG_FILES([libfswatch/doc/Makefile libfswatch/doc/doxygen/Makefile]) AC_CONFIG_FILES([libfswatch/src/Makefile libfswatch/src/libfswatch/Makefile]) AC_CONFIG_FILES([fswatch/Makefile fswatch/src/Makefile fswatch/doc/Makefile]) AC_CONFIG_FILES([po/Makefile.in]) AC_CONFIG_FILES([man/fswatch.7]) AC_CONFIG_MACRO_DIRS([m4]) AC_CONFIG_MACRO_DIR([m4]) # Compute the canonical target-system type variables AC_CANONICAL_TARGET TARGET_VENDOR=$target_vendor TARGET_OS=$target_os AC_SUBST([TARGET_VENDOR]) AC_SUBST([TARGET_OS]) # Initialize Automake. AM_INIT_AUTOMAKE([-Wall -Werror gnu subdir-objects std-options 1.14]) AM_SILENT_RULES([yes]) AM_PROG_AR # Configure language. AC_LANG(C++) AC_PROG_CXX([clang++ g++]) # Initialize libtool. LT_PREREQ([2.4.2]) LT_INIT AC_SUBST([LIBTOOL_DEPS]) # Configure package AC_ARG_ENABLE([docker], [AS_HELP_STRING([--enable-docker], [enable docker (default=no)])], [use_docker=${enableval}], [use_docker=no]) # OS-specific treatment AM_CONDITIONAL([OS_CYGWIN], [test "x${target_os}" = "xcygwin"]) # Set library interface version AC_SUBST([AM_LIBFSWATCH_API_VERSION], LIBFSWATCH_API_VERSION) # Checks for programs. EMC_PATH_PROG([DOXYGEN], [doxygen], [], [AC_MSG_WARN([Doxygen support disabled])], [doxygen path]) AM_CONDITIONAL([HAVE_DOXYGEN], [test -n "${DOXYGEN}"]) AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([libfswatch/doc/doxygen/Doxyfile])]) # Initialize gettext. AM_GNU_GETTEXT([external]) AM_GNU_GETTEXT_VERSION([0.19.4]) AM_CONDITIONAL([USE_NLS], [test "x${USE_NLS}" = "xyes"]) # Configure C++ compiler AX_CXX_COMPILE_STDCXX_11 AX_CXXFLAGS_WARN_ALL # Checks for libraries. AC_CHECK_LIB([pthread], [pthread_create]) # Checks for header files. AC_CHECK_HEADERS([cstdlib], [], [AC_MSG_ERROR([A required header file is missing.])]) AC_CHECK_HEADERS([unistd.h], [], [AC_MSG_ERROR([A required header file is missing.])]) AC_CHECK_HEADERS([fcntl.h], [], [AC_MSG_ERROR([A required header file is missing.])]) # Check for optional header files. AC_CHECK_HEADERS([unordered_map unordered_set]) AC_CHECK_HEADERS([getopt.h]) # Check for optional header files required to support OS-specific monitors # Check for OS X FSEvents. FSEvents added file events in a later release, so # this check must be performed separately. AC_CHECK_HEADERS([CoreServices/CoreServices.h]) AS_VAR_IF([ac_cv_header_CoreServices_CoreServices_h], ["yes"], [AX_FSEVENTS_HAVE_FILE_EVENTS]) AM_CONDITIONAL([USE_FSEVENTS], [test "x${ax_cv_fsevents_have_file_events}" = "xyes"]) # Check for kqueue: if the sys/event.h header is present, perform a check for # the kqueue and kevent functions. AC_CHECK_HEADERS([sys/event.h]) AS_VAR_IF([ac_cv_header_sys_event_h], ["yes"], [ AS_VAR_SET([KQUEUE_AVAILABLE], ["yes"]) AC_CHECK_DECLS( [kqueue, kevent], [], [AS_VAR_SET([KQUEUE_AVAILABLE], ["no"])], [ AC_INCLUDES_DEFAULT [#include ] [#include ] [#include ] ] ) AC_CHECK_LIB([c], [kqueue], [], [AS_VAR_SET([KQUEUE_AVAILABLE], ["no"])]) ]) AM_CONDITIONAL([USE_KQUEUE], [test "x${KQUEUE_AVAILABLE}" = "xyes"]) # Check for Solaris/Illumos File Events Notification API. AC_CHECK_HEADERS([port.h]) AS_VAR_IF([ac_cv_header_port_h], ["yes"], [ AS_VAR_SET([FEN_AVAILABLE], ["yes"]) AC_CHECK_DECLS( [port_create], [], [AS_VAR_SET([FEN_AVAILABLE], ["no"])], [ AC_INCLUDES_DEFAULT [#include ] ] ) AC_CHECK_LIB([c], [port_create], [], [AS_VAR_SET([FEN_AVAILABLE], ["no"])]) ]) AM_CONDITIONAL([USE_FEN], [test "x${FEN_AVAILABLE}" = "xyes"]) # Check for Linux inotify. AC_CHECK_HEADERS([sys/inotify.h]) AS_VAR_IF([ac_cv_header_sys_inotify_h], ["yes"], [ AS_VAR_SET([INOTIFY_AVAILABLE], ["yes"]) AC_CHECK_DECLS( [inotify_init, inotify_add_watch, inotify_rm_watch], [], [AS_VAR_SET([INOTIFY_AVAILABLE], ["no"])], [ AC_INCLUDES_DEFAULT [#include ] ] ) AC_CHECK_LIB([c], [inotify_init], [], [AS_VAR_SET([INOTIFY_AVAILABLE], ["no"])]) ]) AM_CONDITIONAL([USE_INOTIFY], [test "x${INOTIFY_AVAILABLE}" = "xyes"]) # Check for Microsoft Windows directory change notification API AS_VAR_SET([WINDOWS_AVAILABLE], ["yes"]) AC_CHECK_HEADERS([windows.h], [], [AS_VAR_SET([WINDOWS_AVAILABLE], ["no"])]) AS_VAR_IF([WINDOWS_AVAILABLE], ["yes"], [ AC_CHECK_DECLS( [FindFirstChangeNotification, FindNextChangeNotification, FindCloseChangeNotification, WaitForSingleObject, ReadDirectoryChangesW], [], [AS_VAR_SET([WINDOWS_AVAILABLE], ["no"])], [ AC_INCLUDES_DEFAULT [#include ] ] ) ]) AM_CONDITIONAL([USE_WINDOWS], [test "x${WINDOWS_AVAILABLE}" = "xyes"]) AS_VAR_IF([WINDOWS_AVAILABLE], ["yes"], [AC_DEFINE([HAVE_WINDOWS], [1], [Windows API present.])]) # Check for CygWin only if Windows is available AS_VAR_IF([WINDOWS_AVAILABLE], ["yes"], [ AS_VAR_SET([CYGWIN_AVAILABLE], ["yes"]) AC_CHECK_HEADERS([sys/cygwin.h], [], [AS_VAR_SET([CYGWIN_AVAILABLE], ["no"])]) AS_VAR_IF([CYGWIN_AVAILABLE], ["yes"], [ AC_CHECK_DECLS( [cygwin_create_path], [], [AS_VAR_SET([CYGWIN_AVAILABLE], ["no"])], [ AC_INCLUDES_DEFAULT [#include ] ] ) ]) ]) AM_CONDITIONAL([USE_CYGWIN], [test "x${CYGWIN_AVAILABLE}" = "xyes"]) AS_VAR_IF([CYGWIN_AVAILABLE], ["yes"], [AC_DEFINE([HAVE_CYGWIN], [1], [CygWin API present.])]) # Some compilers declare to conform to C++11 but the library does not. # These OS X versions are known to miss at least the listed headers: # - 10.6 Snow Leopard: mutex, atomic # - 10.7 Lion: mutex, atomic # - 10.8 Mountain Lion: mutex, atomic # Let's check for and skip multi-threading code if not found. AC_CHECK_HEADER([mutex]) if test "x${ac_cv_header_mutex}" = "xyes" ; then AC_DEFINE([HAVE_CXX_MUTEX], [1], [Define if is available.]) else AC_MSG_WARN([AC_PACKAGE_NAME is not thread-safe because required C++11 library classes are not available.].) fi AC_CHECK_HEADER([atomic]) AS_VAR_IF([ac_cv_header_atomic], ["yes"], [AC_DEFINE([HAVE_CXX_ATOMIC], [1], [Define if is available.])], [AC_MSG_WARN([ unavailable: some functionalities will not be built.])]) # Checks for typedefs, structures, and compiler characteristics. AC_CHECK_HEADER_STDBOOL AC_TYPE_SIZE_T AC_TYPE_SSIZE_T AC_TYPE_UINT32_T AC_TYPE_MODE_T AC_CHECK_MEMBERS([struct stat.st_mtime], [], [], [ AC_INCLUDES_DEFAULT #include ]) AC_CHECK_MEMBERS([struct stat.st_mtimespec], [], [], [ AC_INCLUDES_DEFAULT #include ]) AC_CHECK_TYPE([std::unique_ptr], [AC_DEFINE([HAVE_CXX_UNIQUE_PTR], [1], [Define if std::unique_ptr in is available.])], [], [[#include ]]) # Checks for library functions. AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK AC_CHECK_FUNCS([modf], [], [AC_MSG_ERROR([The modf function cannot be found.])]) AC_CHECK_FUNCS([realpath], [], [AC_MSG_ERROR([The realpath function cannot be found.])]) AC_CHECK_FUNCS([regcomp], [], [AC_MSG_ERROR([The regcomp function cannot be found.])]) AC_CHECK_FUNCS([select], [], [AC_MSG_ERROR([The select function cannot be found.])]) AC_FUNC_STRTOD AC_CHECK_FUNCS([atexit], [], [AC_MSG_ERROR([The atexit function cannot be found.])]) AC_CHECK_FUNCS([setlocale], [], [AC_MSG_ERROR([The setlocale function cannot be found.])]) AX_CXX_HAVE_THREAD_LOCAL AS_VAR_IF( [ax_cv_cxx_have_thread_local], ["yes"], [], [AC_MSG_WARN([The C API of AC_PACKAGE_NAME is not thread-safe because the current combination of compiler and libraries do not support the thread_local storage specifier.])]) # Check for optional library functions. AS_VAR_IF([ac_cv_header_getopt_h], ["yes"], [AC_CHECK_FUNCS([getopt_long])]) # Create Dockerfile for test build containers AS_VAR_IF([use_docker], [yes], [ AX_GIT_CURRENT_BRANCH AC_CONFIG_FILES([docker/alpine/Dockerfile]) AC_CONFIG_FILES([docker/debian9/Dockerfile]) ], []) # Variables used in man files. MAN_DATE=$(date +'%B %d, %Y') FSWATCH=${PACKAGE_NAME} MAN_BUG_REPORT=${PACKAGE_BUGREPORT} AC_SUBST([MAN_DATE]) AC_SUBST([FSWATCH]) AC_SUBST([MAN_BUG_REPORT]) AC_OUTPUT fswatch-1.11.2/docker/000755 000765 000024 00000000000 13175374107 015134 5ustar00enricostaff000000 000000 fswatch-1.11.2/INSTALL000644 000765 000024 00000036614 13175374062 014730 0ustar00enricostaff000000 000000 Installation Instructions ************************* Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software Foundation, Inc. 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 warranty of any kind. Basic Installation ================== Briefly, the shell command './configure && make && make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the 'README' file for instructions specific to this package. Some packages provide this 'INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The 'configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a 'Makefile' in each directory of the package. It may also create one or more '.h' files containing system-dependent definitions. Finally, it creates a shell script 'config.status' that you can run in the future to recreate the current configuration, and a file 'config.log' containing compiler output (useful mainly for debugging 'configure'). It can also use an optional file (typically called 'config.cache' and enabled with '--cache-file=config.cache' or simply '-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how 'configure' could check whether to do them, and mail diffs or instructions to the address given in the 'README' so they can be considered for the next release. If you are using the cache, and at some point 'config.cache' contains results you don't want to keep, you may remove or edit it. The file 'configure.ac' (or 'configure.in') is used to create 'configure' by a program called 'autoconf'. You need 'configure.ac' if you want to change it or regenerate 'configure' using a newer version of 'autoconf'. The simplest way to compile this package is: 1. 'cd' to the directory containing the package's source code and type './configure' to configure the package for your system. Running 'configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type 'make' to compile the package. 3. Optionally, type 'make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type 'make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the 'make install' phase executed with root privileges. 5. Optionally, type 'make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior 'make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing 'make clean'. To also remove the files that 'configure' created (so you can compile the package for a different kind of computer), type 'make distclean'. There is also a 'make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type 'make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide 'make distcheck', which can by used by developers to test that all other targets like 'make install' and 'make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the 'configure' script does not know about. Run './configure --help' for details on some of the pertinent environment variables. You can give 'configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU 'make'. 'cd' to the directory where you want the object files and executables to go and run the 'configure' script. 'configure' automatically checks for the source code in the directory that 'configure' is in and in '..'. This is known as a "VPATH" build. With a non-GNU 'make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use 'make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple '-arch' options to the compiler but only a single '-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the 'lipo' tool if you have problems. Installation Names ================== By default, 'make install' installs the package's commands under '/usr/local/bin', include files under '/usr/local/include', etc. You can specify an installation prefix other than '/usr/local' by giving 'configure' the option '--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option '--exec-prefix=PREFIX' to 'configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like '--bindir=DIR' to specify different values for particular kinds of files. Run 'configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of '${prefix}', so that specifying just '--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to 'configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the 'make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, 'make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of '${prefix}'. Any directories that were specified during 'configure', but not in terms of '${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the 'DESTDIR' variable. For example, 'make install DESTDIR=/alternate/directory' will prepend '/alternate/directory' before all installation names. The approach of 'DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of '${prefix}' at 'configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving 'configure' the option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. Some packages pay attention to '--enable-FEATURE' options to 'configure', where FEATURE indicates an optional part of the package. They may also pay attention to '--with-PACKAGE' options, where PACKAGE is something like 'gnu-as' or 'x' (for the X Window System). The 'README' should mention any '--enable-' and '--with-' options that the package recognizes. For packages that use the X Window System, 'configure' can usually find the X include and library files automatically, but if it doesn't, you can use the 'configure' options '--x-includes=DIR' and '--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of 'make' will be. For these packages, running './configure --enable-silent-rules' sets the default to minimal output, which can be overridden with 'make V=1'; while running './configure --disable-silent-rules' sets the default to verbose, which can be overridden with 'make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. HP-UX 'make' updates targets which have the same time stamps as their prerequisites, which makes it generally unusable when shipped generated files such as 'configure' are involved. Use GNU 'make' instead. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its '' header file. The option '-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put '/usr/ucb' early in your 'PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in '/usr/bin'. So, if you need '/usr/ucb' in your 'PATH', put it _after_ '/usr/bin'. On Haiku, software installed for all users goes in '/boot/common', not '/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features 'configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, 'configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the '--build=TYPE' option. TYPE can either be a short name for the system type, such as 'sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file 'config.sub' for the possible values of each field. If 'config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option '--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with '--host=TYPE'. Sharing Defaults ================ If you want to set default values for 'configure' scripts to share, you can create a site shell script called 'config.site' that gives default values for variables like 'CC', 'cache_file', and 'prefix'. 'configure' looks for 'PREFIX/share/config.site' if it exists, then 'PREFIX/etc/config.site' if it exists. Or, you can set the 'CONFIG_SITE' environment variable to the location of the site script. A warning: not all 'configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to 'configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the 'configure' command line, using 'VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified 'gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an Autoconf limitation. Until the limitation is lifted, you can use this workaround: CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash 'configure' Invocation ====================== 'configure' recognizes the following options to control how it operates. '--help' '-h' Print a summary of all of the options to 'configure', and exit. '--help=short' '--help=recursive' Print a summary of the options unique to this package's 'configure', and exit. The 'short' variant lists options used only in the top level, while the 'recursive' variant lists options also present in any nested packages. '--version' '-V' Print the version of Autoconf used to generate the 'configure' script, and exit. '--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally 'config.cache'. FILE defaults to '/dev/null' to disable caching. '--config-cache' '-C' Alias for '--cache-file=config.cache'. '--quiet' '--silent' '-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to '/dev/null' (any error messages will still be shown). '--srcdir=DIR' Look for the package's source code in directory DIR. Usually 'configure' can determine that directory automatically. '--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. '--no-create' '-n' Run the configure checks, but stop before creating any output files. 'configure' also accepts some other, not widely useful, options. Run 'configure --help' for more details. fswatch-1.11.2/NEWS.libfswatch000644 000765 000024 00000011236 13175372771 016521 0ustar00enricostaff000000 000000 NEWS **** New in 1.11.2: * Issue 182: Generate a single message catalog for both fswatch and libfswatch. New in 1.11.1: * Issue 182: Remove mandatory dependency to git. New in 1.11.0: * Issue 181: Make gettext an optional dependency. New in 1.10.0: * Add Doxygen documentation. * Issue 60: Add function to load filters from a file. * Issue 137: Deadlock on C function fsw_destroy_session if fsw_start_monitor is called. * Modify fsw_destroy_session function not to destroy a session that has a running monitor. * Issue 143: Add fsw_stop_monitor to the C API. New in 1.9.3: * Use C header names in C headers instead of C++. * Explicitly use the enum keyword when referring to enum types in C headers. * Remove default argument values from C headers. New in 1.9.2: * Issue 118: v. 1.9.0 breaks the -1 option. New in 1.9.1: * libfswatch API version 7:0:1. New in 1.9.0: * Update monitor::~monitor() to invoke monitor::stop(), close resources in monitor::on_stop(). * Issue 84: Add the possibility of scheduling a periodic idle event. * Run a separate thread to fire idle events. * Improve logging. * Do not fail if blocking calls are interrupted by a signal. * Issue 114: fswatch does not track newly created directories recursively when using the inotify monitor. * The AX_CXX_COMPILE_STDCXX macro was patched so that the switches it adds to the compiler are added to the preprocessor configuration as well. New in 1.8.0: * Unsupported CMake files and CLion project files are included as a courtesy. * Parts of the code have been refactored to use move semantics. * Fixed a bug in fsw::monitor_factory::create_monitor(). * Refactor fsw::monitor_factory to dynamically create the default monitor using the factory registration information. * Generate documentation using Doxygen. * Texinfo documentation has been obsoleted by Doxygen documentation and has been removed. * Add fsw::monitor::stop() function to allow for cooperative monitor shutdown. * Implement fsw::monitor::stop() on all available monitors. * Fixed a but in the Solaris/Illumos monitor that prevented it to correctly detect the ETIME status code upon waiting for events. New in 1.7.0: * Issue 35: Support Solaris/Illumos File Events Notification API. * Issue 98: A monitor can be requested to watch directories only during a recursive scan. * Issue 99: A monitor using the File Events Notification API of the Solaris/Illumos kernel has been added. * Issue 101: Add flag to watch file accesses. New in 1.6.1: * Texinfo documentation now includes @dircategory and @direntry tags to be compatible with install-info. New in 1.6.0: * libfswatch can now be built on Microsoft Windows using Cygwin. * A monitor for Microsoft Windows has been added. * libfswatch can report monitor buffer overflows (which cannot be avoided with certain monitors) as regular events for callers to recover gracefully. * Monitor can be customized by passing monitor-specific configuration properties. New in 1.5.1: * Fixes Issue 91: Can't compile fswatch 1.5.0 on FreeBSD 9.3-RELEASE. New in 1.5.0: * Fix issue 46: Allow filtering by event type. * Fix issue 83: Callback invocation should be moved into fsw::monitor. New in 1.4.7: * Provide a way to pass context data to the C API monitor callback. New in 1.4.6: * Fix issue 74: Assertion failed on fsw_destroy_session. New in 1.4.5.3: * Fix issue 67: 100% CPU usage while using libfswatch. This issue only affects the inotify monitor, available only on Linux. New in 1.4.5.2: * Fix issue 66: Exclude items with poll_monitor not considered. New in 1.4.4: * Localize fswatch and libfswatch using GNU gettext. * Add Italian (it) localization. * Add Spanish (es) localization. New in 1.4.3: * Add Texinfo documentation. * libfswatch API is now versioned. * Improved Autoconf checks. * The inotify monitor now waits for events and honours the latency settings. * Automaticaly generate the ChangeLog using Git. * Update autogen.sh to honour some commonly used environment variables. New in 1.4.2: * The inotify monitor now provides the same functionality provided by all the other monitors. Recursive directory monitoring is now implemented. * Version and revision is now determined dynamically from Git by ancillary scripts invoked by the GNU Build System. New in 1.4.0: * The libfswatch library has been added with bindings for C and C++. * Move monitors to separate library. * Provide a libtool-configured library exposing the functionality of fswatch monitors. * Provide C and C++ headers and bindings. fswatch-1.11.2/README.codestyle000644 000765 000024 00000004732 13174733730 016545 0ustar00enricostaff000000 000000 README.codestyle ================ The indent style used by `fswatch` is a custom Allman (BSD) style. The code is formatted using NetBeans with the following format settings: Indents Indent Size = 2 Expand Tabs to Spaces = true Tab Size = 2 Statement Continuation = 2 Constructor Continuation = 2 Preprocessor Directive = Preprocessor # at Start Line = true Indent Namespaces = true Indent Case Statements = false Absolute Label Indentation = true Indent Visibility = None Keep Extra Spaces = false Braces Placement Namespace Declaration = New Line Class Declaration = New Line Function Declaration = New Line Ignore Empty Function = false Lambda = New Line "switch" statement = New Line Other = New Line Multiline Alignment Function Parameters = true Function Call Arguments = true Array Initializer = false "for" Statement = true "if" Condition = true "while" Condition = true Other Parenthesis = false New Line Function Name = false "catch" = true "else" = true "while" = true Spaces Before Keywords "catch" = true "else" = true "while" = true Spaces Before Parentheses Function Declaration = false Function Call = false "catch" = true "for" = true "if" = true "switch" = true "while" = true Other Keywords = true Spaces Around Operators Assignment Operators = true Binary Operators = true Ternary Operators = true Unary Operators = false Spaces Before Left Braces Class Declaration = true Function Declaration = true Lambda = true Array Initializer = false "catch" = true "do" = true "else" = true "for" = true "if" = true "switch" = true "try" = true "while" = true Spaces Within Parentheses Function Declaration = false Function Call = false Braces = false Parentheses = false "catch" = false "for" = false "if" = false "switch" = false Type Cast = false "while" = false Other Spaces Before Comma = false After Comma = true Before Semicolon = false After Semicolon = true Before Colon = true After Colon = true After Type Cast = true After operator Keyword = false Blank Lines Before Class = 1 After Class Header = 0 Before Function = 1 Other Add Leading Star in = true Toggle block comment = false Insert 'inline' keyword = false fswatch-1.11.2/README.windows000644 000765 000024 00000005427 13174733730 016246 0ustar00enricostaff000000 000000 README.windows ************** Introduction ============ This file describes the steps required to build fswatch on Windows. fswatch was born as a POSIX application and the Windows monitor has been developed trying to reduce the dependencies on the Windows API at a minimum. To fulfill this goal, a dependency to Cygwin has been introduced. Windows has historically provided multiple versions of the same API for single byte and multibyte character sets. We have decided to only support the multibyte API: the Windows monitor will thus not build on Windows system supporting only the single-byte APIs. In this case, the only available monitor on the Windows OS will be the poll monitor. Cygwin ====== Cygwin is a required dependency and must be installed to provide the toolchain and the libraries required by fswatch. The current Cygwin distribution can be downloaded at: https://cygwin.com Cygwin is a modular environment and the following componentes are required to successfully build fswatch: * GNU GCC C++ compiler. * GNU Autoconf. * GNU Automake. * GNU Autoconf. * GNU libtool. The following are optional: * GNU gettext (optional) Windows SDK =========== The Windows SDK is required to successfully build fswatch since it ships the headers and the libraries required to build Windows applications. Please, consult your Windows documentation to get the latest SDK for your platform. GNU Build System ================ For further instruction on building the GNU Build System from scratch, please check the README.gnu-build-system file. Localization and gettext ======================== fswatch is localizable and locale support requires GNU gettext to be available at build time. Depending on gettext installation path, configure may not be able to find or libintl. In this case, you will need to instruct configure about their location: $ CPPFLAGS="-I/path/to/include" LDFLAGS="-L/path/to/lib" ./configure If configure detects that gettext is available, you will find a message such as: checking whether to use NLS... yes or, which is equivalent, config.h will contain the following definition: #define ENABLE_NLS 1 ----- Copyright (c) 2014-2015 Enrico M. Crisostomo 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, 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 . fswatch-1.11.2/README.solaris000644 000765 000024 00000004117 13174733730 016223 0ustar00enricostaff000000 000000 README.solaris ************** Introduction ============ This file describes the steps required to build this bundle on a supported system running the Solaris or the Illumos kernel. See README for more information about the tested configurations. When Illumos was created, the Solaris kernel already included the File Events Notification API. Hence, the fen_monitor should be available on any system running Solaris (> 10) or an Illumos kernel. Additionally, a Solaris/Illumos system should be able to use the following monitors: * inotify_monitor, depending on the kernel version. * poll_monitor. So far, however, the author has only tested this release on SmartOS. Feedback on different Solaris/Illumos systems is much appreciated and will benefit other users as well. Installation ============ See the INSTALL file for detailed information about how to configure and install fswatch. fswatch is a C++ program and a C++ compiler compliant with the C++11 standard is required to compile it. Check the documentation of your distribution to learn how to install the required software. The configure script enforces an ordered compiler search list and clang++ will be used first if available. If you do not like this choice and wish to use another compiler set the value of the CXX environment variable to the name of your compiler binary. If, for example, you wish to use the g++ compiler, then use this command to configure the build: $ ./configure CXX=g++ ----- Copyright (c) 2015 Enrico M. Crisostomo 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, 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 .fswatch-1.11.2/ChangeLog000644 000765 000024 00000147505 13175374113 015450 0ustar00enricostaff000000 000000 ChangeLog ********* This file has been automatically generated using the following command: $ git log --oneline --decorate 2875be8 (HEAD -> master, origin/master, origin/HEAD) Update history 16ecbc0 Update NEWS files c7b0f7b Update po and pot files 1240a71 Bump 1.11.2 480bdac Update po files aa2a32f Update po and pot files 645711c Reconfigure output files after moving po directories cc65d61 Remove po subdir from fswatch and libfswatch Makefiles f7012b5 Update po/Makevars after location change 24a81fb Move fswatch po directory to package root 6a1893d Remove libfswatch/po d75e89a Merge po and pot files 0e9261a Merge POTFILES.in abfe0cc (tag: 1.11.1) Update po and pot files a810f46 Bump 1.11.1 36f01b8 Refactor and substitute manual path tests with EMC_PATH_PROG e412c4e Add option to enable the generation of docker files for test containers 05823d3 Refactor after changes to EMC_PATH_PROG 08e9932 Refactor to avoid using magic values when checking the result of AC_PATH_PROG 13a962b Reformat 07fd8ae Refactor ax_git_current_branch to use m4sh 666077e (tag: 1.11.0) Update po and pot files 23c94ca Update change history 3a93035 Update the manual to update the behaviour of the --event option 2c0c8f3 Refactor to use constants 4fa5249 Build documentation and copy it to the dist directory 97d2cc4 Update the build-from-scratch.sh 55c0672 Add build-from-scratch.sh 9033554 Update gettext.h 0659c70 Update NEWS 092f15b Merge branch 'master' into release/1.11.0 9678505 Merge branch 'master' into feature/issue-174-event-with-bitmask 1725945 Update README a9591d2 Bump 1.11.0 049cb20 Only use a COPYING file for license 014c20d Copy COPYING over LICENSE 8b3ae3f Link LICENSE to COPYING eeb457a Update CONTRIBUTING.md to reflect changes to the branch structure 3ff3806 Merge branch 'develop' d97954e Recursively build the po subdirectory only if NLS is enabled f116447 Distribute ABOUT-NLS only if NLS is enabled f0cb6dd Add an automake conditional to check whether NLS is enabled 659a2a4 Use one dist_doc_DATA statement per file 9166e53 Reorder options in usage message 0fa6d20 Bump copyright year 7040d86 Merge branch 'master' of github.com:emcrisostomo/fswatch into feature/issue-174-event-with-bitmask 3a2510a Add copy constructor and assignment operator 88cacb8 Merge pull request #159 from nickmccurdy/hotfix-wording 4b35480 Overload --event to accept a bitmask d655777 Add array with all event types 9397784 Update code style settings 3ada000 Require C++11 using the new CMAKE_CXX_STANDARD instead of CMAKE_CXX_FLAGS f52783e Define HAVE_CONFIG_H in each project 93f1dbf Bump minimum cmake to 3.8 cd657a2 Merge branch 'master' into develop dcf019f Add GNU gettext to the list of the development dependencies 7524f19 Update pot files 85ab057 Update ax_ macros a496e8b Update ax macros c91b5b1 Merge tag '1.10.1' into develop 529c7e8 (tag: 1.10.1) Merge branch 'hotfix/1.10.1' f70fe73 Update Texinfo documentation 42fa6b7 Bump 1.11.0-develop a4c426e Merge tag '1.10.0' into develop bd58735 (tag: 1.10.0) Merge branch 'release/1.10.0' ca955e8 Update NEWS cde73f1 Rename debian-9 to debian9 56dfdf9 Update .gitignore to add debian-9/Dockerfile 61737a1 Use debian:9 when testing debian builds b83d832 Update INSTALL dfd42de Update man page description a4063de Fix wording for monitor list 89ad43f Update NEWS c70394c Update NEWS files 7762f80 Strengthen memory ordering 4825273 Fix build-images.sh 6bbbccf Refactor docker files to get git branch name from the configuration 2fb13f6 Set branch to HEAD if detached 9694a86 Clean up docker files a2b0079 Get the current git branch 636a22e Add M4 macro to get the current git branch 1e2a2a3 Build fswatch on Docker images 2436e04 Merge branch 'release/1.10.0' of github.com:emcrisostomo/fswatch into release/1.10.0 d440a3d Clean up Alpine Dockerfile e11d16b Merge pull request #145 from agaida/release/1.10.0 610628b Merge pull request #147 from agaida/fix-license 57da3cd Merge pull request #148 from agaida/fix-manpage 8ff8eff Fix manpage generation 09ce586 Fix license text 804ab6f Added basic .gitattributes to prevent the export of: - .gitignore - .gitattributes - .idea/ - .travis.yml - .*~ 177614f Update Doxygen documentation 22d0a48 Add cmake-build-debug/ to .gitignore 7f768b6 Bump libfswatch 9:0:0 f4ee4fd Refactor code after FSW_HANDLE redefinition cd15c60 Update FSW_HANDLE to be FSW_SESSION * bb38ff9 Add fswatch_test binary to .gitignore ba5a6e8 Add test compilation of a C program against the libfswatch library ae48ea8 Update NEWS files 80db165 Add fsw_stop_monitor function to stop a running monitor. A session with a running monitor cannot be destroyed any longer. 28d1134 Update include directory after package refactoring e70cfc6 Update po and pot files 9bfac0f Fix index 6ad0abb Update version history in Texinfo documentation 5181aa2 Update Texinfo documentation 93c61a3 Bump 1.10.0 2f2763e Merge branch 'feature/merge-projects' into develop 9c7cfd5 Update README.md 05b9874 Update AUTHORS.libfswatch 8b2c038 Remove libtool dependencies from child Makefile fee0ede Remove dist hook from Makefile in child project b8042ab Remove ChangeLog, INSTALL and README from child project 03732fc Update po and pot files 88eaf0d Rename root package to fswatch 26584da Rename pot files to fswatch.pot b680da5 Move libfswatch README files to the project root a0af954 Update copyright e014579 Update po and pot files 5061858 Add docker-images target to build Docker images f8420bd Add script to build Docker images f474168 Fix paths in CMakeLists.txt after refactoring fb332f6 Fix paths in .gitignore after refactoring e5433e6 Fix paths in Doxyfile.in after refactoring cd751ff Update po and pot files 6395745 Fix paths in po/POTFILES.in after refactoring a5a2cba Fix paths in po/Makevars after refactoring d578464 Update fswatch Makefile to recurse into po and doc subdirs 8282c5b Update paths in POTFILES.in after refactoring 0ff74ee Fix .gitignore paths after refactoring 8a2a1e9 Fix config header path after refactoring 7f8ba12 Update paths in .gitignore c44f474 Update po/Makevars a23fc5f Add fswatch/Makefile.am f2a21e1 Fix paths in configure.ac after refactoring 85152bf Update root Makefile b18e538 Merge libfswatch's and fswatch's configure.ac bd723a6 Consolidate M4 macros into a shared directory afc2c9d Move doc and po to fswatch 52d14e1 Move fswatch to root 9f8403b Move fswatch sources to src/fswatch/src 2883062 Unlock session mutex before starting the monitor 7c9f2e6 Refactor to improve readability fc6402a Add Docker files for Alpine and Debian Linux 100b075 Merge branch 'hotfix/1.9.3' into develop 11ebf02 (tag: 1.9.3) Merge branch 'hotfix/1.9.3' c1d9895 Update po and pot files 57084d1 Update NEWS 71c1c3d Remove stale comment a08d5f1 Merge pull request #124 from johndid/hotfix/1.9.3 f9222ae Fixed headers for c compilation 28b8998 Update NEWS. de24a48 Substitute C++ header names with C names in C headers. 895b901 Bump 1.9.3. c556ebd Move filters parsed from file into filter vector instead of copying them. a1e992a Pass const string by reference. b75d793 Rewrap. 0be9d5c Update po and pot files. 2122224 Set correct case sensitivity. 7b25e7c Handle invalid_argument exceptions in main(). 3b7ff7b Improve exception message when filter file cannot be opened. 8d9cd5f Add option to load filters from files. 3d737cb Provide a default value for the error handler of the filter parser. 69b5a24 Add doxygen documentation. 68dd90f Inline static functions. fcc32cb Read filters from file. 3abd16a Merge tag '1.9.2' into develop a79113a (tag: 1.9.2) Merge branch 'hotfix/1.9.2' aed6b7a Update texinfo documentation. dfed4fe Bump libtool 8:0:2. e7d2e97 Update po and pot files. c422884 Update news. a320837 Add a mutex to protect the notify_events() method. bc371e2 Fix missing #ifdef. 22fbeb1 Invoke close_monitor() instead of exit() after processing the first events and -1 was used. ba0fa1a Bump 1.9.2. 83054a2 Merge tag '1.9.1' into develop cb046d2 (tag: 1.9.1) Merge branch 'hotfix/1.9.1' 160875f Update PO and POT files for 1.9.1. 72b981a Update Texinfo documentation. 75c7769 Update NEWS. d3af2e5 Bump libfswatch API version to 7:0:1. 933aafc Bump 1.9.1. ec332db Bump 1.10.0-develop. ef7260c Bump 1.10.0.develop. 1bbb077 Merge tag '1.9.0' into develop be03582 (tag: 1.9.0) Merge branch 'release/1.9.0' c364399 Update NEWS. 8d5c3a8 Update documentation. a00bdbe Update copyright statement for 1.9.0. e1ffb0a Update PO and POT files for 1.9.0. 153284b Update CLion project files. be7ae7c Update README for 1.9.0. 834853a Update README for 1.9.0. fffd2fd Update copyright on configure.ac for 1.9.0. 1889524 Update NEWS for 1.9.0. 6bd8d7c Update Texinfo documentation for 1.9.0. 1a67f25 Bump 1.9.0. 8091f20 Update ax_cxx_compile_stdcxx series of macro. f114b2a Update PO and POT files. b2acd97 Do not print an error message if port_get() is interrupted by a signal. be4f319 Issue 114: fswatch (inotify) does not track newly created dirs recursively 26b3400 Link against pthread if available. 7a2accf Update. 8f219c3 Move variable into inner scope. ff14906 Check for support. 78bb204 Check for support. 2e93863 Add missing header: . a9911f4 Update macros to check for C++11 support and set the correct compiler flags. 1bd5bba Add check for the availability of std::atomic. bbe5d83 Merge branch 'feature/inactivity-notification' into develop 75b6325 Add --fire-idle-events option to fswatch. 59dbc70 Add fsw::monitor::set_fire_idle_event() to enable idle events. 2945640 Do not exit() from signal handler: stop monitor and wait for it to stop. 8b5c6f7 Update inactivity callback to sleep a maximum time of 2 seconds. 21a5942 Refactor inactivity callback and make it sleep 10% more than latency. 394b31c Do not fail if kevent() is interrupted by a signal. 0222cec Move inactivity thread to fsw::monitor and refactor fsw::fsevents_monitor. 16ffbe7 Refactor to use monitor::notify_events instead of using a mutex of its own. 33b1e93 Protect access to monitor::notify_events() using monitor::run_mutex. 8a7a1b2 Improve logging. 98699a3 Run a separate thread to forge an inactivity event. 650f4b9 Close resources in monitor::on_stop() and clean up destructor. d7aea67 Update monitor::~monitor() to invoke monitor::stop(). e7cab20 Travis CI: Use clang++-3.7. 3f8e13b Travis CI: Use Trusty while building and required sudo. 3e03d8b Enable builds on develop. ab4e5b7 Only build master branch on Travis CI. 58e5e74 Bump 1.9.0-develop. 10f6437 Merge tag '1.8.0' into develop cda2487 (tag: 1.8.0) Merge branch 'release/1.8.0' 21db940 Remove texinfo documentation of libfswatch (obsoleted by Doxygen documentation). d9bd682 Do not manually distribute config.rpath. 91f1629 Update po and pot files. 1f41249 Include doxygen subdirectory in SUBDIRS so that Makefile.am is distributed. d2fb73d Bump 1.8.0 b42c928 Update NEWS. e73991d Update copyright statement. 796c563 Fix missing header. 6679f6d Update documentation and remove unused status codes. fc6fea1 Merge branch 'feature/doxygen-support' into develop 7120d4d Update documentation. 3b4b600 Update documentation. bc6938b Invoke the Doxygen generation target during all. Do not descend into the doxygen directory during normal builds. 0c6a1c7 Do not execute doxygen targets during all. 357ce6d Update documentation. 32c2823 Update documentation. 3ac437f Update documentation. fc42131 Remove libfswatch_mem.{h, cpp}. 4a9b516 Add Doxygen documentation for cmonitor.h. 5c82e6d Update documentation. 2b5b75a Update documentation. c839fc3 Update documentation. 63e04ec Update documentation. 0911cac Move constructor parameters instead of copy-constructing them. 620844d Add example to Doxygen C++ API page. e5556a1 Add "C API" Doxygen page. dd0b13d Update documentation. c175b60 Generate Doxygen documentation from libfswatch_types.h. fea506a Update documentation. 42234fe Add Path Filter page to Doxygen documentation. 537596f Generate Doxygen documentation from filter.hpp. 914f3c7 Format code using Markdown syntax. 99f3538 Add ignore pattern for Doxygen's output directories: html/ and latex/. 8b906e9 Update documentation. c4eeea2 Update the changelog page. 36553ea Generate Doxygen documentation from event.hpp. 2ce4c8c Generate Doxygen documentation from cfilter.h. 693c2da Update documentation. f991368 Generate Doxygen documentation from libfswatch.h. d156773 Generate Doxygen documentation from libfswatch_log.h. ff5b5f0 Add a history page containing an API changelog. d754d93 Update documentation. 7ffbb7e Merge branch 'develop' into feature/doxygen-support abaa9aa Refine thread-safety warning when a missing requirement affects only the C API. fb17e90 Update documentation. 8464d36 Update documentation. 3e55a4a Merge branch 'feature/doxygen-support' of github.com:emcrisostomo/fswatch into feature/doxygen-support 98de813 Update documentation. 1b705f3 Update documentation. c4d9884 Update documentation. 876a377 Update documentation. 3d89252 Update documentation. 6cc594b Change signature to monitor::set_properties(const std::map) so that parameter can be moved into field. 6e67d6a Remove unnecessary call from destructor. 6d0133b Update documentation. b15becd Update documentation. 281c37b Update Doxyfile.in: 6d29b4f Merge branch 'develop' into feature/doxygen-support 5facbd4 Merge branch 'feature/monitor-stop' into develop caaf8e6 Fix bug: port_get returns error in errno. 5e17511 Fix bug using timespec_t. d369c32 Add support for monitor::stop() to fen_monitor. 8195985 Add support for monitor::stop() to windows_monitor. 877bfe1 Add support for monitor::stop() to poll_monitor. a1da571 Move code that doesn't need to be repeated outside the loop. 1a34b47 Add support for monitor::stop() to inotify_monitor. 36562a8 Add support for monitor::stop() to kqueue_monitor. 4c107ce Let monitor::start() do nothing if monitor is already running. 4617e68 Allow monitor::stop() to be invoked on any monitor state. 4b1e1ac Add monitor::is_running(); edcd94e Stop the monitor before deleting it. 83642b3 Initial stop() implementation for the fsevents_monitor. 44184b6 Add a stop() method to the monitor class to allow for cooperative monitor shutdown. 0e17594 Update CLion code-style settings. a76a61d Update documentation. 996adfd Update documentation. 17fdc63 Merge branch 'develop' into feature/doxygen-support 4d43be6 Update fsw_get_event_flag_by_name so that it does not throw exceptions. 37bb2d0 Move common types to libfswatch_types.h. 351b0fb Update main Doxygen page. 35f5115 Add documentation. e04ac7d Add command ALIAS for @license. 48f273c Create Doxygen documentation on all-local. 6686415 Remove make target from main Makefile. b6d5d8a Add Makefile.am for Doxygen documentation. 795648b Organize documentation by type. ff51c3d Remove Doxygen configuration for fswatch. 63e88f2 Add Doxyfile for libfswatch and fswatch. 0bb7fc1 Add ignore pattern for Doxyfile. 23e13c0 Add macros to detect Doxygen availability to configure.ac. 58e268c Add ignore pattern for Doxygen configuration file. 0c3e4e9 Refactory monitor_factory to dynamically create the default monitor using the factory registration info. 13e2f9a Fix refactoring bug in monitor_factory::create_monitor: function would never return. be36974 Reformat. 8b90b02 Add missing include. a0635e3 Do not close handle during move or assignment if source and target objects contains the same handle. 3c6e366 Update po and pot files. d783764 Refactor to use functions in fsw::string_utils. 2ff4b4b Move fsw::string to fsw::string_utils. 53701c8 Refactor log functions to use the string utility functions. f3fcf66 Add functions to create a std::string from a printf format. 46a26c5 Add git ignore pattern for .idea/dictionaries. 655dc2b Move paths vector in monitor constructor. 6766211 Declare callback used by fswatch. 4254b97 Add factory function to register a monitor by type. bb82169 Update code-style setting to put brace in new line in lambda. 0338825 Reformat using the newly-configured code-style settings. 386c7e2 Update CLion code-style settings. 6b61465 Remove non-accessed variables. f27a10b Update code style rules for IDEA. 5c4fae1 Update library version. 9fa9ec3 Add CLion project files. d52a97f Add README.cmake. b57ebd1 Remove unused interface members. 927ea4e Cleanup unused imports. 3535b4b Initial CMake files. a39b4e4 Exclude IDEA files. 295e4fe Merge branch 'master' into develop 925d495 Update README.md. cbd3ecb Bump 1.8.0-develop. 81c8278 Merge tag '1.7.0' into develop aa79549 (tag: 1.7.0) Merge branch 'release/1.7.0' 85d5454 Update po and pot files. cc5bec4 Bump v. 1.7.0. dd6d107 Update Texinfo documentation. 3c88f78 Reformat code. 5a76c0d Reorder getops options. 0ca8c1f Update Texinfo documentation. c615999 Fix usage of @command and @file. 6025ecf Merge pull request #105 from MaxGabriel/patch-2 51f501e his => their in README 52b19b3 Update. 1aa0270 Update Texinfo documentation. 763599e Add Solaris/Illumos to the list of supported operating systems in the description. bb6ec59 Update PO and POT files. d951ef2 Merge branch 'feature/file-event-notification-support' into develop 91dc952 Issue 101: Add option to watch file accesses. cdcaf70 Fix usage message. 2e1ddd6 Update NEWS files. 356d842 Add Solaris/Illumos' README files to distribution. 4662187 Add support for FILE_ACCESS filter. b6d455d Update README.smartos. 3d6bfc3 Add README for SmartOS. a008a03 Add README for illumos and solaris. ffb3ab7 Add information about Freenode #fswatch channel. 28371bd Refactor: 08e6e0d Update ~fen_monitor_load(). 20c49f8 Remove redundant event type mapping. 4b7270e Close port handle when finished. b2c23a3 Detect removed files and port_disassociate() them. fab032c Update fen_monitor. 937d172 Add draft implementation of the fen_monitor. 5cb66c0 Fix comparison. 26447e0 Remove unused variable. fc9d66f Add configure check the availability of and port_create in libc. Refactor fen_monitor. 683f9ec Rename fen.{c,h}pp to fen_monitor.{c,h}pp. 7c16265 Add fen monitor sources to Makefile and POTFILES.in. 46f1c0c Add skeleton sources for Solaris/Illumos file events notification monitor. 370b172 Fix signed/unsigned integer comparison. 2b3b945 Fix wrong function call after refactoring. b2efb47 Merge pull request #99 from AlainODea/IllumosBuildSupport b3054d7 Cosmetic changes to the Texinfo documentation. 50220ed Allow build on Illumos 2b4c50d Merge branch 'feature/recurse-and-watch-directories-only' into develop 1150862 Update Texinfo documentation. 454036c Update the inotify monitor to treat the directory_only flag as if it were always set to true. 68f0f0a Ignore -d when processing a path that has been explicitly passed as a parameter. e586031 Refactor get_directory_children to return a vector instead of requiring the caller to provide one. c88a20f Update Texinfo documentation. 1515263 Update Texinfo documentation. bcd6623 Update NEWS files. af6a031 Update Texinfo documentation. ea898cb Add C support for set_directory_only. ad2b683 Bump libfswatch 5:0:2. 743758e Minor refactor in inotify_monitor. db37bfa Update the kqueue monitor to support the (-d, --directories) option. 7ae8098 Add fsw_logf_perror function to wrap a call to perror passing a printf-style format string with parameters. b5ed036 Migrate old logging code. ff49cf8 Do not open files with O_NOFOLLOW. cd60d38 Move implementation details into pimpl. 32064e6 Update the kqueue monitor to support the (-d, --directories) option. ca54b8d Update the inotify monitor to support the (-d, --directories) option. 94dc106 Add (-d, --directories) option to fswatch and add corresponding flag in monitor. a4f3411 Merge tag '1.6.1' into develop 14ec961 (tag: 1.6.1) Merge branch 'hotfix/1.6.1' e3ce9c8 Remove debian package descriptors. 80a24b5 Update Debian changelog. ca24599 Update Build-Depends in the Debian descriptors. 74adcff Merge branch 'hotfix/1.6.1' of github.com:emcrisostomo/fswatch into hotfix/1.6.1 4ac68a4 Update Automake configuration: require 1.14 and set std-options. 7328bb8 Add Debian packaging descriptors. c851d1d Update NEWS. e9b2577 Add @dircategory and @direntry to Texinfo files. 809b2f6 Bump v. 1.6.1. fc8a63b Bump v. 1.7.0.develop. 331ae3b Merge tag '1.6.0' into develop 13f9a6b (tag: 1.6.0) Merge branch 'release/1.6.0' e51a428 Add README.windows to the distribution. b1ba1e9 Add README.windows. 2492a02 Update README.md. 4694cb8 Update NEWS. 33e70e1 Update translations (pot and po files). 609c1c2 Simplify guarding the session on multithreaded implementations using a macro. f610f4a Add fsw_add_property to the C API. 3972767 Cleanup namespace explicit usage. 0a37aa6 Merge branch 'release/1.6.0' of github.com:emcrisostomo/fswatch into release/1.6.0 9d7e3c3 Use notify_overflow in the inotify monitor. a2af3a0 Update notify_overflow signature. 39da6a6 Pass watched path when notifying an overflow event. fa88815 Update Texinfo documentation. b11595d Remove is_verbose() and use libfswatch instead. 74d0e07 Move includes from header to source file and clean up. 88a5a7d Clean up and remove unused includes. ffcde63 Update Texinfo documentation. 44b5626 Update method signature to use a const reference. 8623e23 Use libfswatch log functions and remove legacy ones. c7812f8 Update po and pot files. 8578c8b Refactor log functions. f414fdf Exclude private OS-specific header from the install target. 4ede236 Remove useless header includes. 06aaa82 Update po files. 8241e0b Update POT files. bf7406a Add missing headers to Makefile.am. a19f0e8 Refactor windows_monitor. 3edaa23 Fix missing newline in PO file. 155bbb3 Update file header. e362058 Update PO and POT files. e764461 Update POTFILES.in. 5c51dd1 Move Windows-specific code to separate classes. f5a8a9a Use strtol instead of string::stol because of a Windows C++ library bug. 517f824 Add --monitor-property option to pass monitor-specific configuration properties. 7f44574 Reset event and read next change event after an overflow. d2ac21b Map Overflow event type. 1636faf Update Texinfo documentation. 6363c70 Update Texinfo documentation. 2d3804f Add the --allow-overflow option to allow monitor buffer overflows and have fswatch report them as change events. e20205d Add the possibility to report monitor buffer overflows. 6c8c4b0 Bump 1.6.0. 6a7f704 Update README. 0e03508 Update Texinfo documentation. 01170f3 Update NEWS. 2febb99 Add *.t2p and documentation PDF to ignore list. cbb62f8 Merge branch 'feature/windows-support' into develop 9a5f62b Bump libfswatch 4:0:1. 826aa6d Update pot templates. da80f6c Update translations. 358e090 Move win_error_message to separate files. ac3c5ae Move win_hamdle to separate files. 11d33e0 Merge branch 'develop' into feature/windows-support 59751f8 Convert global variables to static method functions to avoid global initialization race conditions. 3c5e548 Update translations. 822ef3d Update translations. 5a28af5 Merge branch 'feature/windows-support' of github.com:emcrisostomo/fswatch into feature/windows-support ba8508f Merge branch 'develop' into feature/windows-support ad4c093 Catch libfsw_exception in C API. f143f70 Refactor the windows_monitor to use FSW_LOGF. 754e24c Define the macros FSW_LOG and FSW_LOGF to simplify log management and to automatically prepend the name of the method where this macro is invoked to the logged message. 1115888 Add windows_monitor.cpp to POTFILES.in. 1b24efc Convert Windows paths back to POSIX paths when printing events. 4cea26d Compile the Windows monitor only if both Windows and CygWin SDKs are detected. c53cdf6 Make sure Automake conditionals are not defined conditionally. c688df3 Check whether the CygWin library is available if Windows is available. cebb510 Report event queue overflow on both the inotify and Windows monitor. f46f609 Log diagnostic messages only if verbose mode is on. 3901c28 Use multibyte strings in iostreams. 214cf29 Refactor code. 67774fe Refactor code. cf224e4 Refactor directory_change_event. f488366 Refactor win_handle. 1a19946 Refactor win_error_message. a4e5893 Remove unused headers. 901e818 Process event types. 6245788 Merge branch 'develop' into feature/windows-support 98c7bf6 Check if required kqueue functions are available in libc. becfd8e Check for inotify functions in libc. 3137859 Update autogen.sh to treat warnings as errors. 8020f52 Check for the presence of inotify headers and for the availability of the necessary functions. 8505e13 Simplify string processing routines by defining ostream::operator+ to encapsulate string conversion from wide char to multibyte. d38058e Refactor path processing routing to convert its output to UTF8. 508ce9d Add logging code to the Windows monitor. 03a3ddd Add log function accepting varargs. b87f6ff Add verbose logging to libfswatch and propagate the -v option from fswatch to libfswatch. e63f5d6 Remove debug output. bfd7ac1 Use a single event per watched path through the process life. a5e017d Use Windows' asynchronous I/O to wait for change events. 2e62e98 Initialize struct using brace initialization. d455c22 Merge pull request #94 from kellytk/master 04a8cbe Spelling correction 046fb08 Add constructor to DirectoryChangeEvents to override the buffer size. 3b1b5ec Fix error management routine. 74be110 Fix error management routine. 1ab841a Update Windows monitor. ea457a6 Add static object factory WinErrorMessage::current(). 5aa8863 Encapsulate Windows system error message processing. 119a2c0 Refactor CHandle in terms of is_valid. 80ab48c Update. 1b59d4c Refactor. e34b381 Add an assignment operator from HANDLE to CHandle. 0af8aad Create RAII wrapper for HANDLE. 09ac6f6 Refactor and encapsulate event data in a common struct. d23ecb9 Use overlapped I/O. bf23c50 Add windows monitor initial draft. f68091c Add checks for the Windows directory change notification API and enable conditional compilation of the Windows monitor. fcf4ed9 Add fswatch.exe to the ignore patterns. 0a9a465 Merge branch 'develop' into feature/windows-support 4efe605 Aesthetic cleanup. a7b7348 Add mandatory check for unistd.h and conditionally check for getopt_long if getopt.h is available. 5153be6 Add autoscan.log and configure.scan to Git ignore patterns. dd8b0a3 Update PO and POT files. a9ded2e Move C++ header files to .hpp. 05f9ca6 Refactor monitor-checking code and fix kqueue detection by checking for the availability of both kqueue and kevent if sys/event.h has been found. cb2d46b Update configure.ac to use M4sh when possible. d5cae04 Have configure check for optional and required headers. f7078f9 Update configure checks. e0d6da1 Update .gitignore to filter out in-site build artifact. 714d0c3 Clean up code conditioned by HAVE_REGCOMP. ed938dc Invoke AC_LANG before LT_INIT. ab3b13a Update .gitignore to filter out in-site build artifact. 58d33d1 Move C++ header files to *.hpp. a57d529 Merge branch 'master' into feature/windows-support e1c1d64 Merge branch 'master' into develop d43e23c Add CONTRIBUTING.md to the distribution. b0fe50a Fix broken link. d57282d Update list style. 20269b8 Add CONTRIBUTING.md. f43a722 Add Contributing section to README.md. ab9d7fe Remove unused configuration checks. f5efca5 Use C++ headers for C libraries when available. 120d7c4 Update History section in Texinfo documentation. 64bc884 Update NEWS adding references to GitHub issues. cb05c26 Remove legacy scripts. 568e5ad Merge branch 'hotfix/1.5.1' into develop 7752074 (tag: 1.5.1) Merge branch 'hotfix/1.5.1' eced175 Update Texinfo documentation. 702e4b5 Update NEWS. 5d22033 Fix import required when building on FreeBSD 9.3. 6c584d3 Remove checks for Zsh and Bash and remove fswatch-run scripts. ba71ceb Bump 1.5.1. bada39c Bump 1.6.0.develop. 9519745 (tag: 1.5.0) Merge branch 'release/1.5.0' 81091b4 Merge branch 'release/1.5.0' into develop e9a90e5 Fix signed/unsigned comparison on gcc. 1e264b9 Add missing include. e3256f7 Distribute gettext.h. 8938e83 Update NEWS. 376de51 Simplify the Documentation section. 74db727 Rearrange README.md entries. 900a594 Fix anchor typo. 2480795 Update README.md. 94a334a Update README.md with links to the GitHub page. ca17426 Merge branch 'develop' into release/1.5.0 4ab9103 Update README.md with links to fswatch's GitHub page. 86646a8 Rename Index node to General Index to avoid Texinfo clobbering the index.html page when outputting HTML. 8d167fb Rename Index node to General Index to avoid Texinfo clobbering the index.html page when outputting HTML. 08253a5 Update man page. 14b4e2f Update fswatch's TeXinfo documentation. c4d026d Update libfswatch's TeXinfo documentation. 6d6b13e Cleanup and refactor libfswatch's Makefile. 54bd867 Refactor to use memory management functions. 6b3b01c Add memory management functions. 82101dd Rewrap document in Emacs' texinfo mode. 9dcea8b Bump 1.5.0 and libfswatch API version 3:0:0. fb890fe Merge branch 'feature/event-type-filter' into develop 8d37e21 Remove custom xgettext invocation (available into the standard Autotools workflow). 1f2bcff Update PO configuration files. f7b54eb Update translations. ab12262 Update POTFILES.in. 8131fe9 Update PO and POT files. 3e97992 Use event::get_event_flag_name in fswatch. 7283c70 Use event::get_event_flag_name in std::ostream& operator<<(std::ostream& out, const fsw_event_flag flag). f9b6a57 Reformat. be853dd Move monitor_filter to fsw::monitor_filter. af0fb7f Fix namespace bug: move event to fsw::event. 660b960 Add --event option to let users add event type filters. 7f7375e Add FSW_ERR_UNKNOWN_VALUE error code. 0d66937 Add API functions to get an event type by name and to get the name of an event type. 3c1d01c Refactor monitors to use monitor::notify_events. bed5e45 Move path filtering logic, event filtering logic and callback invocation to monitor class. 70fa06b Add function to libfswatch to add event type filters to a session. f0bd4e3 Update monitor to hold an optional list of event filters. a8ddd22 Define a structure for an event flag filter. 3b24960 Fix signed/unsigned comparison. b0bfd49 Configure libtool to use -no-undefined when linking shared libraries on CygWin. 5a1a49d Merge branch 'develop' into feature/windows-support 0160c9c Fix bug that had fsw_destroy_session always return FSW_ÖK. 650d1fe Import to define realpath. 7970806 Enable C++11 with extensions (realpath may not be available in strict ANSI mode). 1a5d300 Update ignore file for in-tree builds. a852a9a Cosmetic refactoring. 836af3f Update obsolete Autoconf macros. f2308ef Add missing const. 8188bf1 Update copyright and rewrap. adde10b Fix constness. b58eefd Update the TeXinfo documentation. 419f9d6 Update the TeXinfo documentation. e0c4bd4 Update the TeXinfo documentation. 82a7bc2 Merge branch 'feature/libfswatch-texinfo-doc' into develop dc6e14c Update the TeXinfo documentation. 5510966 Update TeXinfo documentation. f7de6e3 Save last error even if the thread_local storage specified is not supported. 1bc4d8e Update TeXinfo documentation. 843de5e Update the TeXinfo documentation. e33e479 Update TeXinfo documentation. 216408b Update TeXinfo documentation. f43ca3d Update TeXinfo documentation. 721e714 Refactor factory methods to simplify them. 9d74a19 Rename factory methods. 9338f17 Update TeXinfo documentation. 0ae0904 Rephrase reference to the official documentation. 58fde3b Add --event-flag-separator option to the man page. 9817ea6 Add --batch-marker option to the man page. b79363a Update the man page and add the (--list-monitors, -M) option. f8229c7 Add the (--list-monitors, -M) option to the TeXinfo manual. 1686b87 Update the Italian (IT) po file. 5565062 Update the Spanish (ES) po file. 5edc19b Update fswatch po template file. 338808a Add (-M, --list-monitors) option. d0606a2 Update libfswatch po files. b1cec6b Bump 1.5.0.develop. aa6174c Bump libfswatch 2:0:0. 7bf25db Move all the factory methods into monitor_factory and refactor. 70a8bdd Merge branch 'develop' into feature/libfswatch-texinfo-doc 7da8577 Merge branch 'feature/improve-monitor-factory' into develop 5cc1a8e Remove legacy code. 706eaf0 Refactor methods that can be const. 1a14945 Use intermediate variable. 40ae744 Merge branch 'develop' into feature/improve-monitor-factory d85588c Fix quotation. 0eecd8e Rewrap text at 80th column. c2f58ab Merge branch 'develop' into feature/libfswatch-texinfo-doc e955614 (tag: 1.4.7) Merge branch 'release/1.4.7' 2a6e106 Merge branch 'release/1.4.7' into develop 5d678ac Update po and pot files. bd367bc Update NEWS. 718e4bf Update po files. 0a6d352 Update TeXinfo documentation. afcc607 Update. acd7e82 Update NEWS. 4730e6b Add all README files to distribution. 1524737 Update po files. bc59a7d Bump autotools dependencies. e2f25e4 Bump autotools dependencies. fcd0587 Require autoconf 2.68. 6318bc4 Update .travis.yml. 321e451 Remove sudo invocations from .travis.yml. 88ae7cc Use container-based builds. 9184ea4 Update Travis scripts. 6a7b3f2 Set required gettext version to 0.18.3 to accomodate for Travis CI VM packages. 72e0159 Add dependency to autopoint. a3db8a7 Fix dependencies during Travis build. 60449bc Fix dependencies during Travis build. f8daa01 Add gettext package from Brew before the Travis build. 4974cc4 Update Travis script. ab9fba6 Add Travis configuration file. c409ed8 Merge branch 'develop' into release/1.4.7 d8503c0 Add license badge. c06e95d Update NEWS. a26b35d Bump v. 1.4.7. 0a163a3 Fix filter behaviour and make them consistent with the documentation. 899cb3b Add indent style information. d2591ad Reformat code. 8ec7736 Merge branch 'gsamokovarov-c-api-extra-context-data' into develop 6a0bde8 Merge branch 'c-api-extra-context-data' of https://github.com/gsamokovarov/fswatch into gsamokovarov-c-api-extra-context-data b03141a Merge branch 'master' into develop 63fa31c Merge pull request #75 from Zearin/patch-1 0665e2c Minor edits to clarity, phrasing, and formatting 71392a1 Attach additional data to C API monitor callbacks df65a49 Merge branch 'release/1.4.6' into develop 578c1d8 (tag: 1.4.6) Release 1.4.6. 505c9a1 Bump v. 1.4.6. 15842d7 Bump v. 1.4.6. c655610 Fix Issue 74 (https://github.com/emcrisostomo/fswatch/issues/74): Assertion failed on fsw_destroy_session. 5ab39e4 Merge branch 'master' into develop a6a26a1 Merge branch 'master' into develop d4a7b30 Merge pull request #73 from sachinsudheendra/fix-doc-1 6390a31 Fixing documentation with correct flag option a8701b8 Fix issue 67 (https://github.com/emcrisostomo/fswatch/issues/67): 100% CPU usage while using libfswatch. 3002295 (tag: 1.4.5.3) Merge branch 'release/1.4.5.3' b4cacbc Merge branch 'release/1.4.5.3' into develop 1808eed Bump v. 1.4.5.3. c0a8d0f Fix issue 67 (https://github.com/emcrisostomo/fswatch/issues/67): 100% CPU usage while using libfswatch. 0db6447 Bump v. 1.4.6-current. 785afb4 Merge branch 'master' into develop 8450dd5 (tag: 1.4.5.2) Update NEWS file for v. 1.4.5.2. 78b8e7c Merge branch 'release/1.4.5.2' into develop e898dc9 Merge branch 'release/1.4.5.2' 8f97e51 Configure tar.gz distributions. 0cc4bb5 Bump v. 1.4.5.2. fb982e5 Fix issue 66 (https://github.com/emcrisostomo/fswatch/issues/66): excluded items are not managed correctly by the poll monitor. 29b5eb2 Merge branch 'develop' into feature/improve-monitor-factory 6af533c Merge branch 'hotfix/1.4.5.1' into develop a7842b6 (tag: 1.4.5.1) Merge branch 'hotfix/1.4.5.1' ef82f2f Bump v. 1.4.5.1. c306a54 Do not distribute wrapper scripts for shells which are not installed (the FreeBSD port system checks shebangs and complains). 4807457 Bump v. 1.4.6-current in . 6189da3 (tag: 1.4.5) Merge branch 'release/1.4.5' 2be6be5 Merge branch 'release/1.4.5' into develop d630bb6 Merge branch 'juliekoubova-patch-1' into develop 5d1326e Merge branch 'patch-1' of https://github.com/juliekoubova/fswatch into juliekoubova-patch-1 1a85db0 Remove unnecessary std namespace qualifiers. 6ae54b6 fixed a typo c43cfdf Update monitor_registrant in order to accept a creator function to create a specific monitor type. aa633bc Add initial monitor_factory description to the documentation. cfd0c5b Update teh C++ API section. b63c2da Add Makefile for libfswatch's documentation. b34ef4b Remove dependency on value.texi. e22f738 Add initial texinfo documentation for libfswatch. 8ea7d78 Update README.md. c559adf Bump v. 1.4.5. 45bae72 Update version. 83d6f75 Update version. 4dcf446 Use std-option when install-checking fswatch. c5c117d Propagate M4 variable to Automake variable to set libfswatch version info. c94281b Update PO and PO template file. b04e93e Do not use shell scripts to set the package version because they are not detected as dependencies by Automake nor can be successfully executed when sources are outside the Git tree. 9548c93 Update fswatch so that --help and --version succeed and exit with 0. b0c345d Amend missing Spanish locale in README. 6e63d7b Merge branch 'release/1.4.4' into develop e2a2399 (tag: 1.4.4) Merge branch 'release/1.4.4' 1d4989f Use m4_esyscmd_s instead of m4_esyscmd so that trailing newlines are removed from the result in libfswatch. de91ef5 Update NEWS. 2b984dc Update PO and PO template files. 4da4426 Merge branch 'feature/record-format' into develop 0985a93 Add section to event flag separator customization in the documentation. da32daf Add --event-flag-separator to customize the event flag separator string. 47455c8 Update documentation adding section about custom record formats. da67506 Update localisations. f2a007b Update printf_event to accept an optional output stream and use it to test the format string. 4152b8f Update code so that line separator is not determined by the format. 7ab69cf Use default record format only when --format is not specified. 7214877 Update option parsing logic to make --format incompatible with other formatting options. 4a203b1 Map existing format options (-0, -t, -x) to corresponding formats for printf_event. 846e8f7 Print event records using printf_event. b3ae34a Add printf-like function to print an event to stdout. 732d137 Add configure dependencies to trigger automatic Makefile rebuilds. fe54b40 Add configure dependencies to trigger automatic Makefile rebuilds. eb694b9 Use m4_esyscmd_s instead of m4_esyscmd so that trailing newlines are removed from the result. 0325fa1 Add README.linux to the list of distributed files. 2f536b5 Update README.freebsd. 3a056e3 Add README.linux file. b4248f0 Update README files. 275f20d Add Emacs local variables to shell script files. 51e384a Update ChangeLog template. be3e538 Fix README.md formatting. 8e2b8d6 Update README.md and README.osx. 08a2f1b Update NEWS. b2368ab Add Emacs local variables. 8645ed2 (tag: 1.4.3.2) Merge branch 'hotfix/1.4.3.2' 87a422e Merge branch 'hotfix/1.4.3.2' into develop d6f7c94 Fix Makefile.am because of broken link when DESTDIR installs are performed. b08c444 Merge branch 'hotfix/1.4.3.1' 7b95bd4 Merge branch 'hotfix/1.4.3.1' into develop a3952a0 Fix bug in fswatch-run wrapper script for ZSH which caused last argument not to be split when passed to xargs. d5d98c6 Update PO and POT files. 9cece81 Update fswatch's include paths after source refactoring in libfswatch. 6a007a2 Update POTFILES. c2deb5d Add Makefiles to libfswatch. 318b3c6 Make libfswatch a non-flat project and move sources into src/libfswatch. 6cbc780 Merge branch 'feature/libfswatch-gettext' into develop eb7e79d Add Spanish (es) localization. f97dd71 Add Italian (it) localization. 7cd12ff Localize strings in libfswatch. 0f15c33 Add library initialization library. d10c41f Add LOCALEDIR definition to Makefile.am. 5f5120c Update .gitignore so that automatically generated PO files and GMO files are excluded at any depth. 47c53cf Add LINGUAS file declaring English (en and automatically generated variants), Italian (it) and Spanish (es) and add initial PO files. c46c589 Add initial PO template file for libfswatch. 75c610a Make fsevents_monitor.cpp localizable. ff6e676 Update Makefile.am to distribute gettext.h and gettext_defs.h 65c6ed8 Add gettext.h and add auxiliary header gettext_defs.h to define _() as a function of gettext(). f59b788 Add po directory with Makevars and POTFILES.in. 6f68ab7 Update Makefile.am and configure.ac after running gettextize. 32f631b Normalize Spanish PO file. 0665d29 Exclude automatically generated PO files and GMO files and add them to .gitignore. 843262c Add Spanish (es) localization. 71929e3 Merge branch 'feature/gettext' into develop 3d936dd Add localization information into README.md and README.osx. 1caa7cb Update PO files. c50193e Canonically rearrange entries in Makefile.am. 5316fc9 Initialize gettext after language initialization. 3d498b9 Move compiler configuration macro in language section. e516913 Update LINGUAS as described in the gettext manual. a7148bc Add LINGUAS file. d306db9 List files needing translation in POTFILES.in. 2ca2db9 Update Makefile.am as described in gettext manual. d90a4ca Added Italian (it) translation. f55dd1e Merge POT file with existing PO files. 817e1db Update fswatch PO file. c7a5513 Add initial it.po PO file. 2ff4865 Add fswatch PO template file. eb170a3 Mark translatable strings in fswatch.cpp. 6c513a3 Add template script build-aux/create-pot-template.sh.in to invoke xgettext with options populated by Autoconf. e2cc018 Trigger gettext operations in main. 115b89d Convert the fswatch package to a non-flat package. 219935a Correctly quote argument of AM_GNU_GETTEXT_VERSION as suggested by gettextize. 753ed1a Add gettext.h so that conditional use of is available. e8b6616 Add initial Makevars. 2edf92e Add initial POTFILES.in. f11c596 Update Makefile.am and configure.ac with changes required by gettext and applied automatically by gettextize. df4cb3c Add files automatically generated by gettextize and autoreconf to .gitignore. 740afb1 (tag: 1.4.3.1, tag: 1.4.3) Merge branch 'release/1.4.3' adf5492 Merge branch 'release/1.4.3' into develop de5acb3 Add disclaimer about documentation in package managers. 85bca11 Add information about install-pdf in README.md. ba3ef70 Add download link for the PDF manual. 196e152 Enhance documentation section in README.md. 29414d3 Update NEWS for 1.4.3. 9744119 Update ChangeLog template to describe how change logs are generated using Git. cb7d4e2 Add Documentation section to the README file. b0e07cc Fix missing newline in help message. 2cbfcf0 Add batch marker documentation to texinfo manual. ec67812 Merge branch 'feature/Batch_Marker' into develop b82b03f Add batch marker feature. 6125ed3 Add batch marker feature. 08018f6 Add notice to redirect users to texinfo documentation in man page. 3683b97 Fix whitespaces. 1f8411b Update document and indices. Update Monitors section. 3bc7941 Add monitors section. d46c361 Add description of the inotify monitor. 429fb8e Add Monitor chapter and describe the FSEvents and kqueue monitor. 5e75f7b Add section to describe the (--recursive, -r) option. de599d5 Add monitor section to document the (--monitor, -m) option. 95d8579 Update numeric event flag section. 2b5ac43 Update. 60968c0 Update. 430066c Update. d516d37 Add GNU Free Documentation License and add dependency in Makefile. cd0447a Rename fsw occurrence in string to fswatch. 97b1207 Add TeXinfo file dependencies. 5e6ae93 Add skeleton of texinfo manual. 94971c9 Update NEWS. 31266fd Move auxiliary configuration scripts to build-aux. de08131 Fix typos in man page. b29ebb9 Add bug report email to man page. 4ed1d3e Add copyright and license to man page. 887b6b8 Fix whitespaces in man page. 634101d Add MONITORS and EXIT STATUS sections. ca1003c Fill in bug report address in man page using PACKAGE_BUGREPORT. 33ff0c3 Update usage and examples in man page. 32645e2 Fill man page variable using Autoconf config file substitution. 6b98f13 Create man page using Autoconf config files. cf43628 Move man files to man subdirectory. ebdb85b Update the kqueue and the inotify monitor to sleep latency when no files can be watched yet. df780c8 Use and if set. ef172b8 Use git log to dynamically generate ChangeLog. 25135a4 Update. dcc22b5 Use ::select to timeout a ::read using the monitor latency as the timeout amount. 5f5122e Add Autoconf function checks for ::modf and ::select. c7773f3 Exit with error if atexit is not found. eee7bd6 Add AC_PROG_RANLIB and AC_CHECK_FUNCS([atexit]) 8ae47b1 Set library version info using an Autoconf-substituted variable. 65f7573 Set library version info to 1.0.0. 02e3036 Add --version option. 82579e1 Improve help message adding bug report email and web page. d24087a Update README. e0f003e Add mention to running ldconfig in README.md. e0ddd15 (tag: 1.4.2) Merge branch 'release/1.4.2' c674001 Update change logs. 3c558a8 Read version number and revision number from script output. 5ebdb13 Add scripts to get version from git tags. 5ada8a8 Read version number from file. 207bb9d Enable silent make rules. 21e1165 Set dist-zip by default and disable dist-gzip. d8ba6f5 Merge branch 'develop' of https://github.com/emcrisostomo/fswatch into develop c1fbe0b Update misleading ::perror argument. bb2b052 Update misleading ÑÑperror argument. 1685374 Refactor method name. fa65da3 Update the inotify monitor. 7b1311c Add the MovedFrom and MovedTo elements to fsw_event_flag. c48ab53 (tag: 1.4.1.1) Merge branch 'hotfix/1.4.1.1' 85b2316 Merge branch 'hotfix/1.4.1.1' into develop 51991a9 Refactor code to support the unavailability of std::unique_ptr. 2d2b347 Add type check for std::unique_ptr in . 61ee86a Add type check for std::unique_ptr in . 09de366 (tag: 1.4.1) Merge branch 'hotfix/1.4.1' aabc450 Merge branch 'hotfix/1.4.1' into develop 013a159 Bump v. 1.4.1. 777643b Issue a configure warning if is not found. a4d3a2a Use only if HAVE_CXX_MUTEX is defined. 4754b80 Add an Autoconf check for the header. e0355e7 Update the inotify monitor to recursively scan directories. ed8f6e4 Do not check paths against filters during watch creation. 669a4b6 Do not throw on non-existing path. 900f248 (tag: 1.4.0) Merge branch 'release/1.4.0' 895ad32 Merge branch 'release/1.4.0' into develop c3e59c5 Remove local cleanup hook becase it broke builds on the root directory. 1a0dc5c Update and rename fsw to fswatch. be19c55 Update installation section with information about MacPorts and Homebrew. 7ff1897 Update. 7a2bae3 Rename inotify monitor's pimpl. 18a52ce Avoid race conditions when initializing static members. 2fba605 Define Automake conditionals in every code path. bbf8602 Rename members using the fsevent_ prefix to use fsevents_. 1fcfd1a Refactor after fsevents_monitor name change. 75448ee Use the fsevent_monitor only if the FSEvents API supports file events. 13e5cb1 Compile the FSEvents monitor only if the OS X FSEvents API supports file events. f1087b3 Add M4 macro to check whether the OS X FSEvents API supports file events. 3e8e382 Fix missed deallocation. 6bb3694 Do not compare signed types against unsigned types. 5416900 Include header required by unique_ptr. 0820f23 Declare destructor noexcept. 1ec1a58 Fix wrong included header path. Fix missing context parameter when invoking callback. a7ed7e5 Free memory allocated by the C callback proxy. b058478 Pass callback address to C proxy callback as context data. bcec60c Simplify the libfsw_cpp_callback_proxy memory allocation. 49fb575 Document the libfswatch.h header. c48772d Document the cevent.h header. 4152638 Update change log. d1588b3 Document the libfswatch.h header. 671d21a Document the cmonitor.h header. 2e047f5 Document the cevent.h header. 15a4d15 Update. 0c44cad Link README.md to README. a3ba3bc Updated instructions to setup the GNU Build System in a development environment. 78bddc9 Update to forward arguments to autoreconf. 3c1a7c5 Make private functions static. 0578239 Document the libfswatch.h header. 01943d7 Start documenting the libfswatch headers. 9741c3c Update the manifest files of the libfswatch package. 3ba8f67 Add usage example of the -m option. b403217 Update NEWS. 11af6d3 Bump v. 1.4.0. 3101ff2 Update mane page. d6f1a84 Update fswatch so that users can specify the monitor to be used by name. -k and -p options were removed. d9810db Update all monitors to register themselves into the factory. 558c0a8 Add a monitor registration and factory facility in order to create monitors by name. fb7ac7d Update distributed document data. 8059147 Add LICENSE file to libfswatch module. 3ec811f Merge branch 'master' into develop 9456a6d update History with new repo URL 92f6139 Update. 1e70591 Update ChangeLog. 38605ea Update sources after moving fsw to fswatch. ed0b465 Remove elements migrated to libfswatch. d07a6a0 Add libfswatch submodule from fsw. See ChangeLog for further details. d298deb Merge configure.ac and Makefile.am from fsw. See ChangeLog for further details. 8f0ad27 Do not track files automatically generated by libtool. b646c76 Add configure scripts for debug, static binary debug and release targets. 095dc3f Fix formatting. 3fb51da Add COPYING. 484dff5 Update AUTHORS. 9c7bb6b Correct some typos. 51ad155 Reindent. 90bf833 (tag: 1.3.9) Bump v. 1.3.9. 2c55578 Update NEWS and README. 58ea395 Update man page and include information about event filtering. e6e7310 Directory names must be filtered when events are fired because they are not filtered while scanning. 7fc7969 Refactor kqueue monitor directory scanning implementation. 79c9c3d Refactor poll monitor directory scanning implementation. b477578 Check filters only on the file path and not on scanned parent directories for the kqueue monitor. d8054c5 Check filters only on the file path and not on scanned parent directories for the kqueue monitor. 7c2616f Check filters only on the file path and not on scanned parent directories. bd7adf9 Change the filter rules so that the first wins, no matter whether it's an exclusion or an inclusion filter. dd02b0e Add -i, --include option and basic implementation to support the use of an include regexp. 764f896 Move -i option to -I. fb7b846 (tag: 1.3.8) Print diagnostic messages only when fswatch is run in verbose mode. 57e6fdf (tag: 1.3.7) Remove usages of C++11 initializer lists so that fswatch builds with older compilers. 10e0ea8 Fix typo. 35af754 (tag: 1.3.6) Updated. 2479407 Update. 07fdbf3 Update. a48a107 Use /bin directory in the sha bang of a shell script whose shell has not been found in the system. d7d73ef Add AC_PATH_PROG macros to detect the paths of ZSH and Bash and AC_SUBST them. ffde403 Update scripts to be template files so that the Autoconf can fill in the correct shell path in the sha bang. 1a8199b Remove symbolic link during the uninstall target and use LN_S. 01a6af3 Link fswatch-run to the correct shell-specific wrapper. 9809e09 Bump v. 1.3.6, check if ZSH and Bash are available and prepare Automake variables. 63b2ef5 Add a fswatch-run wrapper for ZSH and Bash. 313ef4b (tag: 1.3.5) Bump v. 1.3.5 and update distribution files. 09e11be Write usage to standard error when invalid arguments are specified. 2430c95 (tag: 1.3.4) Bump v. 1.3.4. 3d2128a Merge pull request #26 from nobeans/fix/fswatch-run e044bee Remove a quotation from xargs arguments to run a command with arguments dbbd2de (tag: 1.3.3) Merge branch 'release/1.3.3' 64def03 Merge branch 'feature/Issue-20' into develop 2430fbc Update man page. 0096e40 Add information about fswatch-run in README. 7b25f6d Add shell script to mimic the behaviour of earlier fswatch versions and launch the specified command when change events are received. 922ac0c Add section about compatibility issues with v. 0.x. 5a48928 Add section about compatibility issues with v. 0.x. fd531ca Add -o/--one-per-batch option to print a single message with the number of change events in the current batch. 9501e2b Bump v. 1.3.3. f0c2e68 Issue 22: Add link to release page. 7c92230 (tag: 1.3.2) Bump v. 1.3.2 to align fswatch releases with fsw. Update ChangeLog. 9a33505 Add History section to README. 457ede7 Add man file. 0c5f4f7 Fix typo. 46b5095 Add README.* files. 10ea4d7 Bump v. 1.0.0 and update README. 96e66f1 Initial merge with fsw (https://github.com/emcrisostomo/fsw). 74c55f5 Update configure.ac and ChangeLog. 3ff7d03 Reconfigure the project as a C++ project. 70e5478 Establish the following ordered compiler search list: CLang, GCC. e9534dc Merge pull request #16 from emcrisostomo/master 27dd186 Link LICENSE to COPYING, update copyright, license and authors. 8ff0e67 Update README file. 36e26d0 Update README file. 7c276cc Add files to build the program using the GNU Build System. 460e818 Add exclusions for GNU Build System, Eclipse CDT and NetBeans to .gitignore. 709b349 Remove custom Makefile. 38d47dc Merge pull request #15 from kud/patch-1 f79dab7 Add brew instructions. 5910b7a Merge pull request #13 from chetbox/master ffbc670 allow bash commands with arguments to be passed as arguments to fswatch c049e85 (tag: 0.0.2) added license (bsd new), closes #7 a6ff7fd Merge pull request #1 from marceloandrader/master b1ba236 Added documentation to multiple dir support 62a9814 Allow watch multiple directories 5e9ef06 (tag: 0.0.1) fix a small tyop 0790697 bash formatting for rsync example 1acf9f1 README -> README.md 8139725 update readme 3273e6f a makefile, why not a0db417 run shell command instead of path c447f6e pass environ to child process e7e5f4a initial commit fswatch-1.11.2/config/000755 000765 000024 00000000000 13175374110 015124 5ustar00enricostaff000000 000000 fswatch-1.11.2/AUTHORS000644 000765 000024 00000000223 13174733730 014732 0ustar00enricostaff000000 000000 AUTHORS ======= Authors of libfswatch: - Alan Dipert (v. < 1.0.0). - Enrico M. Crisostomo fswatch-1.11.2/README.smartos000644 000765 000024 00000006043 13174733730 016237 0ustar00enricostaff000000 000000 README.smartos ************** Introduction ============ This file describes the steps required to build this bundle on SmartOS. A complete C/C++ toolchain for SmartOS is provided on the base-multiarch image. The user is currently using the following image for the development of fswatch on SmartOS: UUID: 9250f5a8-6e9c-11e5-9cdb-67fab8707bfd NAME: base-multiarch VERSION: 15.3.0 Setting Up a Development Zone ============================= A development zone can be setup using the following procedure: * Search for the latest base-multiarch image: $ imgadm avail | grep base-multiarch 9250f5a8-6e9c-11e5-9cdb-67fab8707bfd base-multiarch 15.3.0 smartos 2015-10-09T15:44:05Z * Install the latest image available: $ imgadm import 9250f5a8-6e9c-11e5-9cdb-67fab8707bfd * Create a zone manifest called development.json. A simple zone manifest template is the following: { "brand": "joyent", "image_uuid": "9250f5a8-6e9c-11e5-9cdb-67fab8707bfd", "alias": "development", "hostname": "development", "max_physical_memory": 4096, "quota": 10, "resolvers": ["8.8.8.8", "8.8.4.4"], "nics": [ { "nic_tag": "admin", "ip": "dhcp" } ] } * Install a zone using the specified image and manifest: $ vmadm create -f development.json Prerequisites ============= The following packages must be installed on the zone where fswatch is built: * autoconf * automake * gettext * libtool * gcc49 * git * gmake * gtexinfo Packages can be installed using pkgin: $ pkgin update $ pkgin install package ... Installation ============ See the INSTALL file for detailed information about how to configure and install fswatch. fswatch is a C++ program and a C++ compiler compliant with the C++11 standard is required to compile it. Check the documentation of your distribution to learn how to install the required software. The configure script enforces an ordered compiler search list and clang++ will be used first if available. If you do not like this choice and wish to use another compiler set the value of the CXX environment variable to the name of your compiler binary. If, for example, you wish to use the g++ compiler, then use this command to configure the build: $ ./configure CXX=g++ ----- Copyright (c) 2015 Enrico M. Crisostomo 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, 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 .fswatch-1.11.2/libfswatch_config.h.in000644 000765 000024 00000015736 13175374060 020130 0ustar00enricostaff000000 000000 /* libfswatch_config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if translation of program messages to the user's native language is requested. */ #undef ENABLE_NLS /* Define to 1 if you have the `atexit' function. */ #undef HAVE_ATEXIT /* Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the CoreFoundation framework. */ #undef HAVE_CFLOCALECOPYCURRENT /* Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in the CoreFoundation framework. */ #undef HAVE_CFPREFERENCESCOPYAPPVALUE /* Define to 1 if you have the header file. */ #undef HAVE_CORESERVICES_CORESERVICES_H /* Define to 1 if you have the header file. */ #undef HAVE_CSTDLIB /* define if the compiler supports basic C++11 syntax */ #undef HAVE_CXX11 /* Define if is available. */ #undef HAVE_CXX_ATOMIC /* Define if is available. */ #undef HAVE_CXX_MUTEX /* Define if the thread_local storage specified is available. */ #undef HAVE_CXX_THREAD_LOCAL /* Define if std::unique_ptr in is available. */ #undef HAVE_CXX_UNIQUE_PTR /* CygWin API present. */ #undef HAVE_CYGWIN /* Define if the GNU dcgettext() function is already present or preinstalled. */ #undef HAVE_DCGETTEXT /* Define to 1 if you have the declaration of `cygwin_create_path', and to 0 if you don't. */ #undef HAVE_DECL_CYGWIN_CREATE_PATH /* Define to 1 if you have the declaration of `FindCloseChangeNotification', and to 0 if you don't. */ #undef HAVE_DECL_FINDCLOSECHANGENOTIFICATION /* Define to 1 if you have the declaration of `FindFirstChangeNotification', and to 0 if you don't. */ #undef HAVE_DECL_FINDFIRSTCHANGENOTIFICATION /* Define to 1 if you have the declaration of `FindNextChangeNotification', and to 0 if you don't. */ #undef HAVE_DECL_FINDNEXTCHANGENOTIFICATION /* Define to 1 if you have the declaration of `inotify_add_watch', and to 0 if you don't. */ #undef HAVE_DECL_INOTIFY_ADD_WATCH /* Define to 1 if you have the declaration of `inotify_init', and to 0 if you don't. */ #undef HAVE_DECL_INOTIFY_INIT /* Define to 1 if you have the declaration of `inotify_rm_watch', and to 0 if you don't. */ #undef HAVE_DECL_INOTIFY_RM_WATCH /* Define to 1 if you have the declaration of `kevent', and to 0 if you don't. */ #undef HAVE_DECL_KEVENT /* Define to 1 if you have the declaration of `kqueue', and to 0 if you don't. */ #undef HAVE_DECL_KQUEUE /* Define to 1 if you have the declaration of `port_create', and to 0 if you don't. */ #undef HAVE_DECL_PORT_CREATE /* Define to 1 if you have the declaration of `ReadDirectoryChangesW', and to 0 if you don't. */ #undef HAVE_DECL_READDIRECTORYCHANGESW /* Define to 1 if you have the declaration of `WaitForSingleObject', and to 0 if you don't. */ #undef HAVE_DECL_WAITFORSINGLEOBJECT /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define if the file events are supported by OS X FSEvents API. */ #undef HAVE_FSEVENTS_FILE_EVENTS /* Define to 1 if you have the header file. */ #undef HAVE_GETOPT_H /* Define to 1 if you have the `getopt_long' function. */ #undef HAVE_GETOPT_LONG /* Define if the GNU gettext() function is already present or preinstalled. */ #undef HAVE_GETTEXT /* Define if you have the iconv() function and it works. */ #undef HAVE_ICONV /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `c' library (-lc). */ #undef HAVE_LIBC /* Define to 1 if you have the `pthread' library (-lpthread). */ #undef HAVE_LIBPTHREAD /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `modf' function. */ #undef HAVE_MODF /* Define to 1 if you have the header file. */ #undef HAVE_PORT_H /* Define to 1 if you have the `realpath' function. */ #undef HAVE_REALPATH /* Define to 1 if you have the `regcomp' function. */ #undef HAVE_REGCOMP /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT /* Define to 1 if you have the `setlocale' function. */ #undef HAVE_SETLOCALE /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if `st_mtime' is a member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_MTIME /* Define to 1 if `st_mtimespec' is a member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_MTIMESPEC /* Define to 1 if you have the header file. */ #undef HAVE_SYS_CYGWIN_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_EVENT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_INOTIFY_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the header file. */ #undef HAVE_UNORDERED_MAP /* Define to 1 if you have the header file. */ #undef HAVE_UNORDERED_SET /* Windows API present. */ #undef HAVE_WINDOWS /* Define to 1 if you have the header file. */ #undef HAVE_WINDOWS_H /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL /* Define to 1 if `lstat' dereferences a symlink specified with a trailing slash. */ #undef LSTAT_FOLLOWS_SLASHED_SYMLINK /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* Define for Solaris 2.5.1 so the uint32_t typedef from , , or is not used. If the typedef were allowed, the #define below would cause a syntax error. */ #undef _UINT32_T /* Define to `int' if does not define. */ #undef mode_t /* Define to `unsigned int' if does not define. */ #undef size_t /* Define to `int' if does not define. */ #undef ssize_t /* Define to the type of an unsigned integer type of width exactly 32 bits if such a type exists and the standard includes do not define it. */ #undef uint32_t fswatch-1.11.2/README.freebsd000644 000765 000024 00000003645 13174733730 016166 0ustar00enricostaff000000 000000 README.freebsd ************** Introduction ============ This file describes the steps required to build this bundle on a supported FreeBSD system. See README for more information about the tested configurations. The kqueue-based monitor should be compatible with any *BSD release with support for kqueue. So far, however, the author has only tested this release on FreeBSD v. >= 10.0. Feedback on different *BSD systems is much appreciated and will benefit other users as well. Installation ============ See the INSTALL file for detailed information about how to configure and install fswatch. fswatch is a C++ program and a C++ compiler compliant with the C++11 standard is required to compile it. FreeBSD v. >= 10.0 ships by default with the CLang compiler suite which builds this package correctly. The GCC compiler collection shipped with FreeBSD, however, is not C++11 compliant and cannot build this package. The configure script enforces an ordered compiler search list and clang++ will be used first if available. If you do not like this choice and wish to use another compiler set the value of the CXX environment variable to the name of your compiler binary. If, for example, you wish to use the g++ compiler, then use this command to configure the build: $ ./configure CXX=g++ ----- Copyright (c) 2014-2015 Enrico M. Crisostomo 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, 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 .fswatch-1.11.2/README000644 000765 000024 00000026727 13174733730 014563 0ustar00enricostaff000000 000000 [![License](https://img.shields.io/badge/license-GPL--3.0-blue.svg?style=flat)](https://github.com/emcrisostomo/fswatch/blob/master/COPYING) README ====== `fswatch` is a file change monitor that receives notifications when the contents of the specified files or directories are modified. `fswatch` implements several monitors: * A monitor based on the _File System Events API_ of Apple OS X. * A monitor based on _kqueue_, a notification interface introduced in FreeBSD 4.1 (and supported on most *BSD systems, including OS X). * A monitor based on the _File Events Notification_ API of the Solaris kernel and its derivatives. * A monitor based on _inotify_, a Linux kernel subsystem that reports file system changes to applications. * A monitor based on _ReadDirectoryChangesW_, a Microsoft Windows API that reports changes to a directory. * A monitor which periodically stats the file system, saves file modification times in memory, and manually calculates file system changes (which works anywhere `stat (2)` can be used). `fswatch` should build and work correctly on any system shipping either of the aforementioned APIs. Table of Contents ----------------- * [libfswatch](#libfswatch) * [Features](#features) * [Limitations](#limitations) * [Getting fswatch](#getting-fswatch) * [Building from Source](#building-from-source) * [Installation](#installation) * [Documentation](#documentation) * [Localization](#localization) * [Usage](#usage) * [Contributing](#contributing) * [Bug Reports](#bug-reports) libfswatch ---------- `fswatch` is a frontend of `libfswatch`, a library with C and C++ binding. More information on `libfswatch` can be found [here][README.libfswatch.md]. [README.libfswatch.md]: README.libfswatch.md Features -------- `fswatch` main features are: * Support for many OS-specific APIs such as kevent, inotify, and FSEvents. * Recursive directory monitoring. * Path filtering using including and excluding regular expressions. * Customizable record format. * Support for periodic idle events. Limitations ----------- The limitations of `fswatch` depend largely on the monitor being used: * The **FSEvents** monitor, available only on OS X, has no known limitations, and scales very well with the number of files being observed. * The **File Events Notification** monitor, available on Solaris kernels and its derivatives, has no known limitations. * The **kqueue** monitor, available on any \*BSD system featuring kqueue, requires a file descriptor to be opened for every file being watched. As a result, this monitor scales badly with the number of files being observed, and may begin to misbehave as soon as the `fswatch` process runs out of file descriptors. In this case, `fswatch` dumps one error on standard error for every file that cannot be opened. * The **inotify** monitor, available on Linux since kernel 2.6.13, may suffer a queue overflow if events are generated faster than they are read from the queue. In any case, the application is guaranteed to receive an overflow notification which can be handled to gracefully recover. `fswatch` currently throws an exception if a queue overflow occurs. Future versions will handle the overflow by emitting proper notifications. * The **Windows** monitor can only establish a watch _directories_, not files. To watch a file, its parent directory must be watched in order to receive change events for all the directory's children, _recursively_ at any depth. Optionally, change events can be filtered to include only changes to the desired file. * The **poll** monitor, available on any platform, only relies on available CPU and memory to perform its task. The performance of this monitor degrades linearly with the number of files being watched. Usage recommendations are as follows: * On OS X, use only the `FSEvents` monitor (which is the default behaviour). * On Solaris and its derivatives use the _File Events Notification_ monitor. * On Linux, use the `inotify` monitor (which is the default behaviour). * If the number of files to observe is sufficiently small, use the `kqueue` monitor. Beware that on some systems the maximum number of file descriptors that can be opened by a process is set to a very low value (values as low as 256 are not uncommon), even if the operating system may allow a much larger value. In this case, check your OS documentation to raise this limit on either a per process or a system-wide basis. * If feasible, watch directories instead of files. Properly crafting the receiving side of the events to deal with directories may sensibly reduce the monitor resource consumption. * On Windows, use the `windows` monitor. * If none of the above applies, use the poll monitor. The authors' experience indicates that `fswatch` requires approximately 150 MB of RAM memory to observe a hierarchy of 500.000 files with a minimum path length of 32 characters. A common bottleneck of the poll monitor is disk access, since `stat()`-ing a great number of files may take a huge amount of time. In this case, the latency should be set to a sufficiently large value in order to reduce the performance degradation that may result from frequent disk access. Getting fswatch --------------- A regular user may be able to fetch `fswatch` from the package manager of your OS or a third-party one. If you are looking for `fswatch` for OS X, you can install it using either [MacPorts] or [Homebrew]: ``` # MacPorts $ port install fswatch # Homebrew $ brew install fswatch ``` Check your favourite package manager and let us know if `fswatch` is missing there. [MacPorts]: https://www.macports.org [Homebrew]: http://brew.sh Building from Source -------------------- A user who wishes to build `fswatch` should get a [release tarball][release]. A release tarball contains everything a user needs to build `fswatch` on their system, following the instructions detailed in the Installation section below and the `INSTALL` file. A developer who wishes to modify `fswatch` should get the sources (either from a source tarball or cloning the repository) and have the GNU Build System installed on their machine. Please read `README.gnu-build-system` to get further details about how to bootstrap `fswatch` from sources on your machine. Getting a copy of the source repository is not recommended unless you are a developer, you have the GNU Build System installed on your machine, and you know how to bootstrap it on the sources. [release]: https://github.com/emcrisostomo/fswatch/releases Installation ------------ See the `INSTALL` file for detailed information about how to configure and install `fswatch`. Since the `fswatch` builds and uses dynamic libraries, in some platforms you may need to perform additional tasks before you can use `fswatch`: * Make sure the installation directory of dynamic libraries (`$PREFIX/lib`) is included in the lookup paths of the dynamic linker of your operating system. The default path, `/usr/local/lib`, will work in nearly every operating system. * Refreshing the links and cache to the dynamic libraries may be required. In GNU/Linux systems you may need to run `ldconfig`: $ ldconfig `fswatch` is a C++ program and a C++ compiler compliant with the C++11 standard is required to compile it. Check your OS documentation for information about how to install the C++ toolchain and the C++ runtime. No other software packages or dependencies are required to configure and install `fswatch` but the aforementioned APIs used by the file system monitors. Documentation ------------- `fswatch` provides the following [documentation]: * Texinfo documentation, included with the distribution. * HTML documentation. * PDF documentation. * A [wiki] page. * A man page. `fswatch` official documentation is provided in Texinfo format. This is the most comprehensive source of information about `fswatch` and the only authoritative one. The man page, in particular, is a stub that suggests the user to use the info page instead. If you are installing `fswatch` using a package manager and you would like the PDF manual to be bundled into the package, please send a feature request to the package maintainer. [documentation]: http://emcrisostomo.github.io/fswatch/doc [wiki]: https://github.com/emcrisostomo/fswatch/wiki Localization ------------ `fswatch` is localizable and internally uses GNU `gettext` to decouple localizable string from their translation. The currently available locales are: * English (`en`). * Italian (`it`). * Spanish (`es`). To build `fswatch` with localization support, you need to have `gettext` installed on your system. If `configure` cannot find `` or the linker cannot find `libintl`, then you may need to manually provide their location to `configure`, usually using the `CPPFLAGS` and the `LDFLAGS` variables. See `README.osx` for an example. If `gettext` is not available on your system, `fswatch` shall build correctly, but it will lack localization support and the only available locale will be English. Usage ----- `fswatch` accepts a list of paths for which change events should be received: $ fswatch [options] ... path-0 ... path-n The event stream is created even if any of the paths do not exist yet. If they are created after `fswatch` is launched, change events will be properly received. Depending on the watcher being used, newly created paths will be monitored after the amount of configured latency has elapsed. The output of `fswatch` can be piped to other program in order to process it further: $ fswatch -0 path | while read -d "" event \ do \ // do something with ${event} done To run a command when a set of change events is printed to standard output but no event details are required, then the following command can be used: $ fswatch -o path | xargs -n1 -I{} program The behaviour is consistent with earlier versions of `fswatch` (v. 0.x). Please, read the _Compatibility Issues with fswatch v. 0.x_ section for further information. By default `fswatch` chooses the best monitor available on the current platform, in terms of performance and resource consumption. If the user wishes to specify a different monitor, the `-m` option can be used to specify the monitor by name: $ fswatch -m kqueue_monitor path The list of available monitors can be obtained with the `-h` option. For more information, refer to the `fswatch` documentation. Contributing ------------ Everybody is welcome to contribute to `fswatch`. Please, see [`CONTRIBUTING`][contrib] for further information. [contrib]: CONTRIBUTING.md Bug Reports ----------- Bug reports can be sent directly to the authors. Contact the Authors ------------------- The author can be contacted on IRC, using the Freenode `#fswatch` channel. ----- Copyright (c) 2013-2017 Enrico M. Crisostomo 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, 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 . fswatch-1.11.2/ABOUT-NLS000644 000765 000024 00000267133 13175374041 015125 0ustar00enricostaff000000 000000 1 Notes on the Free Translation Project *************************************** Free software is going international! The Free Translation Project is a way to get maintainers of free software, translators, and users all together, so that free software will gradually become able to speak many languages. A few packages already provide translations for their messages. If you found this `ABOUT-NLS' file inside a distribution, you may assume that the distributed package does use GNU `gettext' internally, itself available at your nearest GNU archive site. But you do _not_ need to install GNU `gettext' prior to configuring, installing or using this package with messages translated. Installers will find here some useful hints. These notes also explain how users should proceed for getting the programs to use the available translations. They tell how people wanting to contribute and work on translations can contact the appropriate team. 1.1 INSTALL Matters =================== Some packages are "localizable" when properly installed; the programs they contain can be made to speak your own native language. Most such packages use GNU `gettext'. Other packages have their own ways to internationalization, predating GNU `gettext'. By default, this package will be installed to allow translation of messages. It will automatically detect whether the system already provides the GNU `gettext' functions. Installers may use special options at configuration time for changing the default behaviour. The command: ./configure --disable-nls will _totally_ disable translation of messages. When you already have GNU `gettext' installed on your system and run configure without an option for your new package, `configure' will probably detect the previously built and installed `libintl' library and will decide to use it. If not, you may have to to use the `--with-libintl-prefix' option to tell `configure' where to look for it. Internationalized packages usually have many `po/LL.po' files, where LL gives an ISO 639 two-letter code identifying the language. Unless translations have been forbidden at `configure' time by using the `--disable-nls' switch, all available translations are installed together with the package. However, the environment variable `LINGUAS' may be set, prior to configuration, to limit the installed set. `LINGUAS' should then contain a space separated list of two-letter codes, stating which languages are allowed. 1.2 Using This Package ====================== As a user, if your language has been installed for this package, you only have to set the `LANG' environment variable to the appropriate `LL_CC' combination. If you happen to have the `LC_ALL' or some other `LC_xxx' environment variables set, you should unset them before setting `LANG', otherwise the setting of `LANG' will not have the desired effect. Here `LL' is an ISO 639 two-letter language code, and `CC' is an ISO 3166 two-letter country code. For example, let's suppose that you speak German and live in Germany. At the shell prompt, merely execute `setenv LANG de_DE' (in `csh'), `export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash'). This can be done from your `.login' or `.profile' file, once and for all. You might think that the country code specification is redundant. But in fact, some languages have dialects in different countries. For example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The country code serves to distinguish the dialects. The locale naming convention of `LL_CC', with `LL' denoting the language and `CC' denoting the country, is the one use on systems based on GNU libc. On other systems, some variations of this scheme are used, such as `LL' or `LL_CC.ENCODING'. You can get the list of locales supported by your system for your language by running the command `locale -a | grep '^LL''. Not all programs have translations for all languages. By default, an English message is shown in place of a nonexistent translation. If you understand other languages, you can set up a priority list of languages. This is done through a different environment variable, called `LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG' for the purpose of message handling, but you still need to have `LANG' set to the primary language; this is required by other parts of the system libraries. For example, some Swedish users who would rather read translations in German than English for when Swedish is not available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'. Special advice for Norwegian users: The language code for Norwegian bokma*l changed from `no' to `nb' recently (in 2003). During the transition period, while some message catalogs for this language are installed under `nb' and some older ones under `no', it's recommended for Norwegian users to set `LANGUAGE' to `nb:no' so that both newer and older translations are used. In the `LANGUAGE' environment variable, but not in the `LANG' environment variable, `LL_CC' combinations can be abbreviated as `LL' to denote the language's main dialect. For example, `de' is equivalent to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT' (Portuguese as spoken in Portugal) in this context. 1.3 Translating Teams ===================== For the Free Translation Project to be a success, we need interested people who like their own language and write it well, and who are also able to synergize with other translators speaking the same language. Each translation team has its own mailing list. The up-to-date list of teams can be found at the Free Translation Project's homepage, `http://translationproject.org/', in the "Teams" area. If you'd like to volunteer to _work_ at translating messages, you should become a member of the translating team for your own language. The subscribing address is _not_ the same as the list itself, it has `-request' appended. For example, speakers of Swedish can send a message to `sv-request@li.org', having this message body: subscribe Keep in mind that team members are expected to participate _actively_ in translations, or at solving translational difficulties, rather than merely lurking around. If your team does not exist yet and you want to start one, or if you are unsure about what to do or how to get started, please write to `coordinator@translationproject.org' to reach the coordinator for all translator teams. The English team is special. It works at improving and uniformizing the terminology in use. Proven linguistic skills are praised more than programming skills, here. 1.4 Available Packages ====================== Languages are not equally supported in all packages. The following matrix shows the current state of internationalization, as of June 2010. The matrix shows, in regard of each package, for which languages PO files have been submitted to translation coordination, with a translation percentage of at least 50%. Ready PO files af am an ar as ast az be be@latin bg bn_IN bs ca +--------------------------------------------------+ a2ps | [] [] | aegis | | ant-phone | | anubis | | aspell | [] [] | bash | | bfd | | bibshelf | [] | binutils | | bison | | bison-runtime | [] | bluez-pin | [] [] | bombono-dvd | | buzztard | | cflow | | clisp | | coreutils | [] [] | cpio | | cppi | | cpplib | [] | cryptsetup | | dfarc | | dialog | [] [] | dico | | diffutils | [] | dink | | doodle | | e2fsprogs | [] | enscript | [] | exif | | fetchmail | [] | findutils | [] | flex | [] | freedink | | gas | | gawk | [] [] | gcal | [] | gcc | | gettext-examples | [] [] [] [] | gettext-runtime | [] [] | gettext-tools | [] [] | gip | [] | gjay | | gliv | [] | glunarclock | [] [] | gnubiff | | gnucash | [] | gnuedu | | gnulib | | gnunet | | gnunet-gtk | | gnutls | | gold | | gpe-aerial | | gpe-beam | | gpe-bluetooth | | gpe-calendar | | gpe-clock | [] | gpe-conf | | gpe-contacts | | gpe-edit | | gpe-filemanager | | gpe-go | | gpe-login | | gpe-ownerinfo | [] | gpe-package | | gpe-sketchbook | | gpe-su | [] | gpe-taskmanager | [] | gpe-timesheet | [] | gpe-today | [] | gpe-todo | | gphoto2 | | gprof | [] | gpsdrive | | gramadoir | | grep | | grub | [] [] | gsasl | | gss | | gst-plugins-bad | [] | gst-plugins-base | [] | gst-plugins-good | [] | gst-plugins-ugly | [] | gstreamer | [] [] [] | gtick | | gtkam | [] | gtkorphan | [] | gtkspell | [] [] [] | gutenprint | | hello | [] | help2man | | hylafax | | idutils | | indent | [] [] | iso_15924 | | iso_3166 | [] [] [] [] [] [] [] | iso_3166_2 | | iso_4217 | | iso_639 | [] [] [] [] | iso_639_3 | | jwhois | | kbd | | keytouch | [] | keytouch-editor | | keytouch-keyboa... | [] | klavaro | [] | latrine | | ld | [] | leafpad | [] [] | libc | [] [] | libexif | () | libextractor | | libgnutls | | libgpewidget | | libgpg-error | | libgphoto2 | | libgphoto2_port | | libgsasl | | libiconv | [] | libidn | | lifelines | | liferea | [] [] | lilypond | | linkdr | [] | lordsawar | | lprng | | lynx | [] | m4 | | mailfromd | | mailutils | | make | | man-db | | man-db-manpages | | minicom | | mkisofs | | myserver | | nano | [] [] | opcodes | | parted | | pies | | popt | | psmisc | | pspp | [] | pwdutils | | radius | [] | recode | [] [] | rosegarden | | rpm | | rush | | sarg | | screem | | scrollkeeper | [] [] [] | sed | [] [] | sharutils | [] [] | shishi | | skencil | | solfege | | solfege-manual | | soundtracker | | sp | | sysstat | | tar | [] | texinfo | | tin | | unicode-han-tra... | | unicode-transla... | | util-linux-ng | [] | vice | | vmm | | vorbis-tools | | wastesedge | | wdiff | | wget | [] [] | wyslij-po | | xchat | [] [] [] [] | xdg-user-dirs | [] [] [] [] [] [] [] [] [] | xkeyboard-config | [] [] | +--------------------------------------------------+ af am an ar as ast az be be@latin bg bn_IN bs ca 6 0 1 2 3 19 1 10 3 28 3 1 38 crh cs da de el en en_GB en_ZA eo es et eu fa +-------------------------------------------------+ a2ps | [] [] [] [] [] [] [] | aegis | [] [] [] | ant-phone | [] () | anubis | [] [] | aspell | [] [] [] [] [] | bash | [] [] [] | bfd | [] | bibshelf | [] [] [] | binutils | [] | bison | [] [] | bison-runtime | [] [] [] [] | bluez-pin | [] [] [] [] [] [] | bombono-dvd | [] | buzztard | [] [] [] | cflow | [] [] | clisp | [] [] [] [] | coreutils | [] [] [] [] | cpio | | cppi | | cpplib | [] [] [] | cryptsetup | [] | dfarc | [] [] [] | dialog | [] [] [] [] [] | dico | | diffutils | [] [] [] [] [] [] | dink | [] [] [] | doodle | [] | e2fsprogs | [] [] [] | enscript | [] [] [] | exif | () [] [] | fetchmail | [] [] () [] [] [] | findutils | [] [] [] | flex | [] [] | freedink | [] [] [] | gas | [] | gawk | [] [] [] | gcal | [] | gcc | [] [] | gettext-examples | [] [] [] [] | gettext-runtime | [] [] [] [] | gettext-tools | [] [] [] | gip | [] [] [] [] | gjay | [] | gliv | [] [] [] | glunarclock | [] [] | gnubiff | () | gnucash | [] () () () () | gnuedu | [] [] | gnulib | [] [] | gnunet | | gnunet-gtk | [] | gnutls | [] [] | gold | [] | gpe-aerial | [] [] [] [] | gpe-beam | [] [] [] [] | gpe-bluetooth | [] [] | gpe-calendar | [] | gpe-clock | [] [] [] [] | gpe-conf | [] [] [] | gpe-contacts | [] [] [] | gpe-edit | [] [] | gpe-filemanager | [] [] [] | gpe-go | [] [] [] [] | gpe-login | [] [] | gpe-ownerinfo | [] [] [] [] | gpe-package | [] [] [] | gpe-sketchbook | [] [] [] [] | gpe-su | [] [] [] [] | gpe-taskmanager | [] [] [] [] | gpe-timesheet | [] [] [] [] | gpe-today | [] [] [] [] | gpe-todo | [] [] [] | gphoto2 | [] [] () [] [] [] | gprof | [] [] [] | gpsdrive | [] [] [] | gramadoir | [] [] [] | grep | [] | grub | [] [] | gsasl | [] | gss | | gst-plugins-bad | [] [] [] [] [] | gst-plugins-base | [] [] [] [] [] | gst-plugins-good | [] [] [] [] [] [] | gst-plugins-ugly | [] [] [] [] [] [] | gstreamer | [] [] [] [] [] | gtick | [] () [] | gtkam | [] [] () [] [] | gtkorphan | [] [] [] [] | gtkspell | [] [] [] [] [] [] [] | gutenprint | [] [] [] | hello | [] [] [] [] | help2man | [] | hylafax | [] [] | idutils | [] [] | indent | [] [] [] [] [] [] [] | iso_15924 | [] () [] [] | iso_3166 | [] [] [] [] () [] [] [] () | iso_3166_2 | () | iso_4217 | [] [] [] () [] [] | iso_639 | [] [] [] [] () [] [] | iso_639_3 | [] | jwhois | [] | kbd | [] [] [] [] [] | keytouch | [] [] | keytouch-editor | [] [] | keytouch-keyboa... | [] | klavaro | [] [] [] [] | latrine | [] () | ld | [] [] | leafpad | [] [] [] [] [] [] | libc | [] [] [] [] | libexif | [] [] () | libextractor | | libgnutls | [] | libgpewidget | [] [] | libgpg-error | [] [] | libgphoto2 | [] () | libgphoto2_port | [] () [] | libgsasl | | libiconv | [] [] [] [] [] | libidn | [] [] [] | lifelines | [] () | liferea | [] [] [] [] [] | lilypond | [] [] [] | linkdr | [] [] [] | lordsawar | [] | lprng | | lynx | [] [] [] [] | m4 | [] [] [] [] | mailfromd | | mailutils | [] | make | [] [] [] | man-db | | man-db-manpages | | minicom | [] [] [] [] | mkisofs | | myserver | | nano | [] [] [] | opcodes | [] [] | parted | [] [] | pies | | popt | [] [] [] [] [] | psmisc | [] [] [] | pspp | [] | pwdutils | [] | radius | [] | recode | [] [] [] [] [] [] | rosegarden | () () () | rpm | [] [] [] | rush | | sarg | | screem | | scrollkeeper | [] [] [] [] [] | sed | [] [] [] [] [] [] | sharutils | [] [] [] [] | shishi | | skencil | [] () [] | solfege | [] [] [] | solfege-manual | [] [] | soundtracker | [] [] [] | sp | [] | sysstat | [] [] [] | tar | [] [] [] [] | texinfo | [] [] [] | tin | [] [] | unicode-han-tra... | | unicode-transla... | | util-linux-ng | [] [] [] [] | vice | () () | vmm | [] | vorbis-tools | [] [] | wastesedge | [] | wdiff | [] [] | wget | [] [] [] | wyslij-po | | xchat | [] [] [] [] [] | xdg-user-dirs | [] [] [] [] [] [] [] [] [] | xkeyboard-config | [] [] [] [] [] [] | +-------------------------------------------------+ crh cs da de el en en_GB en_ZA eo es et eu fa 5 64 105 117 18 1 8 0 28 89 18 19 0 fi fr ga gl gu he hi hr hu hy id is it ja ka kn +----------------------------------------------------+ a2ps | [] [] [] [] | aegis | [] [] | ant-phone | [] [] | anubis | [] [] [] [] | aspell | [] [] [] [] | bash | [] [] [] [] | bfd | [] [] [] | bibshelf | [] [] [] [] [] | binutils | [] [] [] | bison | [] [] [] [] | bison-runtime | [] [] [] [] [] [] | bluez-pin | [] [] [] [] [] [] [] [] | bombono-dvd | [] | buzztard | [] | cflow | [] [] [] | clisp | [] | coreutils | [] [] [] [] [] | cpio | [] [] [] [] | cppi | [] [] | cpplib | [] [] [] | cryptsetup | [] [] [] | dfarc | [] [] [] | dialog | [] [] [] [] [] [] [] | dico | | diffutils | [] [] [] [] [] [] [] [] [] | dink | [] | doodle | [] [] | e2fsprogs | [] [] | enscript | [] [] [] [] | exif | [] [] [] [] [] [] | fetchmail | [] [] [] [] | findutils | [] [] [] [] [] [] | flex | [] [] [] | freedink | [] [] [] | gas | [] [] | gawk | [] [] [] [] () [] | gcal | [] | gcc | [] | gettext-examples | [] [] [] [] [] [] [] | gettext-runtime | [] [] [] [] [] [] | gettext-tools | [] [] [] [] | gip | [] [] [] [] [] [] | gjay | [] | gliv | [] () | glunarclock | [] [] [] [] | gnubiff | () [] () | gnucash | () () () () () [] | gnuedu | [] [] | gnulib | [] [] [] [] [] [] | gnunet | | gnunet-gtk | [] | gnutls | [] [] | gold | [] [] | gpe-aerial | [] [] [] | gpe-beam | [] [] [] [] | gpe-bluetooth | [] [] [] [] | gpe-calendar | [] [] | gpe-clock | [] [] [] [] [] | gpe-conf | [] [] [] [] | gpe-contacts | [] [] [] [] | gpe-edit | [] [] [] | gpe-filemanager | [] [] [] [] | gpe-go | [] [] [] [] [] | gpe-login | [] [] [] | gpe-ownerinfo | [] [] [] [] [] | gpe-package | [] [] [] | gpe-sketchbook | [] [] [] [] | gpe-su | [] [] [] [] [] [] | gpe-taskmanager | [] [] [] [] [] | gpe-timesheet | [] [] [] [] [] | gpe-today | [] [] [] [] [] [] [] | gpe-todo | [] [] [] | gphoto2 | [] [] [] [] [] [] | gprof | [] [] [] [] | gpsdrive | [] [] [] | gramadoir | [] [] [] | grep | [] [] | grub | [] [] [] [] | gsasl | [] [] [] [] [] | gss | [] [] [] [] [] | gst-plugins-bad | [] [] [] [] [] [] | gst-plugins-base | [] [] [] [] [] [] | gst-plugins-good | [] [] [] [] [] [] | gst-plugins-ugly | [] [] [] [] [] [] | gstreamer | [] [] [] [] [] | gtick | [] [] [] [] [] | gtkam | [] [] [] [] [] | gtkorphan | [] [] [] | gtkspell | [] [] [] [] [] [] [] [] [] | gutenprint | [] [] [] [] | hello | [] [] [] | help2man | [] [] | hylafax | [] | idutils | [] [] [] [] [] [] | indent | [] [] [] [] [] [] [] [] | iso_15924 | [] () [] [] | iso_3166 | [] () [] [] [] [] [] [] [] [] [] [] | iso_3166_2 | () [] [] [] | iso_4217 | [] () [] [] [] [] | iso_639 | [] () [] [] [] [] [] [] [] | iso_639_3 | () [] [] | jwhois | [] [] [] [] [] | kbd | [] [] | keytouch | [] [] [] [] [] [] | keytouch-editor | [] [] [] [] [] | keytouch-keyboa... | [] [] [] [] [] | klavaro | [] [] | latrine | [] [] [] | ld | [] [] [] [] | leafpad | [] [] [] [] [] [] [] () | libc | [] [] [] [] [] | libexif | [] | libextractor | | libgnutls | [] [] | libgpewidget | [] [] [] [] | libgpg-error | [] [] | libgphoto2 | [] [] [] | libgphoto2_port | [] [] [] | libgsasl | [] [] [] [] [] | libiconv | [] [] [] [] [] [] | libidn | [] [] [] [] | lifelines | () | liferea | [] [] [] [] | lilypond | [] [] | linkdr | [] [] [] [] [] | lordsawar | | lprng | [] | lynx | [] [] [] [] [] | m4 | [] [] [] [] [] [] | mailfromd | | mailutils | [] [] | make | [] [] [] [] [] [] [] [] [] | man-db | [] [] | man-db-manpages | [] | minicom | [] [] [] [] [] | mkisofs | [] [] [] [] | myserver | | nano | [] [] [] [] [] [] | opcodes | [] [] [] [] | parted | [] [] [] [] | pies | | popt | [] [] [] [] [] [] [] [] [] | psmisc | [] [] [] | pspp | | pwdutils | [] [] | radius | [] [] | recode | [] [] [] [] [] [] [] [] | rosegarden | () () () () () | rpm | [] [] | rush | | sarg | [] | screem | [] [] | scrollkeeper | [] [] [] [] | sed | [] [] [] [] [] [] [] [] | sharutils | [] [] [] [] [] [] [] | shishi | [] | skencil | [] | solfege | [] [] [] [] | solfege-manual | [] [] | soundtracker | [] [] | sp | [] () | sysstat | [] [] [] [] [] | tar | [] [] [] [] [] [] [] | texinfo | [] [] [] [] | tin | [] | unicode-han-tra... | | unicode-transla... | [] [] | util-linux-ng | [] [] [] [] [] [] | vice | () () () | vmm | [] | vorbis-tools | [] | wastesedge | () () | wdiff | [] | wget | [] [] [] [] [] [] [] [] | wyslij-po | [] [] [] | xchat | [] [] [] [] [] [] [] [] [] | xdg-user-dirs | [] [] [] [] [] [] [] [] [] [] [] [] [] | xkeyboard-config | [] [] [] [] [] | +----------------------------------------------------+ fi fr ga gl gu he hi hr hu hy id is it ja ka kn 105 121 53 20 4 8 3 5 53 2 120 5 84 67 0 4 ko ku ky lg lt lv mk ml mn mr ms mt nb nds ne +-----------------------------------------------+ a2ps | [] | aegis | | ant-phone | | anubis | [] [] | aspell | [] | bash | | bfd | | bibshelf | [] [] | binutils | | bison | [] | bison-runtime | [] [] [] [] [] | bluez-pin | [] [] [] [] [] | bombono-dvd | | buzztard | | cflow | | clisp | | coreutils | [] | cpio | | cppi | | cpplib | | cryptsetup | | dfarc | [] | dialog | [] [] [] [] [] | dico | | diffutils | [] [] | dink | | doodle | | e2fsprogs | | enscript | | exif | [] | fetchmail | | findutils | | flex | | freedink | [] | gas | | gawk | | gcal | | gcc | | gettext-examples | [] [] [] [] | gettext-runtime | [] | gettext-tools | [] | gip | [] [] | gjay | | gliv | | glunarclock | [] | gnubiff | | gnucash | () () () () | gnuedu | | gnulib | | gnunet | | gnunet-gtk | | gnutls | [] | gold | | gpe-aerial | [] | gpe-beam | [] | gpe-bluetooth | [] [] | gpe-calendar | [] | gpe-clock | [] [] [] [] [] | gpe-conf | [] [] | gpe-contacts | [] [] | gpe-edit | [] | gpe-filemanager | [] [] | gpe-go | [] [] [] | gpe-login | [] | gpe-ownerinfo | [] [] | gpe-package | [] [] | gpe-sketchbook | [] [] | gpe-su | [] [] [] [] [] [] | gpe-taskmanager | [] [] [] [] [] [] | gpe-timesheet | [] [] | gpe-today | [] [] [] [] | gpe-todo | [] [] | gphoto2 | | gprof | [] | gpsdrive | | gramadoir | | grep | | grub | | gsasl | | gss | | gst-plugins-bad | [] [] [] [] | gst-plugins-base | [] [] | gst-plugins-good | [] [] | gst-plugins-ugly | [] [] [] [] [] | gstreamer | | gtick | | gtkam | [] | gtkorphan | [] [] | gtkspell | [] [] [] [] [] [] [] | gutenprint | | hello | [] [] [] | help2man | | hylafax | | idutils | | indent | | iso_15924 | [] [] | iso_3166 | [] [] () [] [] [] [] [] | iso_3166_2 | | iso_4217 | [] [] | iso_639 | [] [] | iso_639_3 | [] | jwhois | [] | kbd | | keytouch | [] | keytouch-editor | [] | keytouch-keyboa... | [] | klavaro | [] | latrine | [] | ld | | leafpad | [] [] [] | libc | [] | libexif | | libextractor | | libgnutls | [] | libgpewidget | [] [] | libgpg-error | | libgphoto2 | | libgphoto2_port | | libgsasl | | libiconv | | libidn | | lifelines | | liferea | | lilypond | | linkdr | | lordsawar | | lprng | | lynx | | m4 | | mailfromd | | mailutils | | make | [] | man-db | | man-db-manpages | | minicom | [] | mkisofs | | myserver | | nano | [] [] | opcodes | | parted | | pies | | popt | [] [] [] | psmisc | | pspp | | pwdutils | | radius | | recode | | rosegarden | | rpm | | rush | | sarg | | screem | | scrollkeeper | [] [] | sed | | sharutils | | shishi | | skencil | | solfege | [] | solfege-manual | | soundtracker | | sp | | sysstat | [] | tar | [] | texinfo | [] | tin | | unicode-han-tra... | | unicode-transla... | | util-linux-ng | | vice | | vmm | | vorbis-tools | | wastesedge | | wdiff | | wget | [] | wyslij-po | | xchat | [] [] [] | xdg-user-dirs | [] [] [] [] [] [] [] [] | xkeyboard-config | [] [] [] | +-----------------------------------------------+ ko ku ky lg lt lv mk ml mn mr ms mt nb nds ne 20 5 10 1 13 48 4 2 2 4 24 10 20 3 1 nl nn or pa pl ps pt pt_BR ro ru rw sk sl sq sr +---------------------------------------------------+ a2ps | [] [] [] [] [] [] [] [] | aegis | [] [] [] | ant-phone | [] [] | anubis | [] [] [] | aspell | [] [] [] [] [] | bash | [] [] | bfd | [] | bibshelf | [] [] | binutils | [] [] | bison | [] [] [] | bison-runtime | [] [] [] [] [] [] [] | bluez-pin | [] [] [] [] [] [] [] [] | bombono-dvd | [] () | buzztard | [] [] | cflow | [] | clisp | [] [] | coreutils | [] [] [] [] [] [] | cpio | [] [] [] | cppi | [] | cpplib | [] | cryptsetup | [] | dfarc | [] | dialog | [] [] [] [] | dico | [] | diffutils | [] [] [] [] [] [] | dink | () | doodle | [] [] | e2fsprogs | [] [] | enscript | [] [] [] [] [] | exif | [] [] [] () [] | fetchmail | [] [] [] [] | findutils | [] [] [] [] [] | flex | [] [] [] [] [] | freedink | [] [] | gas | | gawk | [] [] [] [] | gcal | | gcc | [] | gettext-examples | [] [] [] [] [] [] [] [] | gettext-runtime | [] [] [] [] [] [] [] [] [] | gettext-tools | [] [] [] [] [] [] | gip | [] [] [] [] [] | gjay | | gliv | [] [] [] [] [] [] | glunarclock | [] [] [] [] [] | gnubiff | [] () | gnucash | [] () () () | gnuedu | [] | gnulib | [] [] [] [] | gnunet | | gnunet-gtk | | gnutls | [] [] | gold | | gpe-aerial | [] [] [] [] [] [] [] | gpe-beam | [] [] [] [] [] [] [] | gpe-bluetooth | [] [] | gpe-calendar | [] [] [] [] | gpe-clock | [] [] [] [] [] [] [] [] | gpe-conf | [] [] [] [] [] [] [] | gpe-contacts | [] [] [] [] [] | gpe-edit | [] [] [] | gpe-filemanager | [] [] [] | gpe-go | [] [] [] [] [] [] [] [] | gpe-login | [] [] | gpe-ownerinfo | [] [] [] [] [] [] [] [] | gpe-package | [] [] | gpe-sketchbook | [] [] [] [] [] [] [] | gpe-su | [] [] [] [] [] [] [] [] | gpe-taskmanager | [] [] [] [] [] [] [] [] | gpe-timesheet | [] [] [] [] [] [] [] [] | gpe-today | [] [] [] [] [] [] [] [] | gpe-todo | [] [] [] [] [] | gphoto2 | [] [] [] [] [] [] [] [] | gprof | [] [] [] | gpsdrive | [] [] | gramadoir | [] [] | grep | [] [] [] [] | grub | [] [] [] | gsasl | [] [] [] [] | gss | [] [] [] | gst-plugins-bad | [] [] [] [] [] [] | gst-plugins-base | [] [] [] [] [] | gst-plugins-good | [] [] [] [] [] | gst-plugins-ugly | [] [] [] [] [] [] | gstreamer | [] [] [] [] [] | gtick | [] [] [] | gtkam | [] [] [] [] [] [] | gtkorphan | [] | gtkspell | [] [] [] [] [] [] [] [] [] [] | gutenprint | [] [] | hello | [] [] [] [] | help2man | [] [] | hylafax | [] | idutils | [] [] [] [] [] | indent | [] [] [] [] [] [] [] | iso_15924 | [] [] [] [] | iso_3166 | [] [] [] [] [] () [] [] [] [] [] [] [] [] | iso_3166_2 | [] [] [] | iso_4217 | [] [] [] [] [] [] [] [] | iso_639 | [] [] [] [] [] [] [] [] [] | iso_639_3 | [] [] | jwhois | [] [] [] [] | kbd | [] [] [] | keytouch | [] [] [] | keytouch-editor | [] [] [] | keytouch-keyboa... | [] [] [] | klavaro | [] [] | latrine | [] [] | ld | | leafpad | [] [] [] [] [] [] [] [] [] | libc | [] [] [] [] | libexif | [] [] () [] | libextractor | | libgnutls | [] [] | libgpewidget | [] [] [] | libgpg-error | [] [] | libgphoto2 | [] [] | libgphoto2_port | [] [] [] [] [] | libgsasl | [] [] [] [] [] | libiconv | [] [] [] [] [] | libidn | [] [] | lifelines | [] [] | liferea | [] [] [] [] [] () () [] | lilypond | [] | linkdr | [] [] [] | lordsawar | | lprng | [] | lynx | [] [] [] | m4 | [] [] [] [] [] | mailfromd | [] | mailutils | [] | make | [] [] [] [] | man-db | [] [] [] | man-db-manpages | [] [] [] | minicom | [] [] [] [] | mkisofs | [] [] [] | myserver | | nano | [] [] [] [] | opcodes | [] [] | parted | [] [] [] [] | pies | [] | popt | [] [] [] [] | psmisc | [] [] [] | pspp | [] [] | pwdutils | [] | radius | [] [] [] | recode | [] [] [] [] [] [] [] [] | rosegarden | () () | rpm | [] [] [] | rush | [] [] | sarg | | screem | | scrollkeeper | [] [] [] [] [] [] [] [] | sed | [] [] [] [] [] [] [] [] [] | sharutils | [] [] [] [] | shishi | [] | skencil | [] [] | solfege | [] [] [] [] | solfege-manual | [] [] [] | soundtracker | [] | sp | | sysstat | [] [] [] [] | tar | [] [] [] [] | texinfo | [] [] [] [] | tin | [] | unicode-han-tra... | | unicode-transla... | | util-linux-ng | [] [] [] [] [] | vice | [] | vmm | [] | vorbis-tools | [] [] | wastesedge | [] | wdiff | [] [] | wget | [] [] [] [] [] [] [] | wyslij-po | [] [] [] | xchat | [] [] [] [] [] [] [] [] [] | xdg-user-dirs | [] [] [] [] [] [] [] [] [] [] [] [] [] [] | xkeyboard-config | [] [] [] | +---------------------------------------------------+ nl nn or pa pl ps pt pt_BR ro ru rw sk sl sq sr 135 10 4 7 105 1 29 62 47 91 3 54 46 9 37 sv sw ta te tg th tr uk vi wa zh_CN zh_HK zh_TW +---------------------------------------------------+ a2ps | [] [] [] [] [] | 27 aegis | [] | 9 ant-phone | [] [] [] [] | 9 anubis | [] [] [] [] | 15 aspell | [] [] [] | 20 bash | [] [] [] | 12 bfd | [] | 6 bibshelf | [] [] [] | 16 binutils | [] [] | 8 bison | [] [] | 12 bison-runtime | [] [] [] [] [] [] | 29 bluez-pin | [] [] [] [] [] [] [] [] | 37 bombono-dvd | [] | 4 buzztard | [] | 7 cflow | [] [] [] | 9 clisp | | 10 coreutils | [] [] [] [] | 22 cpio | [] [] [] [] [] [] | 13 cppi | [] [] | 5 cpplib | [] [] [] [] [] [] | 14 cryptsetup | [] [] | 7 dfarc | [] | 9 dialog | [] [] [] [] [] [] [] | 30 dico | [] | 2 diffutils | [] [] [] [] [] [] | 30 dink | | 4 doodle | [] [] | 7 e2fsprogs | [] [] [] | 11 enscript | [] [] [] [] | 17 exif | [] [] [] | 16 fetchmail | [] [] [] | 17 findutils | [] [] [] [] [] | 20 flex | [] [] [] [] | 15 freedink | [] | 10 gas | [] | 4 gawk | [] [] [] [] | 18 gcal | [] [] | 5 gcc | [] [] [] | 7 gettext-examples | [] [] [] [] [] [] [] | 34 gettext-runtime | [] [] [] [] [] [] [] | 29 gettext-tools | [] [] [] [] [] [] | 22 gip | [] [] [] [] | 22 gjay | [] | 3 gliv | [] [] [] | 14 glunarclock | [] [] [] [] [] | 19 gnubiff | [] [] | 4 gnucash | () [] () [] () | 10 gnuedu | [] [] | 7 gnulib | [] [] [] [] | 16 gnunet | [] | 1 gnunet-gtk | [] [] [] | 5 gnutls | [] [] [] | 10 gold | [] | 4 gpe-aerial | [] [] [] | 18 gpe-beam | [] [] [] | 19 gpe-bluetooth | [] [] [] | 13 gpe-calendar | [] [] [] [] | 12 gpe-clock | [] [] [] [] [] | 28 gpe-conf | [] [] [] [] | 20 gpe-contacts | [] [] [] | 17 gpe-edit | [] [] [] | 12 gpe-filemanager | [] [] [] [] | 16 gpe-go | [] [] [] [] [] | 25 gpe-login | [] [] [] | 11 gpe-ownerinfo | [] [] [] [] [] | 25 gpe-package | [] [] [] | 13 gpe-sketchbook | [] [] [] | 20 gpe-su | [] [] [] [] [] | 30 gpe-taskmanager | [] [] [] [] [] | 29 gpe-timesheet | [] [] [] [] [] | 25 gpe-today | [] [] [] [] [] [] | 30 gpe-todo | [] [] [] [] | 17 gphoto2 | [] [] [] [] [] | 24 gprof | [] [] [] | 15 gpsdrive | [] [] [] | 11 gramadoir | [] [] [] | 11 grep | [] [] [] | 10 grub | [] [] [] | 14 gsasl | [] [] [] [] | 14 gss | [] [] [] | 11 gst-plugins-bad | [] [] [] [] | 26 gst-plugins-base | [] [] [] [] [] | 24 gst-plugins-good | [] [] [] [] | 24 gst-plugins-ugly | [] [] [] [] [] | 29 gstreamer | [] [] [] [] | 22 gtick | [] [] [] | 13 gtkam | [] [] [] | 20 gtkorphan | [] [] [] | 14 gtkspell | [] [] [] [] [] [] [] [] [] | 45 gutenprint | [] | 10 hello | [] [] [] [] [] [] | 21 help2man | [] [] | 7 hylafax | [] | 5 idutils | [] [] [] [] | 17 indent | [] [] [] [] [] [] | 30 iso_15924 | () [] () [] [] | 16 iso_3166 | [] [] () [] [] () [] [] [] () | 53 iso_3166_2 | () [] () [] | 9 iso_4217 | [] () [] [] () [] [] | 26 iso_639 | [] [] [] () [] () [] [] [] [] | 38 iso_639_3 | [] () | 8 jwhois | [] [] [] [] [] | 16 kbd | [] [] [] [] [] | 15 keytouch | [] [] [] | 16 keytouch-editor | [] [] [] | 14 keytouch-keyboa... | [] [] [] | 14 klavaro | [] | 11 latrine | [] [] [] | 10 ld | [] [] [] [] | 11 leafpad | [] [] [] [] [] [] | 33 libc | [] [] [] [] [] | 21 libexif | [] () | 7 libextractor | [] | 1 libgnutls | [] [] [] | 9 libgpewidget | [] [] [] | 14 libgpg-error | [] [] [] | 9 libgphoto2 | [] [] | 8 libgphoto2_port | [] [] [] [] | 14 libgsasl | [] [] [] | 13 libiconv | [] [] [] [] | 21 libidn | () [] [] | 11 lifelines | [] | 4 liferea | [] [] [] | 21 lilypond | [] | 7 linkdr | [] [] [] [] [] | 17 lordsawar | | 1 lprng | [] | 3 lynx | [] [] [] [] | 17 m4 | [] [] [] [] | 19 mailfromd | [] [] | 3 mailutils | [] | 5 make | [] [] [] [] | 21 man-db | [] [] [] | 8 man-db-manpages | | 4 minicom | [] [] | 16 mkisofs | [] [] | 9 myserver | | 0 nano | [] [] [] [] | 21 opcodes | [] [] [] | 11 parted | [] [] [] [] [] | 15 pies | [] [] | 3 popt | [] [] [] [] [] [] | 27 psmisc | [] [] | 11 pspp | | 4 pwdutils | [] [] | 6 radius | [] [] | 9 recode | [] [] [] [] | 28 rosegarden | () | 0 rpm | [] [] [] | 11 rush | [] [] | 4 sarg | | 1 screem | [] | 3 scrollkeeper | [] [] [] [] [] | 27 sed | [] [] [] [] [] | 30 sharutils | [] [] [] [] [] | 22 shishi | [] | 3 skencil | [] [] | 7 solfege | [] [] [] [] | 16 solfege-manual | [] | 8 soundtracker | [] [] [] | 9 sp | [] | 3 sysstat | [] [] | 15 tar | [] [] [] [] [] [] | 23 texinfo | [] [] [] [] [] | 17 tin | | 4 unicode-han-tra... | | 0 unicode-transla... | | 2 util-linux-ng | [] [] [] [] | 20 vice | () () | 1 vmm | [] | 4 vorbis-tools | [] | 6 wastesedge | | 2 wdiff | [] [] | 7 wget | [] [] [] [] [] | 26 wyslij-po | [] [] | 8 xchat | [] [] [] [] [] [] | 36 xdg-user-dirs | [] [] [] [] [] [] [] [] [] [] | 63 xkeyboard-config | [] [] [] | 22 +---------------------------------------------------+ 85 teams sv sw ta te tg th tr uk vi wa zh_CN zh_HK zh_TW 178 domains 119 1 3 3 0 10 65 51 155 17 98 7 41 2618 Some counters in the preceding matrix are higher than the number of visible blocks let us expect. This is because a few extra PO files are used for implementing regional variants of languages, or language dialects. For a PO file in the matrix above to be effective, the package to which it applies should also have been internationalized and distributed as such by its maintainer. There might be an observable lag between the mere existence a PO file and its wide availability in a distribution. If June 2010 seems to be old, you may fetch a more recent copy of this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date matrix with full percentage details can be found at `http://translationproject.org/extra/matrix.html'. 1.5 Using `gettext' in new packages =================================== If you are writing a freely available program and want to internationalize it you are welcome to use GNU `gettext' in your package. Of course you have to respect the GNU Library General Public License which covers the use of the GNU `gettext' library. This means in particular that even non-free programs can use `libintl' as a shared library, whereas only free software can use `libintl' as a static library or use modified versions of `libintl'. Once the sources are changed appropriately and the setup can handle the use of `gettext' the only thing missing are the translations. The Free Translation Project is also available for packages which are not developed inside the GNU project. Therefore the information given above applies also for every other Free Software Project. Contact `coordinator@translationproject.org' to make the `.pot' files available to the translation teams. fswatch-1.11.2/Makefile.am000644 000765 000024 00000003573 13175367735 015742 0ustar00enricostaff000000 000000 # # Copyright (c) 2014-2017 Enrico M. Crisostomo # # 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, 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 . # ACLOCAL_AMFLAGS = -I m4 # Refresh configuration if libtool dependencies change LIBTOOL_DEPS = @LIBTOOL_DEPS@ libtool: $(LIBTOOL_DEPS) $(SHELL) $(top_builddir)/config.status libtool if USE_NLS FSW_PO_SUBDIR = po endif SUBDIRS = libfswatch fswatch $(FSW_PO_SUBDIR) dist_man_MANS = man/fswatch.7 dist_doc_DATA = README.bsd dist_doc_DATA += README.codestyle dist_doc_DATA += README.freebsd dist_doc_DATA += README.gnu-build-system dist_doc_DATA += README.illumos dist_doc_DATA += README.md dist_doc_DATA += README.libfswatch.md dist_doc_DATA += README.linux dist_doc_DATA += README.osx dist_doc_DATA += README.smartos dist_doc_DATA += README.solaris dist_doc_DATA += README.windows if USE_NLS dist_doc_DATA += ABOUT-NLS endif dist_doc_DATA += AUTHORS dist_doc_DATA += CONTRIBUTING.md dist_doc_DATA += COPYING dist_doc_DATA += NEWS dist_doc_DATA += AUTHORS.libfswatch dist_doc_DATA += NEWS.libfswatch dist-hook: # The recipe cannot assume a file in $(distdir) is writable. chmod u+w $(distdir)/ChangeLog git log --oneline --decorate >> $(distdir)/ChangeLog # Manually distributing config.rpath seems not to be required any longer with # current Autotools. # # EXTRA_DIST = config/config.rpath docker-images: ./docker/build-images.sh fswatch-1.11.2/README.md000644 000765 000024 00000026727 13174733730 015162 0ustar00enricostaff000000 000000 [![License](https://img.shields.io/badge/license-GPL--3.0-blue.svg?style=flat)](https://github.com/emcrisostomo/fswatch/blob/master/COPYING) README ====== `fswatch` is a file change monitor that receives notifications when the contents of the specified files or directories are modified. `fswatch` implements several monitors: * A monitor based on the _File System Events API_ of Apple OS X. * A monitor based on _kqueue_, a notification interface introduced in FreeBSD 4.1 (and supported on most *BSD systems, including OS X). * A monitor based on the _File Events Notification_ API of the Solaris kernel and its derivatives. * A monitor based on _inotify_, a Linux kernel subsystem that reports file system changes to applications. * A monitor based on _ReadDirectoryChangesW_, a Microsoft Windows API that reports changes to a directory. * A monitor which periodically stats the file system, saves file modification times in memory, and manually calculates file system changes (which works anywhere `stat (2)` can be used). `fswatch` should build and work correctly on any system shipping either of the aforementioned APIs. Table of Contents ----------------- * [libfswatch](#libfswatch) * [Features](#features) * [Limitations](#limitations) * [Getting fswatch](#getting-fswatch) * [Building from Source](#building-from-source) * [Installation](#installation) * [Documentation](#documentation) * [Localization](#localization) * [Usage](#usage) * [Contributing](#contributing) * [Bug Reports](#bug-reports) libfswatch ---------- `fswatch` is a frontend of `libfswatch`, a library with C and C++ binding. More information on `libfswatch` can be found [here][README.libfswatch.md]. [README.libfswatch.md]: README.libfswatch.md Features -------- `fswatch` main features are: * Support for many OS-specific APIs such as kevent, inotify, and FSEvents. * Recursive directory monitoring. * Path filtering using including and excluding regular expressions. * Customizable record format. * Support for periodic idle events. Limitations ----------- The limitations of `fswatch` depend largely on the monitor being used: * The **FSEvents** monitor, available only on OS X, has no known limitations, and scales very well with the number of files being observed. * The **File Events Notification** monitor, available on Solaris kernels and its derivatives, has no known limitations. * The **kqueue** monitor, available on any \*BSD system featuring kqueue, requires a file descriptor to be opened for every file being watched. As a result, this monitor scales badly with the number of files being observed, and may begin to misbehave as soon as the `fswatch` process runs out of file descriptors. In this case, `fswatch` dumps one error on standard error for every file that cannot be opened. * The **inotify** monitor, available on Linux since kernel 2.6.13, may suffer a queue overflow if events are generated faster than they are read from the queue. In any case, the application is guaranteed to receive an overflow notification which can be handled to gracefully recover. `fswatch` currently throws an exception if a queue overflow occurs. Future versions will handle the overflow by emitting proper notifications. * The **Windows** monitor can only establish a watch _directories_, not files. To watch a file, its parent directory must be watched in order to receive change events for all the directory's children, _recursively_ at any depth. Optionally, change events can be filtered to include only changes to the desired file. * The **poll** monitor, available on any platform, only relies on available CPU and memory to perform its task. The performance of this monitor degrades linearly with the number of files being watched. Usage recommendations are as follows: * On OS X, use only the `FSEvents` monitor (which is the default behaviour). * On Solaris and its derivatives use the _File Events Notification_ monitor. * On Linux, use the `inotify` monitor (which is the default behaviour). * If the number of files to observe is sufficiently small, use the `kqueue` monitor. Beware that on some systems the maximum number of file descriptors that can be opened by a process is set to a very low value (values as low as 256 are not uncommon), even if the operating system may allow a much larger value. In this case, check your OS documentation to raise this limit on either a per process or a system-wide basis. * If feasible, watch directories instead of files. Properly crafting the receiving side of the events to deal with directories may sensibly reduce the monitor resource consumption. * On Windows, use the `windows` monitor. * If none of the above applies, use the poll monitor. The authors' experience indicates that `fswatch` requires approximately 150 MB of RAM memory to observe a hierarchy of 500.000 files with a minimum path length of 32 characters. A common bottleneck of the poll monitor is disk access, since `stat()`-ing a great number of files may take a huge amount of time. In this case, the latency should be set to a sufficiently large value in order to reduce the performance degradation that may result from frequent disk access. Getting fswatch --------------- A regular user may be able to fetch `fswatch` from the package manager of your OS or a third-party one. If you are looking for `fswatch` for OS X, you can install it using either [MacPorts] or [Homebrew]: ``` # MacPorts $ port install fswatch # Homebrew $ brew install fswatch ``` Check your favourite package manager and let us know if `fswatch` is missing there. [MacPorts]: https://www.macports.org [Homebrew]: http://brew.sh Building from Source -------------------- A user who wishes to build `fswatch` should get a [release tarball][release]. A release tarball contains everything a user needs to build `fswatch` on their system, following the instructions detailed in the Installation section below and the `INSTALL` file. A developer who wishes to modify `fswatch` should get the sources (either from a source tarball or cloning the repository) and have the GNU Build System installed on their machine. Please read `README.gnu-build-system` to get further details about how to bootstrap `fswatch` from sources on your machine. Getting a copy of the source repository is not recommended unless you are a developer, you have the GNU Build System installed on your machine, and you know how to bootstrap it on the sources. [release]: https://github.com/emcrisostomo/fswatch/releases Installation ------------ See the `INSTALL` file for detailed information about how to configure and install `fswatch`. Since the `fswatch` builds and uses dynamic libraries, in some platforms you may need to perform additional tasks before you can use `fswatch`: * Make sure the installation directory of dynamic libraries (`$PREFIX/lib`) is included in the lookup paths of the dynamic linker of your operating system. The default path, `/usr/local/lib`, will work in nearly every operating system. * Refreshing the links and cache to the dynamic libraries may be required. In GNU/Linux systems you may need to run `ldconfig`: $ ldconfig `fswatch` is a C++ program and a C++ compiler compliant with the C++11 standard is required to compile it. Check your OS documentation for information about how to install the C++ toolchain and the C++ runtime. No other software packages or dependencies are required to configure and install `fswatch` but the aforementioned APIs used by the file system monitors. Documentation ------------- `fswatch` provides the following [documentation]: * Texinfo documentation, included with the distribution. * HTML documentation. * PDF documentation. * A [wiki] page. * A man page. `fswatch` official documentation is provided in Texinfo format. This is the most comprehensive source of information about `fswatch` and the only authoritative one. The man page, in particular, is a stub that suggests the user to use the info page instead. If you are installing `fswatch` using a package manager and you would like the PDF manual to be bundled into the package, please send a feature request to the package maintainer. [documentation]: http://emcrisostomo.github.io/fswatch/doc [wiki]: https://github.com/emcrisostomo/fswatch/wiki Localization ------------ `fswatch` is localizable and internally uses GNU `gettext` to decouple localizable string from their translation. The currently available locales are: * English (`en`). * Italian (`it`). * Spanish (`es`). To build `fswatch` with localization support, you need to have `gettext` installed on your system. If `configure` cannot find `` or the linker cannot find `libintl`, then you may need to manually provide their location to `configure`, usually using the `CPPFLAGS` and the `LDFLAGS` variables. See `README.osx` for an example. If `gettext` is not available on your system, `fswatch` shall build correctly, but it will lack localization support and the only available locale will be English. Usage ----- `fswatch` accepts a list of paths for which change events should be received: $ fswatch [options] ... path-0 ... path-n The event stream is created even if any of the paths do not exist yet. If they are created after `fswatch` is launched, change events will be properly received. Depending on the watcher being used, newly created paths will be monitored after the amount of configured latency has elapsed. The output of `fswatch` can be piped to other program in order to process it further: $ fswatch -0 path | while read -d "" event \ do \ // do something with ${event} done To run a command when a set of change events is printed to standard output but no event details are required, then the following command can be used: $ fswatch -o path | xargs -n1 -I{} program The behaviour is consistent with earlier versions of `fswatch` (v. 0.x). Please, read the _Compatibility Issues with fswatch v. 0.x_ section for further information. By default `fswatch` chooses the best monitor available on the current platform, in terms of performance and resource consumption. If the user wishes to specify a different monitor, the `-m` option can be used to specify the monitor by name: $ fswatch -m kqueue_monitor path The list of available monitors can be obtained with the `-h` option. For more information, refer to the `fswatch` documentation. Contributing ------------ Everybody is welcome to contribute to `fswatch`. Please, see [`CONTRIBUTING`][contrib] for further information. [contrib]: CONTRIBUTING.md Bug Reports ----------- Bug reports can be sent directly to the authors. Contact the Authors ------------------- The author can be contacted on IRC, using the Freenode `#fswatch` channel. ----- Copyright (c) 2013-2017 Enrico M. Crisostomo 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, 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 . fswatch-1.11.2/COPYING000644 000765 000024 00000104513 13174733730 014724 0ustar00enricostaff000000 000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . fswatch-1.11.2/README.gnu-build-system000644 000765 000024 00000005677 13174733730 017773 0ustar00enricostaff000000 000000 README.gnu-build-system ======================= Introduction ------------ `fswatch` is built using the GNU Build System (a.k.a. the Autotools) and developers willing to modify the configuration files must have the GNU Build System installed in order to do so. For further information about the GNU Build System and its use, please refer to its official documentation. Installing the GNU Build System ------------------------------- To install the GNU Build System, the following operations must be performed: * Get the GNU Build System components: - [Autoconf] (>= v. 2.69). - [Automake]: (>= v. 1.14.1). - [Libtool]: (>= v. 2.4.2). - [Gettext]: (>= v. 0.19.4). * Install the packages in the following order: - Autoconf - Automake - Libtool - Gettext * From now on, `` will indicate any of the above-mentioned components. * Grab the sources: $ wget * Uncompress the source bundle: $ gunzip .tar.gz $ tar -xf .tar * Configure the GNU Build System using the provided `autogen.sh` script: $ ./autogen.sh Whenever any component of the GNU Build System is updated, the `--force` option should be passed to `autogen.sh`, which in turn forwards it to `autoreconf`, to make sure that automatically generated scripts and macros are updated: $ ./autogen.sh --force * Configure the package: $ ./configure [...] * If you want to install the package in the default location (`/usr/local/bin`) you can invoke `./configure` with no option, otherwise provide the desired installation directory using the `--prefix` option: $ ./configure --prefix=/destdir * Build the package: $ make * Test the components: $ make check * Test the installed components: $ make check * Install the components: $ make install Depending on the installation directory additional privileges may be required. * Add the installation directory to the `PATH`, otherwise builds of the package may fail: $ export PATH=/destdir/bin:$PATH [Autoconf]: https://www.gnu.org/software/autoconf/ [Automake]: https://www.gnu.org/software/automake/ [Libtool]: https://www.gnu.org/software/libtool/ [Gettext]: https://www.gnu.org/software/gettext/ ----- Copyright (c) 2014-2017 Enrico M. Crisostomo 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, 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 . fswatch-1.11.2/po/000755 000765 000024 00000000000 13175374113 014300 5ustar00enricostaff000000 000000 fswatch-1.11.2/NEWS000644 000765 000024 00000014143 13175372713 014370 0ustar00enricostaff000000 000000 NEWS **** New in 1.11.2: * Issue 182: Generate a single message catalog for both fswatch and libfswatch. New in 1.11.1: * Issue 182: Remove mandatory dependency to git. New in 1.11.0: * Issue 174: Allow a numeric event mask to be specified. * Issue 181: Make gettext an optional dependency. New in 1.10.0: * Issue 60: Allow excluding file patterns by passing in a file. * Issue 119: Merge fswatch and libfswatch Autotools project into one. * Issue 141: Add Docker files for Linux distributions used for testing. * Add target to build fswatch on Alpine Linux and Debian. New in 1.9.3: * Only libfswatch has been updated. New in 1.9.2: * Issue 118: v. 1.9.0 breaks the -1 option. New in 1.9.1: * Only libfswatch has been updated. New in 1.9.0: * Issue 84: Add the possibility of scheduling a periodic event. * Issue 114: fswatch does not track newly created directories recursively when using the inotify monitor. * The AX_CXX_COMPILE_STDCXX macro was patched so that the switches it adds to the compiler are added to the preprocessor configuration as well. New in 1.8.0: * Unsupported CMake files and CLion project files are included as a courtesy. New in 1.7.0: * Issue 35: Support Solaris/Illumos File Events Notification API. * Issue 98: Add (-d, --directories) option to request the monitor to watch directories only during a recursive scan. * Issue 99: A monitor using the File Events Notification API of the Solaris/Illumos kernel has been added. * Issue 101: Add flag to watch file accesses. New in 1.6.1: * Texinfo documentation now includes @dircategory and @direntry tags to be compatible with install-info. New in 1.6.0: * fswatch can now be built on Microsoft Windows using Cygwin. * A monitor for Microsoft Windows has been added. * fswatch can report monitor buffer overflows (which cannot be avoided with certain monitors) as regular events for callers to recover gracefully. * Monitors can be customized by passing monitor-specific configuration properties. New in 1.5.1: * fswatch-run scripts have been removed. * Dependency on at least one supported shell (Zsh or Bash) has been removed. * Fixes Issue 91: Can't compile fswatch 1.5.0 on FreeBSD 9.3-RELEASE. New in 1.5.0: * Fix issue 46: Allow filtering by event type. New in 1.4.7: * Fix bug in exclusion filter ordering (PR 75). * README.md improvements. * Documentation improvements. New in 1.4.6: * Fix issue 74: Assertion failed on fsw_destroy_session. New in 1.4.5.3: * Fix issue 67: 100% CPU usage while using libfswatch. This issue only affects the inotify monitor, available only on Linux. New in 1.4.5.2: * Fix issue 66: Exclude items with poll_monitor not considered. New in 1.4.5.1: * Do not distribute wrapper scripts for shells which are not installed (the FreeBSD port system checks shebangs and complains). New in 1.4.5: * Add custom record formats. New in 1.4.4: * Localize fswatch and libfswatch using GNU gettext. * Add Italian (it) localization. * Add Spanish (es) localization. New in 1.4.3.2: * Fix Makefile.am because of broken link when DESTDIR installs are performed. New in 1.4.3.1: * Fix bug in fswatch-run wrapper script for ZSH which caused last argument not to be split when passed to xargs. New in 1.4.3: * Add batch marker feature to delimit the boundaries of a batch of events. * Add Texinfo documentation. * libfswatch API is now versioned. * Improved Autoconf checks. * The inotify monitor now waits for events and honours the latency settings. * Automaticaly generate the ChangeLog using Git. * Update autogen.sh to honour some commonly used environment variables. New in 1.4.2: * The inotify monitor now provides the same functionality provided by all the other monitors. Recursive directory monitoring is now implemented. * Version and revision is now determined dynamically from Git by ancillary scripts invoked by the GNU Build System. New in 1.4.1.1: * fswatch does not compile on OS X < 10.9 because some required C++11 classes are not supported by the C++ runtime. New in 1.4.1: * fswatch does not compile on OS X < 10.9 because some required C++11 classes are not supported by the C++ runtime. New in 1.4.0: * The libfswatch library has been added with bindings for C and C++. * fswatch let users specify the monitor to use by name. New in 1.3.9: * Fix Issue 23: Add `--include [regex]` option. * Fix Issue 25: Add `--include [regex]` option. * Paths can be included using -i/--include and providing a set of regular expressions. New in 1.3.8: * Fix Issue 34: Diagnostic messages were output by the inotify monitor even if fswatch was not run in verbose mode. New in 1.3.7: * Fix Issue 32: Problems building fswatch 1.3.6 on Mac v10.8.5 * Remove usages of C++11 initializer lists so that fswatch builds with older compiler. New in 1.3.6: * Fix Issue 26: fswatch-run can't run a command with arguments. * fswatch-run scripts are provided for ZSH and Bash. * System is scanned during installation to check for ZSH and Bash availability. Path of found shells is substituted in the corresponding scripts, otherwise the default /bin/[shell] is used. * If a supported shell is found, the fswatch-run symbolic link is created in the installation directory to the corresponding script. The lookup order of the shells is: - ZSH. - Bash. New in 1.3.5: * Fix Issue 27: Redirect usage text to standard error unless `-h` or `--help`. * Fix bug to write usage to standard error when invalid arguments are specified. New in 1.3.4: * Fix bug in fswatch-run script to allow arguments to be passed to the command to run. New in 1.3.3: * Add -o/--one-per-batch option to print a single message with the number of change events in the current batch. * Add fswatch-run shell script to mimic the behaviour of earlier fswatch versions and launch the specified command when change events are received. New in 1.3.2: * fswatch has been merged with fsw (https://github.com/emcrisostomo/fsw). fswatch-1.11.2/README.linux000644 000765 000024 00000003763 13174733730 015714 0ustar00enricostaff000000 000000 README.linux ************ Introduction ============ This file describes the steps required to build fswatch on a supported GNU/Linux system. The supported monitors on GNU/Linux systems are: * The inotify monitor (on Linux kernels > 2.6.13). * The poll monitor. The availability of the inotify API is checked by configure and it will be built into fswatch when found. When available, the inotify monitor is the default choice on GNU/Linux systems. The list of monitors built into libfswatch can be read in the help message of fswatch: $ fswatch --help Installation ============ See the INSTALL file for detailed information about how to configure and install fswatch. fswatch is a C++ program and a C++ compiler compliant with the C++11 standard is required to compile it. Reasonably recent GNU/Linux distributions usually ship at least two such compilers: * GCC. * Clang. Please, check your distribution documentation to find an appropriate C++ compiler and how to install it. The configure script enforces an ordered compiler search list and clang++ will be used first if available. If you do not like this choice and wish to use another compiler set the value of the CXX environment variable to the name of your compiler binary. If, for example, you wish to use the g++ compiler, then use this command to configure the build: $ ./configure CXX=g++ ----- Copyright (c) 2014-2015 Enrico M. Crisostomo 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, 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 . fswatch-1.11.2/CONTRIBUTING.md000644 000765 000024 00000001577 13174733730 016130 0ustar00enricostaff000000 000000 Contributing to fswatch ======================= The easiest ways to contribute to `fswatch` are: * Creating a new [issue]. * Forking the repository, make your contribution and submit a pull request. See [GitHub Flow](#github-flow) for further information. [issue]: https://github.com/emcrisostomo/fswatch/issues/new Github Flow ----------- I chose to use the [Github flow][flow] for `fswatch`, so you are kindly required to follow the same model when making your contributions. [flow]: https://help.github.com/articles/github-flow/ Coding Conventions and Style ---------------------------- The C and C++ code uses `snake_case` and is formatted with a customized [Allman (BSD)][allman] style. See [`README.codestyle`][codestyle] for further information on how setting up your IDE. [codestyle]: README.codestyle [allman]: https://en.wikipedia.org/wiki/Indent_style#Allman_style fswatch-1.11.2/libfswatch/000755 000765 000024 00000000000 13175374110 016005 5ustar00enricostaff000000 000000 fswatch-1.11.2/m4/000755 000765 000024 00000000000 13175374107 014205 5ustar00enricostaff000000 000000 fswatch-1.11.2/README.osx000644 000765 000024 00000011205 13174733730 015354 0ustar00enricostaff000000 000000 README.osx ********** Introduction ============ This file describes the steps required to build this bundle on a supported Apple OS X system. A complete C/C++ toolchain for OS X is provided with Apple XCode, which can be freely installed from the Apple App Store. See README for more information about the tested configurations. XCode ===== If you plan to build the bundle with CLang/LLVM, the easiest way to get a working toolchain is installing Apple XCode. Apple XCode ships with both the CLang/LLVM and the GCC compiler. XCode, however, does not install some required command line tools by default. To install them, the following operations must be performed: 1. Choose the "XCode/Preferences..." menu item. 2. Navigate to the "Downloads" pane. 3. Select the "Components" tab. 4. Select the "Command Line Tools" item and press the "Install" button. XCode 4.x ========= XCode 4 ships with the following C/C++ compilers: 1. Apple clang++/LLVM v. 4.2: Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn) Target: x86_64-apple-darwin12.4.0 Thread model: posix 2. GNU GCC v. 4.2.1: i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00) Only clang++ implements the required C++11 features required by fswatch, so that it must be configured with this compiler: $ CXX=clang++ ./configure XCode 5.x ========= XCode 5 ships with the following C/C++ compilers: 1. Apple clang++/LLVM v. 5.0: Apple LLVM version 5.0 (clang-500.2.75) (based on LLVM 3.3svn) Target: x86_64-apple-darwin12.5.0 Thread model: posix 2. GNU GCC v. 5.0: Apple LLVM version 5.0 (clang-500.2.76) (based on LLVM 3.3svn) Target: x86_64-apple-darwin12.5.0 Thread model: posix The GCC suite has been deprecated in favour of LLVM/CLang and gcc/g++ are now aliases to clang/clang++. The project can be configured with the default compiler: $ ./configure GNU Build System ================ The GNU Build System is required only by developers willing to modify the code on a OS X machine. Regular users only willing to install fswatch do not need the GNU Build System. Recent XCode Command Line Tools releases are not shipping all the components of the GNU Build System any longer. OS X users are thus required to build an alternate GNU Build System on their system. The required source bundles can be downloaded from their official web pages: 1. Autoconf: (http://www.gnu.org/software/autoconf/) (>= v. 2.69) 2. Automake (http://www.gnu.org/software/automake/) (>= v. 1.14.1) 3. Libtool: (http://www.gnu.org/software/libtool/) (>= v. 2.4.2) Libtool is not required to build this package but it's a core component of the GNU Build System. XCode Command Line Tools still ships GNU M4 (v. 1.4.6). To avoid conflicts with the binaries installed by XCode, it is strongly suggested to install the GNU Build System in an alternate location (such as the default /usr/local/bin) or in a private user folder. To choose the desired install location, use the --prefix configure option. For further instruction on building the GNU Build System from scratch, please check the README.gnu-build-system file. Localization and gettext ======================== fswatch is localizable and locale support requires GNU gettext to be available at build time. OS X does not ship gettext you will need to build it yourself or use a package manager such as MacPorts or Homebrew to install it. Depending on gettext installation path, configure may not be able to find or libintl. In this case, you will need to instruct configure about their location (this example assumes you use MacPorts' default installation path /opt/local): $ CPPFLAGS="-I/opt/local/include" LDFLAGS="-L/opt/local/lib" ./configure If configure detects that gettext is available, you will find a message such as: checking whether to use NLS... yes or, which is equivalent, config.h will contain the following definition: #define ENABLE_NLS 1 ----- Copyright (c) 2014-2015 Enrico M. Crisostomo 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, 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 . fswatch-1.11.2/README.libfswatch.md000644 000765 000024 00000003362 13174733730 017275 0ustar00enricostaff000000 000000 README ====== `libfswatch` is a library that provides developers the functionality of `fswatch`, the main `libfswatch` frontend. The library provides both C and C++ bindings. `libfswatch` provides the following [documentation]: * Texinfo documentation, included with the distribution. * HTML documentation. * PDF documentation. * A [wiki] page. * A man page. `libfswatch` official documentation is provided in Texinfo format. This is the most comprehensive source of information about `libfswatch` and the only authoritative one. The man page, in particular, is a stub that suggests the user to use the info page instead. If you are installing `libfswatch` using a package manager and you would like the PDF manual to be bundled into the package, please send a feature request to the package maintainer. [documentation]: http://emcrisostomo.github.io/fswatch/doc [wiki]: https://github.com/emcrisostomo/fswatch/wiki Bug Reports ----------- Bug reports can be sent directly to the authors. Contact the Authors ------------------- The author can be contacted on IRC, using the Freenode `#fswatch` channel. ----- Copyright (c) 2013-2016 Enrico M. Crisostomo 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, 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 . fswatch-1.11.2/AUTHORS.libfswatch000644 000765 000024 00000000142 13174733730 017057 0ustar00enricostaff000000 000000 AUTHORS ======= Authors of libfswatch: - Enrico M. Crisostomo fswatch-1.11.2/aclocal.m4000644 000765 000024 00000131556 13175374056 015543 0ustar00enricostaff000000 000000 # generated automatically by aclocal 1.15.1 -*- Autoconf -*- # Copyright (C) 1996-2017 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.15.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.15.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Copyright (C) 2011-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_AR([ACT-IF-FAIL]) # ------------------------- # Try to determine the archiver interface, and trigger the ar-lib wrapper # if it is needed. If the detection of archiver interface fails, run # ACT-IF-FAIL (default is to abort configure with a proper error message). AC_DEFUN([AM_PROG_AR], [AC_BEFORE([$0], [LT_INIT])dnl AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([ar-lib])dnl AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) : ${AR=ar} AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], [AC_LANG_PUSH([C]) am_cv_ar_interface=ar AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a ]) AC_LANG_POP([C])]) case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) m4_default([$1], [AC_MSG_ERROR([could not determine $AR interface])]) ;; esac AC_SUBST([AR])dnl ]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_COND_IF -*- Autoconf -*- # Copyright (C) 2008-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_COND_IF # _AM_COND_ELSE # _AM_COND_ENDIF # -------------- # These macros are only used for tracing. m4_define([_AM_COND_IF]) m4_define([_AM_COND_ELSE]) m4_define([_AM_COND_ENDIF]) # AM_COND_IF(COND, [IF-TRUE], [IF-FALSE]) # --------------------------------------- # If the shell condition COND is true, execute IF-TRUE, otherwise execute # IF-FALSE. Allow automake to learn about conditional instantiating macros # (the AC_CONFIG_FOOS). AC_DEFUN([AM_COND_IF], [m4_ifndef([_AM_COND_VALUE_$1], [m4_fatal([$0: no such condition "$1"])])dnl _AM_COND_IF([$1])dnl if test -z "$$1_TRUE"; then : m4_n([$2])[]dnl m4_ifval([$3], [_AM_COND_ELSE([$1])dnl else $3 ])dnl _AM_COND_ENDIF([$1])dnl fi[]dnl ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/ax_append_flag.m4]) m4_include([m4/ax_cflags_warn_all.m4]) m4_include([m4/ax_cxx_compile_stdcxx.m4]) m4_include([m4/ax_cxx_compile_stdcxx_11.m4]) m4_include([m4/ax_cxx_have_thread_local.m4]) m4_include([m4/ax_fsevents_have_file_events.m4]) m4_include([m4/ax_git_current_branch.m4]) m4_include([m4/ax_require_defined.m4]) m4_include([m4/emc_path_prog.m4]) m4_include([m4/gettext.m4]) m4_include([m4/iconv.m4]) m4_include([m4/intlmacosx.m4]) m4_include([m4/lib-ld.m4]) m4_include([m4/lib-link.m4]) m4_include([m4/lib-prefix.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) m4_include([m4/nls.m4]) m4_include([m4/po.m4]) m4_include([m4/progtest.m4]) fswatch-1.11.2/README.bsd000644 000765 000024 00000001710 13174733730 015313 0ustar00enricostaff000000 000000 README.bsd ********** Introduction ============ The kqueue-based monitor should be compatible with any *BSD release with support for kqueue. So far, however, the author has only tested this release on FreeBSD v. >= 10.0. Feedback on different *BSD systems is much appreciated and will benefit other users as well. ----- Copyright (c) 2014-2015 Enrico M. Crisostomo 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, 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 .fswatch-1.11.2/README.illumos000644 000765 000024 00000004117 13174733730 016233 0ustar00enricostaff000000 000000 README.solaris ************** Introduction ============ This file describes the steps required to build this bundle on a supported system running the Solaris or the Illumos kernel. See README for more information about the tested configurations. When Illumos was created, the Solaris kernel already included the File Events Notification API. Hence, the fen_monitor should be available on any system running Solaris (> 10) or an Illumos kernel. Additionally, a Solaris/Illumos system should be able to use the following monitors: * inotify_monitor, depending on the kernel version. * poll_monitor. So far, however, the author has only tested this release on SmartOS. Feedback on different Solaris/Illumos systems is much appreciated and will benefit other users as well. Installation ============ See the INSTALL file for detailed information about how to configure and install fswatch. fswatch is a C++ program and a C++ compiler compliant with the C++11 standard is required to compile it. Check the documentation of your distribution to learn how to install the required software. The configure script enforces an ordered compiler search list and clang++ will be used first if available. If you do not like this choice and wish to use another compiler set the value of the CXX environment variable to the name of your compiler binary. If, for example, you wish to use the g++ compiler, then use this command to configure the build: $ ./configure CXX=g++ ----- Copyright (c) 2015 Enrico M. Crisostomo 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, 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 .fswatch-1.11.2/fswatch/000755 000765 000024 00000000000 13175374110 015316 5ustar00enricostaff000000 000000 fswatch-1.11.2/fswatch/Makefile.am000644 000765 000024 00000001261 13175367735 017371 0ustar00enricostaff000000 000000 # # Copyright (c) 2014-2017 Enrico M. Crisostomo # # 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, 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 . # SUBDIRS = src doc fswatch-1.11.2/fswatch/doc/000755 000765 000024 00000000000 13175374112 016065 5ustar00enricostaff000000 000000 fswatch-1.11.2/fswatch/src/000755 000765 000024 00000000000 13175374110 016105 5ustar00enricostaff000000 000000 fswatch-1.11.2/fswatch/src/fswatch.hpp000644 000765 000024 00000002124 13174733730 020262 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ #ifndef FSW_H # define FSW_H # define FSW_EXIT_OK 0 # define FSW_EXIT_UNK_OPT 1 # define FSW_EXIT_USAGE 2 # define FSW_EXIT_LATENCY 3 # define FSW_EXIT_STREAM 4 # define FSW_EXIT_ERROR 5 # define FSW_EXIT_ENFILE 6 # define FSW_EXIT_OPT 7 # define FSW_EXIT_MONITOR_NAME 8 # define FSW_EXIT_FORMAT 9 #endif /* FSW_H */ fswatch-1.11.2/fswatch/src/Makefile.am000644 000765 000024 00000002226 13174733730 020151 0ustar00enricostaff000000 000000 # # Copyright (c) 2014-2015 Enrico M. Crisostomo # # 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, 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 . # AUTOMAKE_OPTIONS = std-options bin_PROGRAMS = fswatch fswatch_SOURCES = fswatch.hpp fswatch.cpp fswatch_SOURCES += gettext.h # Set include path for libfswatch AM_CPPFLAGS = -I$(top_srcdir)/libfswatch/src # Prepare gettext-related symbols used by programs AM_CPPFLAGS += -DLOCALEDIR=\"$(localedir)\" # Link fswatch against dependent libraries fswatch_LDADD = $(top_builddir)/libfswatch/src/libfswatch/libfswatch.la # Link fswatch against libintl if gettext is being used fswatch_LDADD += @LTLIBINTL@ fswatch-1.11.2/fswatch/src/fswatch.cpp000644 000765 000024 00000056477 13174733730 020301 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2017 Enrico M. Crisostomo * * 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, 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 . */ #ifdef HAVE_CONFIG_H # include "libfswatch_config.h" #endif #include "gettext.h" #include "fswatch.hpp" #include #include #include #include #include #include #include #include #include #include #include "libfswatch/c++/event.hpp" #include "libfswatch/c++/monitor.hpp" #include "libfswatch/c/error.h" #include "libfswatch/c/libfswatch.h" #include "libfswatch/c/libfswatch_log.h" #include "libfswatch/c++/libfswatch_exception.hpp" #ifdef HAVE_GETOPT_LONG # include #endif #define _(String) gettext(String) using namespace std; using namespace fsw; /* * Event formatting types and routines. */ static void print_event_flags(const event& evt); static void print_event_path(const event& evt); static void print_event_timestamp(const event& evt); static int printf_event_validate_format(const string& fmt); static FSW_EVENT_CALLBACK process_events; struct printf_event_callbacks { void (*format_f)(const event& evt); void (*format_p)(const event& evt); void (*format_t)(const event& evt); }; struct printf_event_callbacks event_format_callbacks { print_event_flags, print_event_path, print_event_timestamp }; static int printf_event(const string& fmt, const event& evt, const struct printf_event_callbacks& callback, ostream& os = cout); static const unsigned int TIME_FORMAT_BUFF_SIZE = 128; static monitor *active_monitor = nullptr; static vector filters; static vector event_filters; static vector filter_files; static bool _0flag = false; static bool _1flag = false; static bool aflag = false; static bool allow_overflow = false; static int batch_marker_flag = false; static bool dflag = false; static bool Eflag = false; static bool fieFlag = false; static bool Iflag = false; static bool Lflag = false; static bool mflag = false; static bool nflag = false; static bool oflag = false; static bool rflag = false; static bool tflag = false; static bool uflag = false; static bool vflag = false; static int version_flag = false; static bool xflag = false; static double lvalue = 1.0; static string monitor_name; static string tformat = "%c"; static string batch_marker = event::get_event_flag_name(fsw_event_flag::NoOp); static int format_flag = false; static string format; static string event_flag_separator = " "; static map monitor_properties; /* * OPT_* variables are used as getopt_long values for long options that do not * have a short option equivalent. */ static const int OPT_BATCH_MARKER = 128; static const int OPT_FORMAT = 129; static const int OPT_EVENT_FLAG_SEPARATOR = 130; static const int OPT_EVENT_TYPE = 131; static const int OPT_ALLOW_OVERFLOW = 132; static const int OPT_MONITOR_PROPERTY = 133; static const int OPT_FIRE_IDLE_EVENTS = 134; static const int OPT_FILTER_FROM = 135; static void list_monitor_types(ostream& stream) { for (const auto& type : monitor_factory::get_types()) { stream << " " << type << "\n"; } } static void print_version(ostream& stream) { stream << PACKAGE_STRING << "\n"; stream << "Copyright (C) 2013-2017 Enrico M. Crisostomo .\n"; stream << _("License GPLv3+: GNU GPL version 3 or later .\n"); stream << _("This is free software: you are free to change and redistribute it.\n"); stream << _("There is NO WARRANTY, to the extent permitted by law.\n"); stream << "\n"; stream << _("Written by Enrico M. Crisostomo."); stream << endl; } static void usage(ostream& stream) { #ifdef HAVE_GETOPT_LONG stream << PACKAGE_STRING << "\n\n"; stream << _("Usage:\n"); stream << PACKAGE_NAME << _(" [OPTION] ... path ...\n"); stream << "\n"; stream << _("Options:\n"); stream << " -0, --print0 " << _("Use the ASCII NUL character (0) as line separator.\n"); stream << " -1, --one-event " << _("Exit fswatch after the first set of events is received.\n"); stream << " --allow-overflow " << _("Allow a monitor to overflow and report it as a change event.\n"); stream << " --batch-marker " << _("Print a marker at the end of every batch.\n"); stream << " -a, --access " << _("Watch file accesses.\n"); stream << " -d, --directories " << _("Watch directories only.\n"); stream << " -e, --exclude=REGEX " << _("Exclude paths matching REGEX.\n"); stream << " -E, --extended " << _("Use extended regular expressions.\n"); stream << " --filter-from=FILE\n"; stream << " " << _("Load filters from file.") << "\n"; stream << " --format=FORMAT " << _("Use the specified record format.") << "\n"; stream << " -f, --format-time " << _("Print the event time using the specified format.\n"); stream << " --fire-idle-event " << _("Fire idle events.\n"); stream << " -h, --help " << _("Show this message.\n"); stream << " -i, --include=REGEX " << _("Include paths matching REGEX.\n"); stream << " -I, --insensitive " << _("Use case insensitive regular expressions.\n"); stream << " -l, --latency=DOUBLE " << _("Set the latency.\n"); stream << " -L, --follow-links " << _("Follow symbolic links.\n"); stream << " -M, --list-monitors " << _("List the available monitors.\n"); stream << " -m, --monitor=NAME " << _("Use the specified monitor.\n"); stream << " --monitor-property name=value\n"; stream << " " << _("Define the specified property.\n"); stream << " -n, --numeric " << _("Print a numeric event mask.\n"); stream << " -o, --one-per-batch " << _("Print a single message with the number of change events.\n"); stream << " -r, --recursive " << _("Recurse subdirectories.\n"); stream << " -t, --timestamp " << _("Print the event timestamp.\n"); stream << " -u, --utc-time " << _("Print the event time as UTC time.\n"); stream << " -x, --event-flags " << _("Print the event flags.\n"); stream << " --event=TYPE " << _("Filter the event by the specified type.\n"); stream << " --event-flag-separator=STRING\n"; stream << " " << _("Print event flags using the specified separator.") << "\n"; stream << " -v, --verbose " << _("Print verbose output.\n"); stream << " --version " << _("Print the version of ") << PACKAGE_NAME << _(" and exit.\n"); stream << "\n"; #else string option_string = "[01adeEfhilLMmnortuvx]"; stream << PACKAGE_STRING << "\n\n"; stream << _("Usage:\n"); stream << PACKAGE_NAME << " " << option_string << " path ...\n"; stream << "\n"; stream << _("Options:\n"); stream << " -0 Use the ASCII NUL character (0) as line separator.\n"; stream << " -1 Exit fswatch after the first set of events is received.\n"; stream << " -a Watch file accesses.\n"; stream << " -d Watch directories only.\n"; stream << " -e Exclude paths matching REGEX.\n"; stream << " -E Use extended regular expressions.\n"; stream << " -f Print the event time stamp with the specified format.\n"; stream << " -h Show this message.\n"; stream << " -i Include paths matching REGEX.\n"; stream << " -I Use case insensitive regular expressions.\n"; stream << " -l Set the latency.\n"; stream << " -L Follow symbolic links.\n"; stream << " -m Use the specified monitor.\n"; stream << " -M List the available monitors.\n"; stream << " -n Print a numeric event masks.\n"; stream << " -o Print a single message with the number of change events in the current\n"; stream << " batch.\n"; stream << " -r Recurse subdirectories.\n"; stream << " -t Print the event timestamp.\n"; stream << " -u Print the event time as UTC time.\n"; stream << " -v Print verbose output.\n"; stream << " -x Print the event flags.\n"; stream << "\n"; #endif stream << _("Available monitors in this platform:\n\n"); list_monitor_types(stream); stream << _("\nSee the man page for more information.\n\n"); stream << _("Report bugs to <") << PACKAGE_BUGREPORT << ">.\n"; stream << PACKAGE << _(" home page: <") << PACKAGE_URL << ">."; stream << endl; } static void close_monitor() { if (active_monitor) active_monitor->stop(); } static void close_handler(int signal) { FSW_ELOG(_("Executing termination handler.\n")); close_monitor(); } static bool parse_event_bitmask(const char *optarg) { try { auto bitmask = std::stoul(optarg, nullptr, 10); for (auto& item : FSW_ALL_EVENT_FLAGS) { if ((bitmask & item) == item) { event_filters.push_back({item}); } } return true; } catch (std::invalid_argument& ex) { return false; } } static bool parse_event_filter(const char *optarg) { if (parse_event_bitmask(optarg)) return true; try { event_filters.push_back({event::get_event_flag_by_name(optarg)}); return true; } catch (libfsw_exception& ex) { cerr << ex.what() << endl; return false; } } static bool validate_latency(double latency) { if (latency == 0.0) { cerr << _("Invalid value: ") << optarg << endl; return false; } if (errno == ERANGE || latency == HUGE_VAL) { cerr << _("Value out of range: ") << optarg << endl; return false; } return true; } static void register_signal_handlers() { struct sigaction action; action.sa_handler = close_handler; sigemptyset(&action.sa_mask); action.sa_flags = 0; if (sigaction(SIGTERM, &action, nullptr) == 0) { FSW_ELOG(_("SIGTERM handler registered.\n")); } else { cerr << _("SIGTERM handler registration failed.") << endl; } if (sigaction(SIGABRT, &action, nullptr) == 0) { FSW_ELOG(_("SIGABRT handler registered.\n")); } else { cerr << _("SIGABRT handler registration failed.") << endl; } if (sigaction(SIGINT, &action, nullptr) == 0) { FSW_ELOG(_("SIGINT handler registered.\n")); } else { cerr << _("SIGINT handler registration failed") << endl; } } static void print_event_path(const event& evt) { cout << evt.get_path(); } static void print_event_timestamp(const event& evt) { const time_t& evt_time = evt.get_time(); char time_format_buffer[TIME_FORMAT_BUFF_SIZE]; struct tm *tm_time = uflag ? gmtime(&evt_time) : localtime(&evt_time); string date = strftime(time_format_buffer, TIME_FORMAT_BUFF_SIZE, tformat.c_str(), tm_time) ? string(time_format_buffer) : string( _("")); cout << date; } static void print_event_flags(const event& evt) { const vector& flags = evt.get_flags(); if (nflag) { int mask = 0; for (const fsw_event_flag& flag : flags) { mask += static_cast (flag); } cout << mask; } else { for (size_t i = 0; i < flags.size(); ++i) { cout << flags[i]; // Event flag separator is currently hard-coded. if (i != flags.size() - 1) cout << event_flag_separator; } } } static void print_end_of_event_record() { if (_0flag) { cout << '\0'; cout.flush(); } else { cout << endl; } } static void write_batch_marker() { if (batch_marker_flag) { cout << batch_marker; print_end_of_event_record(); } } static void write_one_batch_event(const vector& events) { cout << events.size(); print_end_of_event_record(); write_batch_marker(); } static void write_events(const vector& events) { for (const event& evt : events) { printf_event(format, evt, event_format_callbacks); print_end_of_event_record(); } write_batch_marker(); if (_1flag) { close_monitor(); } } void process_events(const vector& events, void *context) { if (oflag) write_one_batch_event(events); else write_events(events); } static void start_monitor(int argc, char **argv, int optind) { // parsing paths vector paths; for (auto i = optind; i < argc; ++i) { char *real_path = realpath(argv[i], nullptr); string path(real_path ? real_path : argv[i]); if (real_path) free(real_path); FSW_ELOGF(_("Adding path: %s\n"), path.c_str()); paths.push_back(path); } if (mflag) active_monitor = monitor_factory::create_monitor(monitor_name, paths, process_events); else active_monitor = monitor_factory::create_monitor( fsw_monitor_type::system_default_monitor_type, paths, process_events); /* * libfswatch supports case sensitivity and extended flags to be set on any * filter but fswatch does not. For the time being, we apply the same flags * to every filter. */ for (auto& filter : filters) { filter.case_sensitive = !Iflag; filter.extended = Eflag; } // Load filters from the specified files. for (const auto& filter_file : filter_files) { auto filters_from_file = monitor_filter::read_from_file(filter_file, [](string f) { cerr << _("Invalid filter: ") << f << "\n"; }); std::move(filters_from_file.begin(), filters_from_file.end(), std::back_inserter(filters)); } active_monitor->set_properties(monitor_properties); active_monitor->set_allow_overflow(allow_overflow); active_monitor->set_latency(lvalue); active_monitor->set_fire_idle_event(fieFlag); active_monitor->set_recursive(rflag); active_monitor->set_directory_only(dflag); active_monitor->set_event_type_filters(event_filters); active_monitor->set_filters(filters); active_monitor->set_follow_symlinks(Lflag); active_monitor->set_watch_access(aflag); active_monitor->start(); } static void parse_opts(int argc, char **argv) { int ch; string short_options = "01ade:Ef:hi:Il:LMm:nortuvx"; #ifdef HAVE_GETOPT_LONG int option_index = 0; static struct option long_options[] = { {"access", no_argument, nullptr, 'a'}, {"allow-overflow", no_argument, nullptr, OPT_ALLOW_OVERFLOW}, {"batch-marker", optional_argument, nullptr, OPT_BATCH_MARKER}, {"directories", no_argument, nullptr, 'd'}, {"event", required_argument, nullptr, OPT_EVENT_TYPE}, {"event-flags", no_argument, nullptr, 'x'}, {"event-flag-separator", required_argument, nullptr, OPT_EVENT_FLAG_SEPARATOR}, {"exclude", required_argument, nullptr, 'e'}, {"extended", no_argument, nullptr, 'E'}, {"filter-from", required_argument, nullptr, OPT_FILTER_FROM}, {"fire-idle-events", no_argument, nullptr, OPT_FIRE_IDLE_EVENTS}, {"follow-links", no_argument, nullptr, 'L'}, {"format", required_argument, nullptr, OPT_FORMAT}, {"format-time", required_argument, nullptr, 'f'}, {"help", no_argument, nullptr, 'h'}, {"include", required_argument, nullptr, 'i'}, {"insensitive", no_argument, nullptr, 'I'}, {"latency", required_argument, nullptr, 'l'}, {"list-monitors", no_argument, nullptr, 'M'}, {"monitor", required_argument, nullptr, 'm'}, {"monitor-property", required_argument, nullptr, OPT_MONITOR_PROPERTY}, {"numeric", no_argument, nullptr, 'n'}, {"one-per-batch", no_argument, nullptr, 'o'}, {"one-event", no_argument, nullptr, '1'}, {"print0", no_argument, nullptr, '0'}, {"recursive", no_argument, nullptr, 'r'}, {"timestamp", no_argument, nullptr, 't'}, {"utc-time", no_argument, nullptr, 'u'}, {"verbose", no_argument, nullptr, 'v'}, {"version", no_argument, &version_flag, true}, {nullptr, 0, nullptr, 0} }; while ((ch = getopt_long(argc, argv, short_options.c_str(), long_options, &option_index)) != -1) { #else while ((ch = getopt(argc, argv, short_options.c_str())) != -1) { #endif switch (ch) { case '0': _0flag = true; break; case '1': _1flag = true; break; case 'a': aflag = true; break; case 'd': dflag = true; break; case 'e': filters.push_back({optarg, fsw_filter_type::filter_exclude}); break; case 'E': Eflag = true; break; case 'f': tformat = string(optarg); break; case 'h': usage(cout); exit(FSW_EXIT_OK); case 'i': filters.push_back({optarg, fsw_filter_type::filter_include}); break; case 'I': Iflag = true; break; case 'l': lvalue = strtod(optarg, nullptr); if (!validate_latency(lvalue)) { exit(FSW_EXIT_LATENCY); } break; case 'L': Lflag = true; break; case 'M': list_monitor_types(cout); exit(FSW_EXIT_OK); case 'm': mflag = true; monitor_name = string(optarg); break; case 'n': nflag = true; xflag = true; break; case 'o': oflag = true; break; case 'r': rflag = true; break; case 't': tflag = true; break; case 'u': uflag = true; break; case 'v': vflag = true; break; case 'x': xflag = true; break; case OPT_BATCH_MARKER: if (optarg) batch_marker = optarg; batch_marker_flag = true; break; case OPT_FORMAT: format_flag = true; format = optarg; break; case OPT_EVENT_FLAG_SEPARATOR: event_flag_separator = optarg; break; case OPT_EVENT_TYPE: if (!parse_event_filter(optarg)) { exit(FSW_ERR_UNKNOWN_VALUE); } break; case OPT_ALLOW_OVERFLOW: allow_overflow = true; break; case OPT_MONITOR_PROPERTY: { string param(optarg); size_t eq_pos = param.find_first_of("="); if (eq_pos == string::npos) { cerr << _("Invalid property format.") << endl; exit(FSW_ERR_INVALID_PROPERTY); } monitor_properties[param.substr(0, eq_pos)] = param.substr(eq_pos + 1); } break; case OPT_FIRE_IDLE_EVENTS: fieFlag = true; break; case OPT_FILTER_FROM: filter_files.push_back(optarg); break; case '?': usage(cerr); exit(FSW_EXIT_UNK_OPT); } } // Set verbose mode for libfswatch. fsw_set_verbose(vflag); if (version_flag) { print_version(cout); exit(FSW_EXIT_OK); } // --format is incompatible with any other format option. if (format_flag && (tflag || xflag)) { cerr << _("--format is incompatible with any other format option such as -t and -x.") << endl; exit(FSW_EXIT_FORMAT); } if (format_flag && oflag) { cerr << _("--format is incompatible with -o.") << endl; exit(FSW_EXIT_FORMAT); } // If no format was specified use: // * %p as the default. // * -t adds "%t " at the beginning of the format. // * -x adds " %f" at the end of the format. // * '\n' is used as record separator unless -0 is used, in which case '\0' // is used instead. if (format_flag) { // Test the user format if (printf_event_validate_format(format) < 0) { cerr << _("Invalid format.") << endl; exit(FSW_EXIT_FORMAT); } } else { // Build event format. if (tflag) { format = "%t "; } format += "%p"; if (xflag) { format += " %f"; } } } static void format_noop(const event& evt) { } static int printf_event_validate_format(const string& fmt) { struct printf_event_callbacks noop_callbacks { format_noop, format_noop, format_noop }; const vector flags; const event empty("", 0, flags); ostream noop_stream(nullptr); return printf_event(fmt, empty, noop_callbacks, noop_stream); } static int printf_event(const string& fmt, const event& evt, const struct printf_event_callbacks& callback, ostream& os) { /* * %t - time (further formatted using -f and strftime. * %p - event path * %f - event flags (event separator will be formatted with a separate option) */ for (size_t i = 0; i < format.length(); ++i) { // If the character does not start a format directive, copy it as it is. if (format[i] != '%') { os << format[i]; continue; } // If this is the end of the string, dump an error. if (i == format.length() - 1) { return -1; } // Advance to next format and check which directive it is. const char c = format[++i]; switch (c) { case '%': os << '%'; break; case '0': os << '\0'; break; case 'n': os << '\n'; break; case 'f': callback.format_f(evt); break; case 'p': callback.format_p(evt); break; case 't': callback.format_t(evt); break; default: return -1; } } return 0; } int main(int argc, char **argv) { // Trigger gettext operations #ifdef ENABLE_NLS setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); #endif parse_opts(argc, argv); // validate options if (optind == argc) { cerr << _("Invalid number of arguments.") << endl; exit(FSW_EXIT_UNK_OPT); } if (mflag && !monitor_factory::exists_type(monitor_name)) { cerr << _("Invalid monitor name.") << endl; exit(FSW_EXIT_MONITOR_NAME); } // configure and start the monitor try { // registering handlers to clean up resources register_signal_handlers(); atexit(close_monitor); // configure and start the monitor loop start_monitor(argc, argv, optind); delete active_monitor; active_monitor = nullptr; } catch (invalid_argument& ex) { cerr << ex.what() << "\n"; return FSW_EXIT_ERROR; } catch (exception& conf) { cerr << _("An error occurred and the program will be terminated.\n"); cerr << conf.what() << "\n"; return FSW_EXIT_ERROR; } catch (...) { cerr << _("An unknown error occurred and the program will be terminated.\n"); return FSW_EXIT_ERROR; } return FSW_EXIT_OK; } fswatch-1.11.2/fswatch/src/gettext.h000644 000765 000024 00000023664 13174733730 017763 0ustar00enricostaff000000 000000 /* Convenience header for conditional use of GNU . Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2016 Free Software Foundation, Inc. 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 . */ #ifndef _LIBGETTEXT_H #define _LIBGETTEXT_H 1 /* NLS can be disabled through the configure --disable-nls option. */ #if ENABLE_NLS /* Get declarations of GNU message catalog functions. */ # include /* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by the gettext() and ngettext() macros. This is an alternative to calling textdomain(), and is useful for libraries. */ # ifdef DEFAULT_TEXT_DOMAIN # undef gettext # define gettext(Msgid) \ dgettext (DEFAULT_TEXT_DOMAIN, Msgid) # undef ngettext # define ngettext(Msgid1, Msgid2, N) \ dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) # endif #else /* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which chokes if dcgettext is defined as a macro. So include it now, to make later inclusions of a NOP. We don't include as well because people using "gettext.h" will not include , and also including would fail on SunOS 4, whereas is OK. */ #if defined(__sun) # include #endif /* Many header files from the libstdc++ coming with g++ 3.3 or newer include , which chokes if dcgettext is defined as a macro. So include it now, to make later inclusions of a NOP. */ #if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) # include # if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H # include # endif #endif /* Disabled NLS. The casts to 'const char *' serve the purpose of producing warnings for invalid uses of the value returned from these functions. On pre-ANSI systems without 'const', the config.h file is supposed to contain "#define const". */ # undef gettext # define gettext(Msgid) ((const char *) (Msgid)) # undef dgettext # define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) # undef dcgettext # define dcgettext(Domainname, Msgid, Category) \ ((void) (Category), dgettext (Domainname, Msgid)) # undef ngettext # define ngettext(Msgid1, Msgid2, N) \ ((N) == 1 \ ? ((void) (Msgid2), (const char *) (Msgid1)) \ : ((void) (Msgid1), (const char *) (Msgid2))) # undef dngettext # define dngettext(Domainname, Msgid1, Msgid2, N) \ ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) # undef dcngettext # define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ ((void) (Category), dngettext (Domainname, Msgid1, Msgid2, N)) # undef textdomain # define textdomain(Domainname) ((const char *) (Domainname)) # undef bindtextdomain # define bindtextdomain(Domainname, Dirname) \ ((void) (Domainname), (const char *) (Dirname)) # undef bind_textdomain_codeset # define bind_textdomain_codeset(Domainname, Codeset) \ ((void) (Domainname), (const char *) (Codeset)) #endif /* Prefer gnulib's setlocale override over libintl's setlocale override. */ #ifdef GNULIB_defined_setlocale # undef setlocale # define setlocale rpl_setlocale #endif /* A pseudo function call that serves as a marker for the automated extraction of messages, but does not call gettext(). The run-time translation is done at a different place in the code. The argument, String, should be a literal string. Concatenated strings and other string expressions won't work. The macro's expansion is not parenthesized, so that it is suitable as initializer for static 'char[]' or 'const char[]' variables. */ #define gettext_noop(String) String /* The separator between msgctxt and msgid in a .mo file. */ #define GETTEXT_CONTEXT_GLUE "\004" /* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be short and rarely need to change. The letter 'p' stands for 'particular' or 'special'. */ #ifdef DEFAULT_TEXT_DOMAIN # define pgettext(Msgctxt, Msgid) \ pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) #else # define pgettext(Msgctxt, Msgid) \ pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) #endif #define dpgettext(Domainname, Msgctxt, Msgid) \ pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) #define dcpgettext(Domainname, Msgctxt, Msgid, Category) \ pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category) #ifdef DEFAULT_TEXT_DOMAIN # define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) #else # define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) #endif #define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) #define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \ npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category) #ifdef __GNUC__ __inline #else #ifdef __cplusplus inline #endif #endif static const char * pgettext_aux (const char *domain, const char *msg_ctxt_id, const char *msgid, int category) { const char *translation = dcgettext (domain, msg_ctxt_id, category); if (translation == msg_ctxt_id) return msgid; else return translation; } #ifdef __GNUC__ __inline #else #ifdef __cplusplus inline #endif #endif static const char * npgettext_aux (const char *domain, const char *msg_ctxt_id, const char *msgid, const char *msgid_plural, unsigned long int n, int category) { const char *translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); if (translation == msg_ctxt_id || translation == msgid_plural) return (n == 1 ? msgid : msgid_plural); else return translation; } /* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID can be arbitrary expressions. But for string literals these macros are less efficient than those above. */ #include #if (((__GNUC__ >= 3 || __GNUG__ >= 2) && !defined __STRICT_ANSI__) \ /* || __STDC_VERSION__ >= 199901L */ ) # define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 1 #else # define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0 #endif #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS #include #endif #define pgettext_expr(Msgctxt, Msgid) \ dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES) #define dpgettext_expr(Domainname, Msgctxt, Msgid) \ dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES) #ifdef __GNUC__ __inline #else #ifdef __cplusplus inline #endif #endif static const char * dcpgettext_expr (const char *domain, const char *msgctxt, const char *msgid, int category) { size_t msgctxt_len = strlen (msgctxt) + 1; size_t msgid_len = strlen (msgid) + 1; const char *translation; #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS char msg_ctxt_id[msgctxt_len + msgid_len]; #else char buf[1024]; char *msg_ctxt_id = (msgctxt_len + msgid_len <= sizeof (buf) ? buf : (char *) malloc (msgctxt_len + msgid_len)); if (msg_ctxt_id != NULL) #endif { int found_translation; memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); msg_ctxt_id[msgctxt_len - 1] = '\004'; memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); translation = dcgettext (domain, msg_ctxt_id, category); found_translation = (translation != msg_ctxt_id); #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS if (msg_ctxt_id != buf) free (msg_ctxt_id); #endif if (found_translation) return translation; } return msgid; } #define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \ dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) #define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) #ifdef __GNUC__ __inline #else #ifdef __cplusplus inline #endif #endif static const char * dcnpgettext_expr (const char *domain, const char *msgctxt, const char *msgid, const char *msgid_plural, unsigned long int n, int category) { size_t msgctxt_len = strlen (msgctxt) + 1; size_t msgid_len = strlen (msgid) + 1; const char *translation; #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS char msg_ctxt_id[msgctxt_len + msgid_len]; #else char buf[1024]; char *msg_ctxt_id = (msgctxt_len + msgid_len <= sizeof (buf) ? buf : (char *) malloc (msgctxt_len + msgid_len)); if (msg_ctxt_id != NULL) #endif { int found_translation; memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); msg_ctxt_id[msgctxt_len - 1] = '\004'; memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); found_translation = !(translation == msg_ctxt_id || translation == msgid_plural); #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS if (msg_ctxt_id != buf) free (msg_ctxt_id); #endif if (found_translation) return translation; } return (n == 1 ? msgid : msgid_plural); } #endif /* _LIBGETTEXT_H */ fswatch-1.11.2/fswatch/doc/fswatch.texi000644 000765 000024 00000223217 13175373373 020436 0ustar00enricostaff000000 000000 \input texinfo @c -*-texinfo-*- @c %**start of header @setfilename fswatch.info @c Automake automatically updates version.texi to @set VERSION and @c @set UPDATED to appropriate values. @include version.texi @settitle fswatch @value{VERSION} @dircategory Individual utilities @direntry * fswatch: (fswatch). Cross-platform file change monitor. @end direntry @c @finalout @smallbook @include value.texi @defcodeindex op @defcodeindex fl @paragraphindent 2 @c %**end of header @copying This manual is for @command{fswatch} (version @value{VERSION}, @value{UPDATED}), a cross-platform file change monitor with multiple backends: Apple OS X @emph{File System Events}, *BSD @emph{kqueue}, Solaris/Illumos @emph{File Events Notification}, Linux @emph{inotify}, Microsoft Windows @code{ReadDirectoryChangesW} and a @code{stat()}-based backend. Copyright @copyright{} 2013-2015 Enrico M. Crisostomo @quotation Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU Free Documentation License''. @end quotation @end copying @setchapternewpage odd @shorttitlepage fswatch @titlepage @title fswatch @subtitle Cross-platform file change monitor with multiple backends @subtitle for @command{fswatch} version @value{VERSION}, @value{UPDATED} @author Enrico M. Crisostomo @c Include the Distribution inside the titlepage so @c that headings are turned off. @page @vskip 0pt plus 1filll @insertcopying @end titlepage @c Output the table of contents at the beginning. @summarycontents @contents @ifnottex @node Top @top fswatch @insertcopying @end ifnottex @menu * Version History:: Version History * Introduction:: Introduction * Tutorial Introduction to @command{fswatch}:: Tutorial Introduction to @command{fswatch} * Invoking @command{fswatch}:: Invoking @command{fswatch} * Monitors:: Monitors * GNU Free Documentation License:: GNU Free Documentation License * Index of Functions:: Index of Functions * Index of Programs:: Index of Programs * Index of Files:: Index of Files * Index of Command Line Options:: Index of Command Line Options * General Index:: General Index @end menu @node Version History @chapter Version History @section 1.11.2 @itemize @item Fix issue 182: Generate a single message catalog for both @command{fswatch} and @file{libfswatch}. @end itemize @section 1.11.1 @itemize @item Fix issue 182: Remove mandatory dependency to git. @end itemize @section 1.11.0 @itemize @item @opindex event@r{, mask} Fix issue 174: Update the @option{--event} option to accept a numeric event mask. @item Fix issue 181: Make gettext an optional dependency. @end itemize @section 1.10.0 @itemize @item Fix issue 60: Allow excluding file patterns by passing a file. @item Fix issue 119: Merge @command{fswatch} and @file{libfswatch} Autotools projects into one. @item Fix issue 141: Add Docker files for Linux distributions used for testing. @item Add target to build @command{fswatch} on Alpine Linux and Debian. @end itemize @section 1.9.3 @itemize @item Fix issue 120: C binding is pulling in C++ headers and using C++ constructs. @item Fix issue 128: C binding is pulling in C++ headers. @end itemize @section 1.9.2 @itemize @item Fix issue 118: v. 1.9.0 breaks the @option{-1} option. @item @file{libfswatch} @acronym{API} version set to 8:0:2. @end itemize @section 1.9.1 @itemize @item @file{libfswatch} @acronym{API} version set to 7:0:1. @end itemize @section 1.9.0 @itemize @item Fix issue 114: @command{fswatch} does not track newly created directories recursively when using the @emph{inotify} monitor. @item Add the possibility of scheduling a periodic event. @end itemize @section 1.8.0 @itemize @item Add preemptive monitor stop support. @end itemize @section 1.7.0 @itemize @item Fix issue 35: Support Solaris/Illumos File Events Notification @acronym{API}. @item @opindex directories@r{, inception} Fix issue 98: Add (@option{-d}, @option{--directories}) option to request the monitor to watch directories only during a recursive scan. @item Fix issue 99: A monitor using the File Events Notification @acronym{API} of the Solaris/Illumos kernel has been added. @item Fix issue 101: Add flag to watch file accesses. @end itemize @section 1.6.0 @itemize @item @command{fswatch} can be built on Microsoft Windows using Cygwin. @item A monitor for Microsoft Windows has been added. @item @fnindex @code{fsw_event_flag::Overflow} @opindex allow-overflow@r{, inception} @command{fswatch} can survive monitor overflows and notify them as a specially crafted change event (of type @command{Overflow}) if invoked with the @option{--allow-overflow} option. @end itemize @section 1.5.1 @itemize @item @pgindex @command{fswatch-run} @command{fswatch-run} scripts have been removed. @item @cpindex Bash @cpindex Zsh As a consequence of the @command{fswatch-run} removal, dependency on at least one supported shell (Zsh and Bash) has been removed. @end itemize @section 1.5.0 @itemize @item @opindex event@r{, inception} Added the @option{--event} option to allow filtering by event type. @end itemize @section 1.4.7 @itemize @item Fix bug in exclusion filter ordering (PR 75). @item @flindex README.md @file{README.md} improvements. @item Documentation improvements. @end itemize @section 1.4.6 @itemize @item @fnindex fsw_destroy_session Fix issue 74: Assertion failed on @code{fsw_destroy_session}. @end itemize @section 1.4.5.3 @itemize @item Fix issue 67: 100% @acronym{CPU} usage while using @file{libfswatch}. This issue only affects the @emph{inotify} monitor. @end itemize @section 1.4.5.2 @itemize @item Fix issue 66: Exclude items with @command{poll_monitor} not considered. @end itemize @section 1.4.5.1 @itemize @item @cpindex FreeBSD Do not distribute wrapper scripts for shells which are not installed (the FreeBSD port system checks shebangs and complains). @end itemize @section 1.4.5 @itemize @item Add custom record formats. @end itemize @section 1.4.4 @itemize @item @cpindex @acronym{GNU} gettext @cpindex gettext @pgindex gettext Localize @command{fswatch} and @file{libfswatch} using @acronym{GNU} @code{gettext}. @item Add Spanish (@code{es}) localization. @item Add Italian (@code{it}) localization. @end itemize @section 1.4.3.2 @itemize @item @flindex Makefile.am Fix @file{Makefile.am} because of broken link when @var{DESTDIR} installs are performed. @end itemize @section 1.4.3.1 @itemize @item @pgindex fswatch-run @pgindex xargs @cpindex Zsh Fix bug in @command{fswatch-run} wrapper script for Zsh which caused last argument not to be split when passed to @file{xargs}. @end itemize @section 1.4.3 @itemize @item @cpindex batch marker, inception Add batch marker feature to delimit the boundaries of a batch of events. @item Add Texinfo documentation. @item @file{libfswatch} @acronym{API} is now versioned. @item @cpindex Autoconf Improved Autoconf checks. @item The @emph{inotify} monitor now waits for events and honours the latency settings. @item @flindex ChangeLog @cpindex Git @pgindex git Automaticaly generate the @file{ChangeLog} file using Git. @item @flindex autogen.sh Update @file{autogen.sh} to honour some commonly used environment variables. @end itemize @section 1.4.2 @itemize @item The @emph{inotify} monitor now provides the same functionality provided by all the other monitors. Recursive directory monitoring is now implemented. @item @cpindex Git @pgindex git Version and revision is now determined dynamically using Git by ancillary scripts invoked by the @acronym{GNU} Build System. @end itemize @section 1.4.1.1 @itemize @item @cpindex Apple OS X @cpindex C++11 @command{fswatch} does not compile on OS X < 10.9 because some required C++11 classes are not supported by its C++ runtime. @end itemize @section 1.4.1 @itemize @item @cpindex Apple OS X @cpindex C++11 @command{fswatch} does not compile on OS X < 10.9 because some required C++11 classes are not supported by its C++ runtime. @end itemize @section 1.4.0 @itemize @item @cpindex C++ @cpindex C The @file{libfswatch} library has been added with bindings for C and C++. @item @command{fswatch} let users specify the monitor to use by name. @end itemize @section 1.3.9 @itemize @item @opindex include@r{, inception} Fix Issue 23: Add @option{--include} option. @item @opindex include@r{, inception} Fix Issue 25: Add @option{--include} option. @item @opindex include Paths can be included using @option{-i}/@option{--include} and providing a set of regular expressions. @end itemize @section 1.3.8 @itemize @item Fix Issue 34: Diagnostic messages were output by the @emph{inotify} monitor even if @command{fswatch} was not run in verbose mode. @end itemize @section 1.3.7 @itemize @item Fix Issue 32: Problems building @command{fswatch} 1.3.6 on Mac v. 10.8.5. @item @cpindex C++11 @cpindex C++, initializer list Remove usages of C++11 initializer lists so that @command{fswatch} builds with older compilers. @end itemize @section 1.3.6 @itemize @item @pgindex fswatch-run Fix Issue 26: @command{fswatch-run} cannot run a command with arguments. @item @pgindex fswatch-run @cpindex Zsh @cpindex Bash @command{fswatch-run} scripts are provided for Zsh and Bash. @item @cpindex Zsh @cpindex Bash System is scanned during installation to check for Zsh and Bash availability. Path of found shells is substituted in the corresponding scripts, otherwise the default @code{/bin/@var{shell}} is used. @item @pgindex fswatch-run @cpindex Zsh @cpindex Bash If a supported shell is found, the @command{fswatch-run} symbolic link is created in the installation directory to the corresponding script. The lookup order of the shells is: @itemize @item Zsh. @item Bash. @end itemize @end itemize @section 1.3.5 @itemize @item Fix Issue 27: Redirect usage text to standard error unless @option{-h} or @option{--help}. @item Fix bug to write usage to standard error when invalid arguments are specified. @end itemize @section 1.3.4 @itemize @item @pgindex fswatch-run Fix bug in @command{fswatch-run} script to allow arguments to be passed to the command to run. @end itemize @section 1.3.3 @itemize @item @opindex one-per-batch@r{, inception} Add @option{-o}/@option{--one-per-batch} option to print a single message with the number of change events in the current batch. @item @pgindex fswatch-run Add @command{fswatch-run} shell script to mimic the behaviour of earlier @command{fswatch} versions and launch the specified command when change events are received. @end itemize @section 1.3.2 @itemize @item @pgindex fsw @cpindex @command{fsw} @command{fswatch} has been merged with @command{fsw}. @end itemize @node Introduction @chapter Introduction @command{fswatch} is a file change monitor that receives notifications when the contents of the specified files or directories are modified. @command{fswatch} interacts with the operating system using a @emph{monitor}. Currently, the following kinds of monitors are available: @itemize @item @cpindex File System Events, see FSEvents @cpindex FSEvents, API @cpindex monitor, FSEvents @cpindex Apple OS X A monitor based on the @emph{File System Events} @acronym{API} (FSEvents) of Apple OS X. @item @cpindex FreeBSD @cpindex BSD @cpindex kqueue @cpindex monitor, kqueue @cpindex Apple OS X A monitor based on @emph{kqueue}, an event notification interface introduced in FreeBSD 4.1 and supported on most *BSD systems (including Apple OS X). @item @cpindex Solaris @cpindex Illumos @cpindex File Events Notifications @cpindex monitor, fse A monitor based on the @emph{File Events Notification} @acronym{API} of the Solaris kernel and its derivatives, such as Illumos. @item @cpindex inotify @cpindex Linux @cpindex monitor, inotify A monitor based on @emph{inotify}, a Linux kernel subsystem that reports file system changes to applications. @item @cpindex Microsoft Windows monitor @cpindex monitor, Microsoft Windows @cpindex Microsoft Windows @fnindex @code{ReadDirectoryChangesW} A monitor based on the Microsoft Windows' @code{ReadDirectoryChangesW} function. @item @cpindex monitor, poll @fnindex @command{stat} A monitor which periodically stats the file system, saves file modification times in memory and manually calculates file system changes, which can work on any operating system where the @code{stat()} function can be used. @end itemize @command{fswatch} should build and work correctly on any system shipping either of the aforementioned APIs. @section History and @command{fswatch} Authors @cpindex authors @pgindex @command{fswatch} @cpindex @command{fswatch}, initial version @cpindex FSEvents @cpindex Apple OS X @flindex @file{AUTHORS} Alan @sc{Dipert} wrote the first implementation of @command{fswatch} in 2009. This version ran exclusively on Apple OS X and relied on the @emph{FSEvents} API to get change events from the OS. @pgindex @command{fsw} @cpindex FSEvents @cpindex kqueue @cpindex inotify @cpindex Microsoft Windows At the end of 2013 Enrico M. @sc{Crisostomo} wrote @command{fsw} aiming at providing not only a drop-in replacement for @command{fswatch}, but also a tool @emph{portable} across as many operating systems as possible. Besides adding support to other operating systems, @command{fsw} introduced new features such as inclusion and exclusion filters and customizable output formats. @cpindex @command{fsw}, merging with @command{fswatch} @cpindex @command{fswatch}, merging with @command{fsw} In April 2014 Alan and Enrico, in the best interest of users of either @command{fswatch} and @command{fsw}, agreed on merging the two programs together. At the same time, Enrico was taking over @command{fswatch} as a maintainer. As a consequence, development of @command{fswatch} has continued on its main repository while the @command{fsw} repository has been frozen. @section Reporting Bugs and Suggestions @anchor{Reporting Bugs and Suggestions} @cpindex bug @cpindex bug report @cpindex GitHub @cpindex @command{fswatch}, repository @cpindex @command{fswatch}, source code @flindex CONTRIBUTING.md If you find problems or have suggestions about this program or this manual, please report them as new issues in the official GitHub repository of @command{fswatch} at @uref{https://github.com/emcrisostomo/fswatch}. Please, read the @file{CONTRIBUTING.md} file for detailed instructions on how to contribute to @command{fswatch}. @node Tutorial Introduction to @command{fswatch} @chapter Tutorial Introduction to @command{fswatch} @cpindex tutorial This chapter is a tutorial walk-through on the most common use cases where @command{fswatch} is useful: @itemize @item Detecting file system changes. @item Observing file system changes. @item Processing @command{fswatch} output. @end itemize @section Detecting File System Changes @cpindex changes, detecting @cpindex @command{fswatch}, bulk mode A common use case is @emph{detecting} file system changes in a set of file system objects@footnote{In the context of this manual (unless specified otherwise), @emph{file system object} refers undistinctively to @emph{files}, @emph{directories} and @emph{symbolic links}.} where the @emph{details} of a change are irrelevant. This mode of operation is called @emph{bulk mode} and @command{fswatch} will only dump a single event record per batch@footnote{A @emph{batch} is an iteration of @command{fswatch} scanning logic, whose frequency is @math{\nu = l^{-1}}, where @math{l} is the @emph{latency}.} containing the number of affected file system objects. No other details are avaible in the event record. @pgindex @command{rsync} The most common application of this mode of operation is performing a bulk action on all the observed file system objects, such as a synchronization with @command{rsync}, which will serve us as an example. In this case, a change event triggers the execution of a synchronization script, no matter the event type kind nor the object the event affects. To run @command{fswatch} in batch mode, the (@option{-o}, @option{--one-per-batch}) must be used: @example $ fswatch -o @var{path} ... 2 10 @end example @noindent The (@option{-l}, @option{--latency}) option can be used to set the latency according to the requirements: @example $ fswatch -o -l 5 @var{path} ... 4 7 @end example @noindent This way, you can respond to change events in a way which is (or can easily be) path-independent (because you are not receiving any event detail) and you prefer to `bubble' events together to reduce the overhead of the command being executed. In bulk mode the output of @command{fswatch} is guaranteed to have the following structure: @example @var{number}\n @end example @noindent @fnindex @command{read} @pgindex @command{xargs} where @samp{number} is an integer value and @samp{\n} is the new line character. A line with this structure is very easy to read with either @command{xargs} or the @command{read} builtin: @example $ fswatch -o @var{path} | while read @var{num} ; \ do \ ... \ done @end example In many scripts of this kind, the @var{num} variable can even be ignored. @section Observing File System Changes @anchor{Observing File System Changes} @cpindex changes, observing @cpindex @command{fswatch}, main mode Besides the batch mode, @command{fswatch} provides a @emph{main} mode providing the full change events details and the file system objects they refer to. The main mode is @command{fswatch}'s @emph{default} mode of operation and needs no specific flags to be activated. In this mode, @command{fswatch} outputs change events to the standard output. By default, only the affected file name is printed and the change event record structure has the following structure: @example @var{path}\n @end example @noindent where @var{path} is the full path of the changed file system object. @command{fswatch} lets users customize the format of the event record and the information it includes. For example: @itemize @item @cpindex timestamp, add The event @emph{timestamp} can be added. @item @cpindex event mask, add The event mask can be added in either textual or numerical form. @item @cpindex record, format The event record can be defined using a @command{printf}-like format string. @end itemize @subsection Event details Beside the full path of the change object, details on the kind of change event can be obtained using the (@option{-x}, @option{--event-flags}) option: @example $ fswatch -xr @var{/path/to/observe} /path/to/observe Created Renamed OwnerModified IsFile ... @end example @noindent In this case, a space-separated list of change flags are printed after the path of the changed object. The record structure is thus: @example /absolute-path flag ( flag)* @end example @noindent where @samp{flag} is an event flag. At least one event flag is always present, and additional ones are `bubbled' into the same record and separated by space. For more information on event flags @pxref{Event Flags}. @subsection Parseability Issues @cpindex parseability @cpindex record, parsing The default record format is intuitive and human-readable. However, since a Unix file name may contain any character but the path separator @samp{/} and the @samp{NUL}@footnote{Depending on the file system being used, other restrictions may apply. However, for file system portability reasons, you should consider @samp{NUL} as the only forbidden character.} character, it suffers from two classes of parseability issues: @itemize @item The default choice of using @samp{\n} as record separator may lead to unexpected results because a file name can legally contain @samp{\n}. @pgindex @command{find} @pgindex @command{xargs} For this reason, along the line of what other tools such as @command{find} and @command{xargs} already do, the @samp{NUL} character (@samp{\0}) can alternatively be used: @example /absolute-path( flag)*\0 @end example @item Since a file name may contain spaces, this record structure is not unambigually parseable if more than one event flag is present: in this case, any subset @math{[0, x], x < n - 1} of the @math{n} event flags may be part or the file name and hence any parse result would be indeterminate. @end itemize Both issues can be solved using a custom record format (@pxref{Custom Record Formats}). @subsection Numeric Event Flags @cpindex event, flags @cpindex event, flags, numeric Instead of using user-friendly event flag @emph{names}, as seen in the previous section, @emph{numeric} event flags can be used instead. Currently, the real advantage this method offers, despite possibly cleaner flag-decoding logic, is the availability of a non-ambigous event record representation. To instruct @command{fswatch} to print numeric event flags, the (@option{-n}, @option{--numeric}) option must be used: @example $ fswatch -xnr @var{/path/to/observe} /absolute-path 2058 @end example @noindent The numeric event flag value is the bitwise OR of the individual event flag values, that are powers of 2. In the previous example, the flag @math{2058} is decomposed in powers of 2 as @math{2058 = 2048 + 8 + 2 = 2^{11} + 2^3 + 2}, that is, the first, the third and the eleventh event flags. @section Processing @command{fswatch} Output @cpindex record, parsing @cpindex record, piping Very often you wish to not only receive an event, but also react to it. The simplest way to do it is piping the output of @command{fswatch} to another process. Since in Unix and Unix-like file system file names may potentially contain any character but @samp{NUL} (@samp{\0}) and the path separator (@samp{/}), @command{fswatch} has a specific mode of operation when its output must be piped to another process. When the (@option{-0}, @option{--print0}) option is used, @command{fswatch} will use the @samp{NUL} character as record separator, thus allowing any other character to appear in a path. @fnindex @command{read} This is important because many commands and shell builtins (such as @command{read}) split lines using the newline character (@samp{\n}) and words using the characters in @env{$IFS}, which by default contains characters which may be present in a file name, resulting in a wrong event path being received and processed. @pgindex @command{xargs} The simplest way to pipe @command{fswatch}'s output to another program is using @command{xargs}: @example $ fswatch -0 (@var{opts})* (@var{paths})+ | xargs -0 -n 1 -I @{@} @var{command} @end example @noindent The command in this example does the following: @itemize @item @code{fswatch -0} will split records using the @samp{NUL} character. @item @code{xargs -0} will split records using the @samp{NUL} character. This is required to correctly match impedance with @command{fswatch}. @item @code{xargs -n 1} will invoke @code{@var{command}} every record. If you want to do it every @code{@var{x}} records, then use @code{xargs -n @var{x}}. @item @code{xargs -I @{@}} will substitute occurrences of @code{@{@}} in @code{@var{command}} with the parsed argument. If the command you are running does not need the event path name, just delete this option. If you prefer using another replacement string, substitute @code{@{@}} with another string of your choice. @end itemize @section Detecting the Boundaries of a Batch of Changes @cpindex batch marker @opindex batch-marker@r{, detail} If a process or script is piped to @command{fswatch} output, sometimes it would be desirable to detect the `boundaries' of a batch of changes. This way, the process receiving the stream of changes would rely on the timings imposed by the latency settings of @command{fswatch} to start a phase of events @emph{processing} after a phase or events @emph{gathering}. The @option{--batch-marker} option can be used to accomplish this task: @example $ fswatch --batch-marker -r ~ /home/fswatch/.zsh_history.LOCK NoOp /home/fswatch/.zsh_history.new /home/fswatch/.zsh_history /home/fswatch/.zsh_history.LOCK NoOp @end example @noindent In this example, the @samp{NoOp} records mark the end of the 1 second batches of events output by @command{fswatch}. The batch marker can be customized. For more information @ref{Batch Marker}. @section Receiving a Single Event @cpindex single event @opindex one-event@r{, detail} Another feature of @command{fswatch} is the possibility of receiving a @emph{single} event and exit. This is most useful when existing scripts processing events include the restart logic of @command{fswatch}. This use case is implemented by the @option{-1}, @option{--one-event} option: @example $ fswatch -1 /path/to/watch /path/to/watch/child0 /path/to/watch/child1 ... $ @end example @node Invoking @command{fswatch} @chapter Invoking @command{fswatch} @cpindex syntax This chapter is about how @command{fswatch} is invoked. There are many options and two styles for writing them. @section Synopsis of @command{fswatch} @command{fswatch} is invoked using the following syntax: @example fswatch (options)* (paths)+ @end example @noindent @fnindex @command{realpath} @command{fswatch} interprets file names as being relative to the working directory and canonicalizes them using @command{realpath}. If a directory is used as an argument, the directory object is watched and, optionally and depending on the monitor being used, the directory is scanned recursively and all its children are watched as well. Depending on the monitor being used, recursively scanning huge directory hierarchies or big set of files may be resource consuming, @acronym{CPU} intensive or even impossible. The characteristics of the available monitors in a system should be assessed in order to choose the best monitor according to the specific needs. Besides successful exits@footnote{Depending on the monitor and options being used, @command{fswatch} may not exit unless @emph{stopped} with a signal such as @code{TERM} or @code{QUIT}.}, indicated with the exit code 0, @command{fswatch} may exit with an error. @command{fswatch} will try to print a diagnostic description on @code{stderr} when an unexpected error occurs. @cpindex exit codes @cpindex error codes The documented@footnote{Exit codes are documented in @file{c/error.h} of @command{libfswatch}.} exit codes of @command{fswatch} are the following: @table @asis @item 0 @code{FSW_EXIT_OK}: No error occurred. @item 1 @code{FSW_EXIT_UNK_OPT}: An unknown option was input. @item 2 @code{FSW_EXIT_USAGE}: Help message was requested. @item 3 @code{FSW_EXIT_LATENCY}: Invalid latency. @item 4 @code{FSW_EXIT_STREAM}: A stream related problem occurred. @item 5 @code{FSW_EXIT_ERROR}: An unkown error occurred. @item 6 @code{FSW_EXIT_ENFILE}: A file could not be opened. @item 7 @code{FSW_EXIT_OPT}: Unused. @item 8 @code{FSW_EXIT_MONITOR_NAME}: The specified monitor does not exist. @item 9 @code{FSW_EXIT_FORMAT}: The specified monitor is invalid. @end table @section The Two Option Styles @command{fswatch} implements two option styles which are common in Unix and Unix-like operating systems and GNU software: @emph{short} and @emph{long} options. The biggest difference between short and long options are argument placing (for options taking one). @fnindex @command{getopt_long} Whether long options are available in a system depend on the availability of the @command{getopt_long} function at build time. For this reason, users should familiarise themselves with short options and use them when possible and do not rely on long options to be available on any @command{fswatch} installation. @subsection Long Options @cpindex options, long @cpindex long options @fnindex @command{getopt_long} In systems where the @command{getopt_long} function is available, each short option has a corresponding long option with a @emph{mnemonic} name starting with two dashes (e.g.: @option{--version}). Long options are meant to be easy to remember and to provide hints about what a command is going to perform. The following command: @example $ fswatch --event-flags --numeric --recursive ~ @end example @noindent is clearer than: @example $ fswatch -xnr ~ @end example If a long option takes an argument, it can be specified in two ways, depending on whether the argument is optional or mandatory: @itemize @item Separating the argument from the option name with an equal sign, if the argument is of either kind. @example $ fswatch --latency=5 ~ @end example @item Separating the argument from the option name with any amount of white space, if the argument is mandatory. @example $ fswatch --latency 5 ~ @end example @end itemize @subsection Short Options @cpindex options, short @cpindex short options Most options have a @emph{short} form consisting of a dash followed by a single character, such as @option{-l} (which is equivalent to @option{--latency}). When available, a short form is interchangeable with the long one. If a short option takes an argument, it can be specified in two ways: @itemize @item Separating the argument from the option name with any amount of white space: @example $ fswatch -l 5 ~ @end example @item Joining the argument to the option name: @example $ fswatch -l5 ~ @end example @end itemize Short options can be stuck together provided all the options but the last one take no argument, in which case it can be specified as described above. The command: @example $ fswatch -xnrl 5 ~ @end example @noindent is equivalent to: @example $ fswatch -x -n -r -l 5 ~ @end example @noindent where @samp{5} is the argument of @option{-l}. @section @command{fswatch} Options @cpindex options @cpindex options, list In the following table you can find the list, in alphabetical order, of @command{fswatch}'s options. @table @option @opsummary{access} @item --access @itemx -a Monitor file access. This functionality is supported by selected monitors only. @opsummary{allow-overflow} @item --allow-overflow Sets the allow overflow flag of the monitor. When this flag is set, monitor buffer overflows are reported as change events of type @code{fsw_event_flag::Overflow}. @opsummary{batch-marker} @item --batch-marker Print a marker at the end of every batch. @opsummary{directories} @item --directories @itemx -d Request the monitor to watch directories only during a recursive scan. This feature helps reducing the number of open file descriptors if a generic change event for a directory is acceptable instead of events on directory children. @opsummary{event} @item --event Filter events by @emph{type} using the specified event name or numeric mask (@pxref{Filtering by Event Type}). Specified event names are @emph{included} in the output. Multiple event types can be specified using this option multiple times. @opsummary{event-flags} @item --event-flags @itemx -x Print the event flags. @opsummary{event-flag-separator} @item --event-flag-separator Use the specified string as event flag separator. @opsummary{exclude} @item --exclude @itemx -e Exclude paths matching @command{@var{regex}}. @opsummary{extended} @item --extended @itemx -E Use extended regular expressions. @opsummary{filter-from} @item --filter-from Load filters from the specified @command{@var{file}}. @opsummary{fire-idle-events} @item --fire-idle-events Fire idle events. @opsummary{follow-links} @item --follow-links @itemx -L Symbolic links are followed instead of being watched as file system objects. @opsummary{format} @item --format Use the specified record format. @opsummary{format-time} @item --format-time @itemx -f Print the event time using the specified @command{@var{format}}. @opsummary{help} @item --help @itemx -h Show the help message. @opsummary{include} @item --include @itemx -i Include paths matching @command{@var{regex}}. @opsummary{insensitive} @item --insensitive @itemx -I Use case insensitive regular expressions. @opsummary{latency} @item --latency @itemx -l Set the latency using the specified @command{@var{value}}. @opsummary{list-monitors} @item --list-monitors @itemx -M List the available monitors. @opsummary{monitor} @item --monitor @itemx -m Use the specified @command{@var{monitor}}. @opsummary{monitor-property} @item --monitor-property Pass the specified property to the monitor (@pxref{Monitor Tunables}). @opsummary{numeric} @item --numeric @itemx -n Print a numeric event mask. @opsummary{one-per-batch} @item --one-per-batch @itemx -o Print a single message with the number of change events in the current batch. @opsummary{one-event} @item --one-event @itemx -1 Exit @command{fswatch} after the first set of events is received. @opsummary{print0} @item --print0 @itemx -0 Use the @acronym{ASCII} @samp{NUL} (@samp{\0}) as record separator. @opsummary{recursive} @item --recursive @itemx -r Recurse subdirectories. @opsummary{timestamp} @item --timestamp @itemx -t Print the event timestamp. @opsummary{utc-time} @item --utc-time @itemx -u Print the event time as @acronym{UTC} time. @opsummary{verbose} @item --verbose @itemx -v Print verbose output. @opsummary{version} @item --version Print the version of fswatch and exit. @end table @section Whitespace and Record Format @anchor{Whitespace and Record Format} @cpindex whitespace @cpindex record, format As seen in @ref{Observing File System Changes}, file names may contain characters such as @samp{\n} which are commonly used as line separators. Many commonly used Unix commands and shell builtins use characters in the @env{$IFS} environment variable@footnote{@acronym{IFS, Internal Field Separators}.} as @emph{separators} to split words. By default, @env{$IFS} contains the characters @samp{ } (@kbd{SPC}), @samp{\t}, @samp{\n} and @samp{\0} (@samp{NUL}). Therefore, if a file contains such a separator character (and all but @samp{NUL} are @emph{legal}), then a parsing ambiguity may arise when using certain record formats such as: @example @var{path}( @var{flag})+ @end example @noindent In this case, for example, if @math{n > 1} @var{flags} are present in the record, and hence more than one @samp{ } (@kbd{SPC}) is present, then it is not known whether any subset containing a number @math{x} of consecutive flags (@math{x < n}) is part of the path or not. The same reasoning applies when splitting @emph{lines} instead of @emph{words}: since @samp{\n} may be a legal file name character, then it is now known whether @samp{\n} indicates a record's end or simply is part of a file name. For this reason, in order to avoid parsing ambiguity, this options instructs @command{fswatch} to use @acronym{ASCII} @samp{NUL} as record separator. @quotation Warning The use of the @option{--print0} solves the @emph{line} splitting ambiguity but not the @emph{word} splitting ambiguity when using textual event flags. A solution to this problem is provided by @emph{custom record formats} (@pxref{Custom Record Formats}). Another way to get an unambiguous record format is using @emph{numeric} event flags (@pxref{Numeric Event Flags}). @end quotation @section Custom Record Formats @anchor{Custom Record Formats} @cpindex record, format, custom To solve the problem of line splitting ambiguities and to provide users the possibilities of tailoring the record format to their needs, @command{fswatch} allows users to specify the event record @emph{format} using the @option{--format} option. This options requires a @command{printf}-like@footnote{Although the available directive are much less than what @command{printf} offers.} @emph{format string} ordinary text containing zero or more @emph{directives}. Characters not belonging to a format directive are copied unchanged to the output, while directives are interpreted and replaced with the result of their evaluation. @subsection Format Directives @cpindex record, format, directives @cpindex record, format, escape character Directives start with @samp{%} which is always treated as a special character: either it marks the beginning of a directive or it is interpreted as an escape character@footnote{Which is the same as considering escaped characters the result of a directive.}. The available directives are: @table @command @item %% @cpindex @command{%%}, format directive Inserts the @samp{%} character. @item %0 @cpindex @command{%0}, format directive Inserts an @acronym{ASCII} @samp{NUL} (@samp{0}) character. @item %n @cpindex @command{%n}, format directive Inserts a @emph{newline} character. @item %f @cpindex @command{%f}, format directive Inserts the list of event flags, separated by default by the space character (@samp{ }) or by the separator specified with the @option{--event-flag-separator} option (@pxref{Event Flag Separator}). @item %p @cpindex @command{%p}, format directive Inserts the path. @item %t @cpindex @command{%t}, format directive Inserts the timestamp, formatted with @command{strftime} using the format optionally specified with the @option{--format-time} option. @end table @subsection Record Termination Each record is terminated by either a newline character (@samp{\n}) or an @acronym{ASCII} @samp{NUL} character when @option{-0} is specified. The record termination character has the following characteristics: @itemize @item It is @emph{not} part of the format string. @item Its value can only be chosen between @samp{\n} and @samp{NUL} (@samp{\0}). @item It cannot be suppressed. @end itemize @subsection Event Flag Separator @anchor{Event Flag Separator} @cpindex event flag, separator @cpindex format, event flag separator When the list of event flags is printed, textual items are separated by default by spaces (@samp{ }). The user can specify an alternate event flag separator using the @option{--event-flag-separator} and passing the desired separator string as argument. For instance, if the user wants event flags to be separated by a comma, the following command can be used: @example $ fswatch --event-flag-separator=, -x (options)* (paths)+ @end example @subsection Builtin Formats @cpindex format, builtin The format used by @command{fswatch} when a custom format is not specified is determined as follows@footnote{In the following example, the record termination character is not shown.}: @itemize @item @samp{%t } is added at the beginning of the format string if @option{-t} is used. @item @samp{%p} is always appended to the format string. @item @samp{ %f} is added at the end of the format string if @option{-x} is used. @end itemize @section Batch Marker @anchor{Batch Marker} @cpindex batch marker @opindex batch-marker@r{, detail} Since @command{fswatch} typically outputs an @emph{endless} event stream, processing parties parsing its output may be interested in `batch event processing': that is, processing batches of events instead of endlessly processing events one by one. To support this use case, @command{fswatch} provides the @option{--batch-marker} option; when specified, @command{fswatch} will output a customizable `batch marker record' processing parties can use as batch @emph{delimiters}. Batch demarcation is made naturally using the monitor's processing loop and its latency setting: every time the monitor loops (typically when latency is elapsed), then a batch marker is printed as final record, as shown in the next example: @example $ fswatch --batch-marker -r ~ /home/fswatch/.zsh_history.LOCK NoOp /home/fswatch/.zsh_history.new /home/fswatch/.zsh_history /home/fswatch/.zsh_history.LOCK NoOp @end example @noindent By default, the batch marker takes the form of a single-line record: @example NoOp(\n | \0) @end example @noindent terminated with either @samp{\n} or @samp{NUL} (@samp{\0}) depending on other @command{fswatch} settings. However, the user can customize it by providing the desired marker string as optional argument to @option{--batch-marker}: @example % ./fswatch --batch-marker="*** BATCH END ***" -r ~ /home/fswatch/.zsh_history.LOCK *** BATCH END *** @end example @section Idle events @cpindex event, idle An @emph{idle} event is a special event type that can optionally be emitted by @command{fswatch} if no change events were collected in a period of time whose average length is equal to the monitor latency (@pxref{Latency}). Idle events come in handy when an observer wants to perform an operation every time a change is detected @emph{or} after a specified amount of time even if no changes were detected. Idle events were introduced in version 1.9.0 and are available only when @command{fswatch} is built on a platform that supports C++11 threads (@command{std::thread}) and can be enabled using the @option{--fire-idle-events} option. An idle event has got the following characteristics: @itemize @item It has an empty path. @item It is of type @command{NoOp}. @end itemize @section Filtering by Path @cpindex path filter @cpindex path filter, inclusion @cpindex path filter, exclusion Filters are @emph{regular expression} which are evaluated against the monitored object path to determine whether a path must be accepted or rejected. Sometimes, the exclusion of a path may result in the exclusion of an object from the list of monitored objects, while other times a path must be evaluated only when an event is detected and in this case the corresponding object cannot be removed from the monitored object list in advance@footnote{This behaviour is monitor-specific.}. Event though event @emph{filtering} is commonly performed when processing @command{fswatch} output, the possibility of filtering paths `at the source' provides not only a greater amount of flexbility, but also: @itemize @item Improved performance, since @command{fswatch} will only monitor matching objects@footnote{Whether an object whose path is matched by an exclusion filter is monitored or not is a monitor-specific implementation detail.}. @item Less resource pressure, especially when resource-intensive monitors are used. This is especially important when using monitors that rely on the availability of open file descriptors for any monitored object. @item Simpler processing logic, since part of the path filtering logic is performed by @command{fswatch}. @end itemize @fnindex @command{regcomp} Since filters are implemented using the @samp{regcomp} library, this feature is built into @command{fswatch} only on systems where this library is available. @subsection Specifying Filters @cpindex path filter @cpindex path filter, file @opindex include@r{, detail} @opindex exclude@r{, detail} @opindex from-file@r{, detail} Path filters can be specified in two ways: @itemize @item By using the @option{--include} and @option{--exclude} options and the modifier options @option{--extended} and @option{--insensitive}. @item By loading them from a file using the @option{--from-file} option. @end itemize @subsubsection Filter File Format @cpindex path filter, file The filter file is made up of @emph{records} separated by a new line charactere, or formally a @acronym{ASCII} @samp{LF} (line feed) character. The structure of the record is the following: @example type pattern @end example @noindent where @samp{type} indicated the filter type and @samp{pattern} is the filter regular expression. @samp{type} may contain the following characters: @itemize @item @samp{+} or @samp{-}, to indicate respectively whether the filter is an inclusion or an exclusion filter. @item @samp{e} to use an extended regular expression. @item @samp{i} to use a case insensitive regular expression. @end itemize The following filter file instructs @command{fswatch} to ignore all files except those ending in @samp{.cpp}, ignoring case. @example - .* +i \.cpp$ @end example @subsection Types of Filters and Order of Execution @cpindex path filter, type @cpindex path filter, exexution order @cpindex path filter, inclusion @cpindex path filter, exclusion Two types of filters are available: @itemize @item @emph{Inclusion} filters. @item @emph{Exclusion} filters. @end itemize As their name indicates, they are used to include and exclude paths from the monitored object list and from resulting events. @command{fswatch} processes filters this way: @itemize @item If a path matches an including filter, the path is accepted no matter any other filter. @item If a path matches an excluding filter, the path is rejected. @item If a path matches no filters, the path is accepted. @end itemize @noindent Said another way: @itemize @item All paths are accepted @emph{by default}, unless an exclusion filter says otherwise. @item Inclusion filters may override any other exclusion filter. @item The order in the definition of filters in the command line has no effect. @end itemize @subsection Filter Modifiers @cpindex path filter, modifier @fnindex @command{regcomp} Filters are regular expression executed using the @uref{http://pubs.opengroup.org/onlinepubs/009695399/functions/regcomp.html, @command{regcomp} function} which is able to interpret case-sensitive and case-insensitive @emph{basic} and @emph{extended} regular expressions as described in @uref{http://pubs.opengroup.org/onlinepubs/009695399/functions/regcomp.html, Base Definitions volume of @acronym{IEEE} Std 1003.1-2001@comma{} Chapter 9@comma{} Regular Expressions}. @cpindex patch filter, case sensitivity The (@option{--insensitive}, @option{-I}) option instructs @command{fswatch} to use case insensitive regular expressions. The following example adds an exclusion filter so that @command{fswatch} ignores any file system object whose name ends with @kbd{.log}, no matter the case. @example $ fswatch -Ie ".*\.log$" ~ @end example @cpindex path filter, regular expression @cpindex path filter, extended regular expression The (@option{--extended}, @option{-E}) option instructs @command{fswatch} to use extended regular expressions, such as: @example $ fswatch -Ee "xl[st]+" ~ @end example Treating the characteristics and the difference between different kinds of regular expressions is out of scope in this manual. @section Filtering by Event Type @anchor{Filtering by Event Type} @cpindex filter, by event type @cpindex event type filter Events can be filtered by event type passing @command{fswatch} a list of event type @emph{names} or masks to accept using the @option{--event} option: @example $ fswatch -x --event Created --event Removed ~ $ fswatch -x --event 10 ~ @end example In this example, the mask of the @command{Created} event is @command{2} and the mask of the @command{Removed} event is @command{8}, so the mask of both events is @command{10}. If no event type filters are specified, @command{fswatch} will accept events of any type; on the other hand, as soon as a filter is specified, only events with a matching type will be accepted. @section Latency @anchor{Latency} @cpindex latency @opindex latency@r{, detail} The @emph{latency} @math{l}, expressed in seconds, is the amount of time that passes between the moment @command{fswatch} outputs a set of detected changes and the next. What happens during the time in-between is a monitor-specific implementation detail. Some @acronym{API}s, such as OS X's FSEvents, implement the concept of latency themselves and @command{fswatch} appears idle in between. Only when the specified amount of time passes, change events are received, processed and written to standard output. Others, such as Linux's inotify, do not@footnote{inotify publishes changes on a file identified by a descriptor which is @command{read} by @command{fswatch}.}; in this case, the inotify monitor @emph{waits} for events a maximum of @math{l} seconds; after that, the monitor logic loops again, performs house-keeping activities@footnote{Such as re-scanning objects which did not exist in the previous iteration.} and starts waiting again. The important thing to keep in mind is that latency and a monitor's behaviour are implementation-dependent: check the documentation of the monitor you are using to get further information about how latency is handled. @section Symbolic Links @cpindex symbolic link @opindex follow-links@r{, detail} Symbolic links are commonly used file system objects and, as it is customary for file system utilities, @command{fswatch} can either @emph{follow} them and monitor the linked object@footnote{When following links, the resolution is recursive: that is, if a link points to another symbolic link, this link is followed as well, and so on, until an object of a different kind is found.} or monitor the link itself. @section Event Flags @anchor{Event Flags} @cpindex event flag @opindex event-flags@r{, detail} Event flags identify the kind of change a file system object has undergone. Many of them directly map to common file system operations (such as creation, deletion, update, etc.), others are less common (such as attribute modification), and others are monitor and platform specific. Currently, @command{fswatch} maps monitor-specific event flags to `global' event flags acting as a sort of `greatest common denominator' of all the available monitor flags. The list of all the available global event flags, defined in @file{c/cevent.h}, is the following: @table @code @item NoOp Idle event, optionally issued when no changes were detected. @item PlatformSpecific This event maps a platform-specific event that has no corresponding flag. @item Created The object has been created. @item Updated The object has been updated. The kind of update is monitor-dependent. @item Removed The object has been removed. @item Renamed The object has been renamed. @item OwnerModified The object's owner has changed. @item AttributeModified An object's attribute has changed. @item MovedFrom The object has moved from this location to a new location of the same file system. @item MovedTo The object has moved from another location in the same file system into this location. @item IsFile The object is a regular file. @item IsDir The object is a directory. @item IsSymLink The object is a symbolic link. @item Link The object link count has changed. @item Overflow The monitor has overflowed. @end table @subsection Peculiarities and Pitfalls @cpindex event flag, peculiarities @cpindex event flag, pitfalls As you can see, the list of event flags contains element whose meaning is overlapping, at least partially. @command{Link}, for instance, may be equivalent to @command{Create} or @command{Removed}, depending on the whether the new link count is 1 or 0. @command{MovedFrom} and @command{MovedTo} may be equivalent to @command{Create} and @command{Removed} if the monitor is unable to discern a move operation has taken place (which is not always possible, as in the case of the poll monitor). @command{fswatch} is unable to univocally map the specific flags of all the monitors consistently. Forcefully, the mapping depends on the capabilities of the monitor which, in turn, depend on the capabilities of the @acronym{API} being used. For this reason, when processing change events, either the behaviour of the underlying monitor is known and taken into account, or all the flags which could possibly be attached at the operation being looked for must be taken into account. @quotation Warning As already explained (@pxref{Whitespace and Record Format}), the record format when using event flags in textual form is ambiguous. For this reason, using numeric event flags (@pxref{Numeric Event Flags}) or a custom record format (@pxref{Custom Record Formats}) is recommended when @command{fswatch} output must be processed. @end quotation @subsection Numeric Event Flags @anchor{Numeric Event Flags} @cpindex event flag, numeric @opindex numeric@r{, detail} When using the (@option{--numeric}, @option{-n}) @command{fswatch} will output event flags in @emph{numeric} format. A change event record may have multiple event flags and the numeric value is calculated as the bitwise @command{or} of the numeric values of all the flags. Since the value of an event flag is guaranteed to be unique and to be a number @math{n} in the form @math{n = 2^k} for a certain integer @math{k}, then the numeric value of a set of event flags is univocally determined. To check whether a given event flag is present when processing @command{fswatch} output, iti s sufficient to check whether its bit is set to 1 in the event value. Let's suppose we want to check whether the event flag whose value is @math{e} is present in a record whose flag numerical value is @math{n}. If the result @math{r} of @tex $$ r = e \wedge b $$ @end tex @noindent where @math{\wedge} is the bitwise @command{and} operator, is @math{r > 0}, then the flag @math{e} is present in @math{n}. The numeric value of all the event flags is the following: @itemize @item @command{NoOp}: 0 @item @command{PlatformSpecific}: 1 @item @command{Created}: 2 @item @command{Updated}: 4 @item @command{Removed}: 8 @item @command{Renamed}: 16 @item @command{OwnerModified}: 32 @item @command{AttributeModified}: 64 @item @command{MovedFrom}: 128 @item @command{MovedTo}: 256 @item @command{IsFile}: 512 @item @command{IsDir}: 1024 @item @command{IsSymLink}: 2048 @item @command{Link}: 4096 @item @command{Overflow}: 8192 @end itemize @section Choosing a Monitor @anchor{Choosing a Monitor} @cpindex monitor, choosing @opindex monitor@r{, detail} @command{fswatch} is a front-end to multiple @emph{monitors}, each taking advantage of different monitoring @acronym{API}s that may be available in a system. When building @command{fswatch}, @command{configure} scans the system to check which @acronym{API}s are available and builds support for all of them. A `special' monitor, the @emph{poll} monitor, manually scans the file system looking for differences. This is a fallback monitor for situations where other, more efficient @acronym{API}s are not available. The poll monitor is available on any system providing the @command{stat} function. Although @command{fswatch} chooses the `best' monitor between the available ones, a user may wish to use another. A specific monitor can be chosen using the (@option{--monitor}, @option{-m}) option. The list of available monitors can be obtained using the (@option{--list-monitors}, @option{-M}) option or at the end of the help message: @example $ fswatch --list-monitors fsevents_monitor kqueue_monitor poll_monitor @end example @example $ fswatch --help [...] Available monitors in this platform: fsevents_monitor kqueue_monitor poll_monitor [...] @end example @noindent A monitor can then be chosen by passing the mandatory @samp{@var{name}} argument to the @option{-m} option: @example $ fswatch -m kqueue_monitor ~ @end example @noindent In this case, the @samp{kqueue_monitor} is manually chosen. @section Recursive Scanning @cpindex recursive scanning @cpindex monitor, recursive scanning @opindex recursive@r{, detail} @command{fswatch}'s behaviour when scanning a directory may vary on a monitor by monitor basis. The semantics of the (@option{--recursive}, @option{-r}) option is: recursively scan subdirectories. However, implementations may silently add `@emph{if the monitor does not do so already}'. Since each monitor uses a different @acronym{API}, its behaviour depends on that of the backing @acronym{API}, and it is monitor-specific. @itemize @item The OS X @emph{FSEvents} @acronym{API} will always recurse subdirectories when monitoring a directory. In this case, even though @option{-r} is not specified, the monitor will monitor a directory's children nonetheless and there is no way to avoid it@footnote{But manually filtering out events based on paths, but @command{fswatch} does not do so @emph{by design}.}. @item The @emph{kqueue} monitor opens a file descriptor for each watched file. When @option{-r} is used and a directory is watched, @command{fswatch} will walk the file system hierarchy rooted at the directory and will open a file descriptor for each children to establish a watch on it. @item The @emph{File Events Notification} monitor does not recurse subdirectories by default. If a directory is watched, change events for the directory are received and even if some of them may be triggered by changes to some of the directory children, no details about their source will be provided. When the @option{-r} option is specified, the monitor will walk the file system hierarchy rooted at the directory and will watch all of its children. @item The @emph{inotify} and @code{ReadDirectoryChangesW} @acronym{API} returns change events for first-level children of a directory. When the @option{-r} option is not specified, change events for a watched directory's children are received. When the @option{-r} is specified, the monitor will walk the file system hierarchy rooted at the watched directory and will establish a watch on every directory object found. @end itemize In general, users should always use the @option{-r} option according to its semantics, no matter what the monitor does. The only case when @option{-r} is `not' honoured is when a monitor @emph{adds} information by recursively monitoring children even when @option{-r} is not specified. Please notice that when this happens, there may be no performance overhead since the backing @acronym{API} is specifically designed to behave like this. The authors think this is not a problem. If you think this behaviour can be improved, please fill a bug report (@pxref{Reporting Bugs and Suggestions}). @subsection Recursively Watching Directories @cpindex monitor, recursive scanning, directories Some monitors such as the @emph{kqueue} monitor require a file descriptor to be open for each watched file system object. This imposes a limitation on the maximum number of files that can be watched by @command{fswatch}. Before version 1.7, a user could only overcome this problem by increasing the maximum number of open file handles on its system. @command{fswatch} 1.7.0 introduced a new option, @option{-d}/@option{--directories}; when this option is used with a monitor that supports it, only directory objects will be watched during recursive scans. When a change occurs on a file, instead of reporting @emph{which} file has changed and how, @command{fswatch} will report a change event on the parent directory: this way, the number of required open file handles decreases at the expense of change event information granularity. @section Monitor Tunables @anchor{Monitor Tunables} @cpindex monitor, tunable Some monitors may accept monitor-specific parameters to tune their behaviour. To this purpose, @command{fswatch} offers a mechanism to pass key-value pair which are literally passed to the underlying monitor. A key-value pair @code{(k, v)} can be passed to a monitor using the @code{--monitor-property} option: @example $ fswatch --monitor-property k=v ~ @end example @noindent Multiple key-value pairs can be passed by using the @code{--monitor-property} option multiple times. @node Monitors @chapter Monitors @cpindex monitor, available @command{fswatch} is a file system monitoring utility that achieves portability across multiple platforms by decoupling the front-end (the @command{fswatch} itself) from back-end logic. Back-end logic is encapsulated in multiple, system-specific @emph{monitors}, interacting with different monitoring @acronym{API}s. Since each operating system may ship a different set of @acronym{API}s@footnote{In fact, only OS X supports more than one such @acronym{API}: BSD's @emph{kqueue} and @emph{FSEvents}.}, each operating system will support the corresponding set of monitors. The list of available monitors is decided at build time by the @command{configure} script. Monitors cannot be currently plugged-in but recompiling the @command{libfswatch} library (shipped with @command{fswath}). The list of available monitors can be obtained in the help message: @example $ fswatch --help [...] Available monitors in this platform: fsevents_monitor kqueue_monitor poll_monitor [...] @end example @section Available Monitors @cpindex monitors, available Currently, the available monitors are: @itemize @item The @emph{FSEvents} monitor, a monitor based on the File System Events @acronym{API} of Apple OS X (@pxref{The FSEvents Monitor}). @item The @emph{kqueue} monitor, a monitor based on @emph{kqueue}, an event notification interface introduced in FreeBSD 4.1 and supported on most *BSD systems (including OS X) (@pxref{The kqueue Monitor}). @item The @emph{File Events Notification} monitor, a monitor based on the File Events Notification @acronym{API} of the Solaris/Illumos kernel (@pxref{The File Events Notification Monitor}). @item The @emph{inotify} monitor, a Linux kernel subsystem that reports file system changes to applications (@pxref{The inotify Monitor}). @item The @emph{Windows} monitor, a monitor that uses the Microsoft Windows' @code{ReadDirectoryChangesW} function and reads change events asynchronously. @item The @emph{poll} monitor, a monitor that periodically stats the file system, saves file modification times in memory and manually calculates file system changes, which can work on any operating system where @command{stat} can be used (@pxref{The Poll Monitor}). @end itemize Each monitor has its own strengths, weakness and peculiarities. Although @command{fswatch} strives to provide a uniform experience no matter which monitor is used, it is still important for users to know which monitor they are using and to be aware of existing bugs, limitations, corner cases or pathological behaviour. @section The FSEvents Monitor @anchor{The FSEvents Monitor} @cpindex FSEvents monitor @cpindex monitor, FSEvents The FSEvents monitor, available only on Apple OS X, has no known limitations and scales very well with the number of files being observed. In fact, I observed no performance degradation when testing @command{fswatch} observing changes on a filesystem of 500 @acronym{GB} over long periods of time. This is the default monitor on Apple OS X. @subsection Peculiarities @cpindex monitor, FSEvents, peculiarities The (@option{--recursive}, @option{-r}) and (@option{--directories}, @option{-d}) options have no effect when used with the FSEvents monitor since the FSEvents @acronym{API} already monitors a directory's children by default. There is no overhead nor resource-consumption issue with this behaviour, but users processing the output must be aware that for each directory @emph{multiple} events may be generated by its children. @section The kqueue Monitor @anchor{The kqueue Monitor} @cpindex kqueue monitor @cpindex monitor, kqueue @fnindex @command{kevent} The kqueue monitor, available on any *BSD system featuring the @command{kevent} function, is very similar in principle to other similar @acronym{API}s (such as FSEvents and inotify) but has important drawback and limitations. @subsection Peculiarities @cpindex monitor, kqueue, peculiarities The kqueue monitor @emph{requires a file descriptor to be opened for every file being watched}. As a result, this monitor scales @emph{badly} with the number of files being observed and may begin to misbehave as soon as the @command{fswatch} process runs out of file descriptors. In this case, @command{fswatch} dumps one error on standard error for every file that cannot be opened so that users are notified and can take action, including terminating the @command{fswatch} session. Beware that on some systems the maximum number of file descriptors that can be opened by a process is set to a @emph{very low value} (values as low as 256 are not uncommon), even if the operating system may allow a much larger value. If you are running out of file descriptors when using this monitor and you cannot reduce the number of observed items, either: @itemize @item Consider raising the number of maximum open file descriptors (check your OS' documentation). @item Consider using the (@option{--directories}, @option{-d}) option. @item Consider using another monitor. @end itemize @section The File Events Notification Monitor @anchor{The File Events Notification Monitor} @cpindex File Events Notification monitor @cpindex monitor, File Events Notification The @emph{File Events Notification} monitor is backed by the File Events Notification @acronym{API} of the Solaris/Illumos kernel. This monitor is very efficient, it suffers from no known resource-exhaustion problems and it scales very well with the number of objects being watched. This monitor is the default monitor on systems running a Solaris or Illumos kernel providing this @acronym{API}. @section The inotify Monitor @anchor{The inotify Monitor} @cpindex inotify monitor @cpindex monitor, inotify @fnindex @command{inotify_init} @fnindex @command{inotify_rm_watch} @fnindex @command{inotify_add_watch} The @emph{inotify} monitor is backed by the inotify @acronym{API} and the @code{inotify_*} set of functions, introduced on Linux since kernel 2.6.13. Similarly to the FSEvents @acronym{API}, inotify is very efficient, it suffers from no known resource-exhaustion problems and it scales very well with the number of objects being watched. This monitor is the default monitor on systems running inotify-enabled Linux kernels. @subsection Peculiarities @cpindex monitor, inotify, peculiarities @subsubsection Queue Overflow @cpindex monitor, inotify, queue overflow @cpindex monitor, inotify, overflow @cpindex queue overflow The inotify monitor may suffer a queue overflow if events are generated faster than they are read from the queue. In any case, the application is guaranteed to receive an overflow notification which can be handled to gracefully recover. By default, the @command{fswatch} process is terminated after the notification is sent by throwing an exception. Using the @option{--allow-overflow} option makes @command{fswatch} emit a change event of type @command{Overflow} without exiting. @subsubsection Duplicate Events @cpindex monitor, inotify, duplicate events The inotify @acronym{API} sends events for the @emph{direct} child elements of a watched directory and it scales pretty well with the number of watched items. For this reason, depending on the number of files to watch, it may sometimes be preferable to non-recursively watch a common parent directory and filter received events rather than adding a huge number of file watches. If recursive watches are used, then duplicate change events will be received: @itemize @item One generated by the parent directory of the file that has changed. @item One generated by the file that has changed. @end itemize @section The Windows monitor @anchor{The Windows monitor} @cpindex Windows monitor @cpindex monitor, Windows The Windows monitor uses the Windows' @code{ReadDirectoryChangesW} function for each watched path and asynchronously waits for change events using overlapped I/O. The Windows monitor is the default choice on Windows because it is the best performing monitor on that platform and it is affected by virtually no limitations. @subsection Peculiarities @cpindex monitor, Windows, peculiarities @subsubsection Buffer Overflow @cpindex monitor, Windows, buffer overflow @cpindex monitor, Windows, overflow @cpindex buffer overflow The Windows monitor may suffer a buffer overflow if events are generated faster than they can be stored in the buffer allocated by the operating system when @code{ReadDirectoryChangesW} is first called on a watched path. Once the buffer has been created, it is never resized and will live until the file handle events are listened upon is closed. Another source of overflow is the size of the buffer passed to @code{ReadDirectoryChangesW} by its caller. Unless the one created by Windows, this buffer's size can be tuned by the user. The custom @code{windows.ReadDirectoryChangesW.buffer.size} property can be used to programmatically set the size of the buffer (in bytes) when @command{fswatch} is invoked, as shown in the following example where a 4 kilobytes buffer is used: @example $ fswatch --monitor-property \ windows.ReadDirectoryChangesW.buffer.size=4096 \ ~ @end example By default, the @command{fswatch} process is terminated after the notification is sent by throwing an exception. Using the @command{--allow-overflow} option makes @command{fswatch} emit a change event of type @command{Overflow} without exiting. @subsubsection Directory Watching The Windows @acronym{API} lets user watch @emph{directory}, not @emph{files}. @command{fswatch} currently passes path arguments to the underlying monitor as they are: as a consequence, if a path corresponds to a file, the monitor will emit an error and will not be able to watch it. For the same reasons, the (@option{--directories}/@option{-d}) has no effect when using this monitor. @subsubsection Recursivity The Windows @acronym{API} will return change events related to a watched directory and any children of its, at any depth. Essentially, the subtree rooted at a directory is @emph{recursively} watched even if the @code{-r} option is not used explicitly. @section The Poll Monitor @anchor{The Poll Monitor} @cpindex Poll monitor @cpindex monitor, poll The poll monitor was added as a fallback mechanisms in the cases where no other monitor could be used, including: @itemize @item Operating system without any sort of file events @acronym{API}. @item Situations where the limitations of the available monitors cannot be overcome@footnote{E.g.: observing a number of files greater than the available file descriptors on a system using the kqueue monitor.}. @end itemize The poll monitor, available on any platform, only relies on available @acronym{CPU} and memory to perform its task. @subsection Peculiarities @cpindex monitor, poll, peculiarities @subsubsection Performance Problems @cpindex monitor, poll, performanc The resource consumption of this monitor increases increases @emph{linearly} with the number of files being watched (the resulting system performance will probably degrade @emph{linearly} or quicker). @fnindex @command{stat} The authors' experience indicates that @command{fswatch} requires approximately 150 @acronym{MB} of @acronym{RAM} memory to observe a hierarchy of 500,000 files with a minimum path length of 32 characters. A common bottleneck of the poll monitor is disk access, since @command{stat()}-ing a great number of files may take a @emph{huge} amount of time. In this case, the latency (@pxref{Latency}) should be set to a sufficiently large value in order to reduce the performance degradation that may result from frequent disk access; this monitor, in fact, will re-scan @emph{all} the monitored object hierarchy looking for differences @emph{every} time its `monitoring loop' is repeated. @quotation Note Using a disk drive with lower latencies may certainly help, although the authors suspect that switching to an operating system with proper file monitoring @acronym{API}s is a better solution when performance problems with the poll monitors are experienced or when @command{fswatch} should drive mission-critical processes. @end quotation @subsubsection Missing Events and Missing Event Flags @cpindex monitor, poll, missing events @cpindex missing events Since this monitor periodically checks the state of monitored objects looking for differences, it may miss events happened between one scan and another. Let's suppose, for example, that a file @file{file} exists at time @math{t_0} when a scan occurs. The poll monitors detects @file{file} and saves the relevant attributes in memory. @file{file} is then updated, moved to another place and recreated with the same name. The chain of events@footnote{The actual chain of events may in fact vary depending on the monitor being used.} occurred to @file{file} are: @itemize @item @command{Updated} @item @command{MovedFrom} (or @command{Deleted}) @item @command{Created} @item @command{Link} @end itemize At time @math{t_1}, another scan runs and the poll monitor detects that the modification date has changed. The poll monitor can only infer that a `change' has occurred and raises an @command{Updated} event; other events that would be noticed and raised by other @acronym{API}s are effectively @emph{lost} since they go unnoticed. The odds of incurring such a loss is inversely proportional to the latency @math{l}: reducing the latency helps alleviating this problem, although on the other hands it also results in linearly increasing resource usage. @section How to Choose a Monitor @command{fswatch} already chooses the `best' monitor for your platform if you do not specify any. However, a specific monitor may be better suited to specific use cases. Please, see @ref{Monitors} to get a description of all the available monitors and their limitations. Usage recommendations are as follows: @itemize @item On Apple OS X, use only the FSEvents monitor (which is the default behaviour). @item On Solaris/Illumos-based systems, use the File Events Notification monitor. @item On Linux, use the inotify monitor (which is the default behaviour). @item If the number of files to observe is sufficiently small, use the kqueue monitor. Beware that on some systems the maximum number of file descriptors that can be opened by a process is set to a very @emph{low} value (values as low as 256 are not uncommon), even if the operating system may allow a much larger value. In this case, check your OS documentation to raise this limit on either a per process or a system-wide basis. @item If feasible, watch directories instead of watching files. Properly crafting the receiving side of the events to deal with directories may sensibly reduce the monitor resource consumption. @item @fnindex @command{stat} If none of the above applies, use the poll monitor. The authors' experience indicates that fswatch requires approximately 150 @acronym{MB} of @acronym{RAM} memory to observe a hierarchy of 500,000 files with a minimum path length of 32 characters. A common bottleneck of the poll monitor is disk access, since @command{stat()}-ing a great number of files may take a huge amount of time. In this case, the latency should be set to a sufficiently large value in order to reduce the performance degradation that may result from frequent disk access. @end itemize @node GNU Free Documentation License @appendix GNU Free Documentation License @include fdl.texi @c Print function index @node Index of Functions @appendix Index of Functions @printindex fn @c Print program index @node Index of Programs @appendix Index of Programs @printindex pg @c Print file index @node Index of Files @appendix Index of Files @printindex fl @c Print option index @node Index of Command Line Options @appendix Index of Command Line Options This appendix contains an index of all @command{fswatch} long command line options. The options are listed without the preceding double-dash. @printindex op @node General Index @unnumbered Index @printindex cp @bye fswatch-1.11.2/fswatch/doc/value.texi000644 000765 000024 00000000333 13174733730 020077 0ustar00enricostaff000000 000000 @macro xopindex{option,text} @opindex \option\@r{, \text\} @end macro @macro opsummary{option} @ifclear ANCHOR--\option\ @set ANCHOR--\option\ 1 @anchor{--\option\} @end ifclear @xopindex{\option\, summary} @end macro fswatch-1.11.2/fswatch/doc/Makefile.am000644 000765 000024 00000001342 13174733730 020125 0ustar00enricostaff000000 000000 # # Copyright (c) 2014-2015 Enrico M. Crisostomo # # 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, 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 . # info_TEXINFOS = fswatch.texi fswatch_TEXINFOS = fdl.texi value.texi fswatch-1.11.2/fswatch/doc/fdl.texi000644 000765 000024 00000055607 13174733730 017546 0ustar00enricostaff000000 000000 @c The GNU Free Documentation License. @center Version 1.3, 3 November 2008 @c This file is intended to be included within another document, @c hence no sectioning command or @node. @display Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. @uref{http://fsf.org/} Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @end display @enumerate 0 @item PREAMBLE The purpose of this License is to make a manual, textbook, or other functional and useful document @dfn{free} in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others. This License is a kind of ``copyleft'', which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software. We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference. @item APPLICABILITY AND DEFINITIONS This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The ``Document'', below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as ``you''. You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law. A ``Modified Version'' of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language. A ``Secondary Section'' is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them. The ``Invariant Sections'' are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none. The ``Cover Texts'' are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words. A ``Transparent'' copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not ``Transparent'' is called ``Opaque''. Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, La@TeX{} input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only. The ``Title Page'' means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, ``Title Page'' means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text. The ``publisher'' means any person or entity that distributes copies of the Document to the public. A section ``Entitled XYZ'' means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as ``Acknowledgements'', ``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title'' of such a section when you modify the Document means that it remains a section ``Entitled XYZ'' according to this definition. The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License. @item VERBATIM COPYING You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3. You may also lend copies, under the same conditions stated above, and you may publicly display copies. @item COPYING IN QUANTITY If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects. If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages. If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public. It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document. @item MODIFICATIONS You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version: @enumerate A @item Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission. @item List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement. @item State on the Title page the name of the publisher of the Modified Version, as the publisher. @item Preserve all the copyright notices of the Document. @item Add an appropriate copyright notice for your modifications adjacent to the other copyright notices. @item Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below. @item Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice. @item Include an unaltered copy of this License. @item Preserve the section Entitled ``History'', Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled ``History'' in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence. @item Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the ``History'' section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission. @item For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein. @item Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles. @item Delete any section Entitled ``Endorsements''. Such a section may not be included in the Modified Version. @item Do not retitle any existing section to be Entitled ``Endorsements'' or to conflict in title with any Invariant Section. @item Preserve any Warranty Disclaimers. @end enumerate If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles. You may add a section Entitled ``Endorsements'', provided it contains nothing but endorsements of your Modified Version by various parties---for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard. You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one. The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version. @item COMBINING DOCUMENTS You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers. The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work. In the combination, you must combine any sections Entitled ``History'' in the various original documents, forming one section Entitled ``History''; likewise combine any sections Entitled ``Acknowledgements'', and any sections Entitled ``Dedications''. You must delete all sections Entitled ``Endorsements.'' @item COLLECTIONS OF DOCUMENTS You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects. You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document. @item AGGREGATION WITH INDEPENDENT WORKS A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an ``aggregate'' if the copyright resulting from the compilation is not used to limit the legal rights of the compilation's users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document. If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document's Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate. @item TRANSLATION Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail. If a section in the Document is Entitled ``Acknowledgements'', ``Dedications'', or ``History'', the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title. @item TERMINATION You may not copy, modify, sublicense, or distribute the Document except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, or distribute it is void, and will automatically terminate your rights under this License. However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, receipt of a copy of some or all of the same material does not give you any rights to use it. @item FUTURE REVISIONS OF THIS LICENSE The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See @uref{http://www.gnu.org/copyleft/}. Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License ``or any later version'' applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation. If the Document specifies that a proxy can decide which future versions of this License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Document. @item RELICENSING ``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any World Wide Web server that publishes copyrightable works and also provides prominent facilities for anybody to edit those works. A public wiki that anybody can edit is an example of such a server. A ``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the site means any set of copyrightable works thus published on the MMC site. ``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0 license published by Creative Commons Corporation, a not-for-profit corporation with a principal place of business in San Francisco, California, as well as future copyleft versions of that license published by that same organization. ``Incorporate'' means to publish or republish a Document, in whole or in part, as part of another Document. An MMC is ``eligible for relicensing'' if it is licensed under this License, and if all works that were first published under this License somewhere other than this MMC, and subsequently incorporated in whole or in part into the MMC, (1) had no cover texts or invariant sections, and (2) were thus incorporated prior to November 1, 2008. The operator of an MMC Site may republish an MMC contained in the site under CC-BY-SA on the same site at any time before August 1, 2009, provided the MMC is eligible for relicensing. @end enumerate @page @heading ADDENDUM: How to use this License for your documents To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page: @smallexample @group Copyright (C) @var{year} @var{your name}. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU Free Documentation License''. @end group @end smallexample If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the ``with@dots{}Texts.''@: line with this: @smallexample @group with the Invariant Sections being @var{list their titles}, with the Front-Cover Texts being @var{list}, and with the Back-Cover Texts being @var{list}. @end group @end smallexample If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation. If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software. @c Local Variables: @c ispell-local-pdict: "ispell-dict" @c End: fswatch-1.11.2/m4/ltversion.m4000644 000765 000024 00000001273 13175374052 016476 0ustar00enricostaff000000 000000 # ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 4179 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.6]) m4_define([LT_PACKAGE_REVISION], [2.4.6]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.6' macro_revision='2.4.6' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) fswatch-1.11.2/m4/ax_fsevents_have_file_events.m4000644 000765 000024 00000003202 13174733730 022357 0ustar00enricostaff000000 000000 # =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_fsevents_have_file_events.html # =========================================================================== # # SYNOPSIS # # AX_FSEVENTS_HAVE_FILE_EVENTS() # # DESCRIPTION # # This macro checks if the OS X FSEvents API supports file events. # # If it does, define the ax_cv_fsevents_have_file_events environment variable to # "yes" and define HAVE_FSEVENTS_FILE_EVENTS. # # CONTRIBUTING # # You can contribute changes on GitHub by forking this repository: # # https://github.com/emcrisostomo/CXX-Autoconf-Macros.git # # LICENSE # # Copyright (c) 2014 Enrico M. Crisostomo # # 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 1 AC_DEFUN([AX_FSEVENTS_HAVE_FILE_EVENTS], [AC_CACHE_CHECK( [for file events in OS X FSEvents API], ax_cv_fsevents_have_file_events, [dnl AC_LANG_PUSH([C]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM( [#include ], [int i = kFSEventStreamCreateFlagFileEvents;] )], [ax_cv_fsevents_have_file_events=yes], [ax_cv_fsevents_have_file_events=no] ) AC_LANG_POP([C])]) if test x"$ax_cv_fsevents_have_file_events" = "xyes" then AC_DEFINE(HAVE_FSEVENTS_FILE_EVENTS, 1, [Define if the file events are supported by OS X FSEvents API.]) fi ]) fswatch-1.11.2/m4/po.m4000644 000765 000024 00000045037 13175374042 015074 0ustar00enricostaff000000 000000 # po.m4 serial 24 (gettext-0.19) dnl Copyright (C) 1995-2014 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1995-2000. dnl Bruno Haible , 2000-2003. AC_PREREQ([2.60]) dnl Checks for all prerequisites of the po subdirectory. AC_DEFUN([AM_PO_SUBDIRS], [ AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl AC_REQUIRE([AC_PROG_SED])dnl AC_REQUIRE([AM_NLS])dnl dnl Release version of the gettext macros. This is used to ensure that dnl the gettext macros and po/Makefile.in.in are in sync. AC_SUBST([GETTEXT_MACRO_VERSION], [0.19]) dnl Perform the following tests also if --disable-nls has been given, dnl because they are needed for "make dist" to work. dnl Search for GNU msgfmt in the PATH. dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. dnl The second test excludes FreeBSD msgfmt. AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], :) AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT]) dnl Test whether it is GNU msgfmt >= 0.15. changequote(,)dnl case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;; *) MSGFMT_015=$MSGFMT ;; esac changequote([,])dnl AC_SUBST([MSGFMT_015]) changequote(,)dnl case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;; *) GMSGFMT_015=$GMSGFMT ;; esac changequote([,])dnl AC_SUBST([GMSGFMT_015]) dnl Search for GNU xgettext 0.12 or newer in the PATH. dnl The first test excludes Solaris xgettext and early GNU xgettext versions. dnl The second test excludes FreeBSD xgettext. AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], :) dnl Remove leftover from FreeBSD xgettext call. rm -f messages.po dnl Test whether it is GNU xgettext >= 0.15. changequote(,)dnl case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;; *) XGETTEXT_015=$XGETTEXT ;; esac changequote([,])dnl AC_SUBST([XGETTEXT_015]) dnl Search for GNU msgmerge 0.11 or newer in the PATH. AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :) dnl Installation directories. dnl Autoconf >= 2.60 defines localedir. For older versions of autoconf, we dnl have to define it here, so that it can be used in po/Makefile. test -n "$localedir" || localedir='${datadir}/locale' AC_SUBST([localedir]) dnl Support for AM_XGETTEXT_OPTION. test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS= AC_SUBST([XGETTEXT_EXTRA_OPTIONS]) AC_CONFIG_COMMANDS([po-directories], [[ for ac_file in $CONFIG_FILES; do # Support "outfile[:infile[:infile...]]" case "$ac_file" in *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; esac # PO directories have a Makefile.in generated from Makefile.in.in. case "$ac_file" in */Makefile.in) # Adjust a relative srcdir. ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` # In autoconf-2.13 it is called $ac_given_srcdir. # In autoconf-2.50 it is called $srcdir. test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" case "$ac_given_srcdir" in .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; /*) top_srcdir="$ac_given_srcdir" ;; *) top_srcdir="$ac_dots$ac_given_srcdir" ;; esac # Treat a directory as a PO directory if and only if it has a # POTFILES.in file. This allows packages to have multiple PO # directories under different names or in different locations. if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then rm -f "$ac_dir/POTFILES" test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" gt_tab=`printf '\t'` cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ${gt_tab}]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" POMAKEFILEDEPS="POTFILES.in" # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend # on $ac_dir but don't depend on user-specified configuration # parameters. if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then # The LINGUAS file contains the set of available languages. if test -n "$OBSOLETE_ALL_LINGUAS"; then test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" fi ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` # Hide the ALL_LINGUAS assignment from automake < 1.5. eval 'ALL_LINGUAS''=$ALL_LINGUAS_' POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" else # The set of available languages was given in configure.in. # Hide the ALL_LINGUAS assignment from automake < 1.5. eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' fi # Compute POFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) # Compute UPDATEPOFILES # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) # Compute DUMMYPOFILES # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) # Compute GMOFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) case "$ac_given_srcdir" in .) srcdirpre= ;; *) srcdirpre='$(srcdir)/' ;; esac POFILES= UPDATEPOFILES= DUMMYPOFILES= GMOFILES= for lang in $ALL_LINGUAS; do POFILES="$POFILES $srcdirpre$lang.po" UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" DUMMYPOFILES="$DUMMYPOFILES $lang.nop" GMOFILES="$GMOFILES $srcdirpre$lang.gmo" done # CATALOGS depends on both $ac_dir and the user's LINGUAS # environment variable. INST_LINGUAS= if test -n "$ALL_LINGUAS"; then for presentlang in $ALL_LINGUAS; do useit=no if test "%UNSET%" != "$LINGUAS"; then desiredlanguages="$LINGUAS" else desiredlanguages="$ALL_LINGUAS" fi for desiredlang in $desiredlanguages; do # Use the presentlang catalog if desiredlang is # a. equal to presentlang, or # b. a variant of presentlang (because in this case, # presentlang can be used as a fallback for messages # which are not translated in the desiredlang catalog). case "$desiredlang" in "$presentlang"*) useit=yes;; esac done if test $useit = yes; then INST_LINGUAS="$INST_LINGUAS $presentlang" fi done fi CATALOGS= if test -n "$INST_LINGUAS"; then for lang in $INST_LINGUAS; do CATALOGS="$CATALOGS $lang.gmo" done fi test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do if test -f "$f"; then case "$f" in *.orig | *.bak | *~) ;; *) cat "$f" >> "$ac_dir/Makefile" ;; esac fi done fi ;; esac done]], [# Capture the value of obsolete ALL_LINGUAS because we need it to compute # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it # from automake < 1.5. eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' # Capture the value of LINGUAS because we need it to compute CATALOGS. LINGUAS="${LINGUAS-%UNSET%}" ]) ]) dnl Postprocesses a Makefile in a directory containing PO files. AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE], [ # When this code is run, in config.status, two variables have already been # set: # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in, # - LINGUAS is the value of the environment variable LINGUAS at configure # time. changequote(,)dnl # Adjust a relative srcdir. ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` # In autoconf-2.13 it is called $ac_given_srcdir. # In autoconf-2.50 it is called $srcdir. test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" case "$ac_given_srcdir" in .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; /*) top_srcdir="$ac_given_srcdir" ;; *) top_srcdir="$ac_dots$ac_given_srcdir" ;; esac # Find a way to echo strings without interpreting backslash. if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then gt_echo='echo' else if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then gt_echo='printf %s\n' else echo_func () { cat < "$ac_file.tmp" tab=`printf '\t'` if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then # Add dependencies that cannot be formulated as a simple suffix rule. for lang in $ALL_LINGUAS; do frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` cat >> "$ac_file.tmp" < /dev/null; then # Add dependencies that cannot be formulated as a simple suffix rule. for lang in $ALL_LINGUAS; do frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'` cat >> "$ac_file.tmp" <> "$ac_file.tmp" < # # 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 2 AC_DEFUN_ONCE([AX_GIT_CURRENT_BRANCH],[dnl EMC_PATH_PROG([GIT], [git], [], [], [git path]) AS_VAR_SET_IF([GIT], [ AC_MSG_CHECKING([for current git branch]) AS_VAR_SET([ax_git_current_branch], [$("${GIT}" rev-parse --symbolic-full-name --abbrev-ref HEAD)]) AS_IF(dnl [test $? -eq 0], [AC_MSG_RESULT([${ax_git_current_branch}])], [ AC_MSG_RESULT([]) AC_MSG_WARN([An error occurred while invoking git]) AS_UNSET([ax_git_current_branch]) ]) AC_SUBST([ax_git_current_branch]) ], []) ])dnl AX_GIT_CURRENT_BRANCH fswatch-1.11.2/m4/ltoptions.m4000644 000765 000024 00000034262 13175374051 016507 0ustar00enricostaff000000 000000 # Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option '$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], [_LT_WITH_AIX_SONAME([aix])]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the 'shared' and # 'disable-shared' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the 'static' and # 'disable-static' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the 'fast-install' # and 'disable-fast-install' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_AIX_SONAME([DEFAULT]) # ---------------------------------- # implement the --with-aix-soname flag, and support the `aix-soname=aix' # and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT # is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. m4_define([_LT_WITH_AIX_SONAME], [m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[[5-9]]*,yes) AC_MSG_CHECKING([which variant of shared library versioning to provide]) AC_ARG_WITH([aix-soname], [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], [case $withval in aix|svr4|both) ;; *) AC_MSG_ERROR([Unknown argument to --with-aix-soname]) ;; esac lt_cv_with_aix_soname=$with_aix_soname], [AC_CACHE_VAL([lt_cv_with_aix_soname], [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) with_aix_soname=$lt_cv_with_aix_soname]) AC_MSG_RESULT([$with_aix_soname]) if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac _LT_DECL([], [shared_archive_member_spec], [0], [Shared archive member basename, for filename based shared library versioning on AIX])dnl ])# _LT_WITH_AIX_SONAME LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. # MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac], [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) fswatch-1.11.2/m4/ltsugar.m4000644 000765 000024 00000010440 13175374051 016125 0ustar00enricostaff000000 000000 # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) fswatch-1.11.2/m4/emc_path_prog.m4000644 000765 000024 00000004247 13174733730 017265 0ustar00enricostaff000000 000000 # -*- Autoconf -*- # # SYNOPSIS # # EMC_PATH_PROG(variable, prog, [action-if-found], [action-if-not-found], # [variable-desc], [path]) # # DESCRIPTION # # Check whether prog exists in PATH, or in path if provided, and make variable # precious invoking AC_ARG_VAR(variable, variable-desc). If it does, set # variable to its PATH, and execute action-if-found, otherwise unset variable # and execute action-if-not-found. Both actions are optional. # # LICENSE # # Copyright (c) 2015-2017 Enrico M. Crisostomo # # 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 2 AC_DEFUN([EMC_PATH_PROG], [dnl AC_ARG_VAR([$1], [$5]) AC_PATH_PROG([$1], [$2], [], [$6]) AS_VAR_SET_IF([ac_cv_path_$1], [$3], [ AS_UNSET($1) $4 ]) ])dnl EMC_PATH_PROG fswatch-1.11.2/m4/lib-link.m4000644 000765 000024 00000100443 13175374042 016150 0ustar00enricostaff000000 000000 # lib-link.m4 serial 26 (gettext-0.18.2) dnl Copyright (C) 2001-2014 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. AC_PREREQ([2.54]) dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and dnl the libraries corresponding to explicit and implicit dependencies. dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and dnl augments the CPPFLAGS variable. dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem. AC_DEFUN([AC_LIB_LINKFLAGS], [ AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) pushdef([Name],[m4_translit([$1],[./+-], [____])]) pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ AC_LIB_LINKFLAGS_BODY([$1], [$2]) ac_cv_lib[]Name[]_libs="$LIB[]NAME" ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" ac_cv_lib[]Name[]_cppflags="$INC[]NAME" ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX" ]) LIB[]NAME="$ac_cv_lib[]Name[]_libs" LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" INC[]NAME="$ac_cv_lib[]Name[]_cppflags" LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) AC_SUBST([LIB]NAME) AC_SUBST([LTLIB]NAME) AC_SUBST([LIB]NAME[_PREFIX]) dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the dnl results of this search when this library appears as a dependency. HAVE_LIB[]NAME=yes popdef([NAME]) popdef([Name]) ]) dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message]) dnl searches for libname and the libraries corresponding to explicit and dnl implicit dependencies, together with the specified include files and dnl the ability to compile and link the specified testcode. The missing-message dnl defaults to 'no' and may contain additional hints for the user. dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} dnl and LTLIB${NAME} variables and augments the CPPFLAGS variable, and dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem. AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], [ AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) pushdef([Name],[m4_translit([$1],[./+-], [____])]) pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME dnl accordingly. AC_LIB_LINKFLAGS_BODY([$1], [$2]) dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, dnl because if the user has installed lib[]Name and not disabled its use dnl via --without-lib[]Name-prefix, he wants to use it. ac_save_CPPFLAGS="$CPPFLAGS" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ ac_save_LIBS="$LIBS" dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS, dnl because these -l options might require -L options that are present in dnl LIBS. -l options benefit only from the -L options listed before it. dnl Otherwise, add it to the front of LIBS, because it may be a static dnl library that depends on another static library that is present in LIBS. dnl Static libraries benefit only from the static libraries listed after dnl it. case " $LIB[]NAME" in *" -l"*) LIBS="$LIBS $LIB[]NAME" ;; *) LIBS="$LIB[]NAME $LIBS" ;; esac AC_LINK_IFELSE( [AC_LANG_PROGRAM([[$3]], [[$4]])], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])']) LIBS="$ac_save_LIBS" ]) if test "$ac_cv_lib[]Name" = yes; then HAVE_LIB[]NAME=yes AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib][$1 library.]) AC_MSG_CHECKING([how to link with lib[]$1]) AC_MSG_RESULT([$LIB[]NAME]) else HAVE_LIB[]NAME=no dnl If $LIB[]NAME didn't lead to a usable library, we don't need dnl $INC[]NAME either. CPPFLAGS="$ac_save_CPPFLAGS" LIB[]NAME= LTLIB[]NAME= LIB[]NAME[]_PREFIX= fi AC_SUBST([HAVE_LIB]NAME) AC_SUBST([LIB]NAME) AC_SUBST([LTLIB]NAME) AC_SUBST([LIB]NAME[_PREFIX]) popdef([NAME]) popdef([Name]) ]) dnl Determine the platform dependent parameters needed to use rpath: dnl acl_libext, dnl acl_shlibext, dnl acl_libname_spec, dnl acl_library_names_spec, dnl acl_hardcode_libdir_flag_spec, dnl acl_hardcode_libdir_separator, dnl acl_hardcode_direct, dnl acl_hardcode_minus_L. AC_DEFUN([AC_LIB_RPATH], [ dnl Tell automake >= 1.10 to complain if config.rpath is missing. m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])]) AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [ CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh . ./conftest.sh rm -f ./conftest.sh acl_cv_rpath=done ]) wl="$acl_cv_wl" acl_libext="$acl_cv_libext" acl_shlibext="$acl_cv_shlibext" acl_libname_spec="$acl_cv_libname_spec" acl_library_names_spec="$acl_cv_library_names_spec" acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" acl_hardcode_direct="$acl_cv_hardcode_direct" acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" dnl Determine whether the user wants rpath handling at all. AC_ARG_ENABLE([rpath], [ --disable-rpath do not hardcode runtime library paths], :, enable_rpath=yes) ]) dnl AC_LIB_FROMPACKAGE(name, package) dnl declares that libname comes from the given package. The configure file dnl will then not have a --with-libname-prefix option but a dnl --with-package-prefix option. Several libraries can come from the same dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar dnl macro call that searches for libname. AC_DEFUN([AC_LIB_FROMPACKAGE], [ pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) define([acl_frompackage_]NAME, [$2]) popdef([NAME]) pushdef([PACK],[$2]) pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) define([acl_libsinpackage_]PACKUP, m4_ifdef([acl_libsinpackage_]PACKUP, [m4_defn([acl_libsinpackage_]PACKUP)[, ]],)[lib$1]) popdef([PACKUP]) popdef([PACK]) ]) dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and dnl the libraries corresponding to explicit and implicit dependencies. dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem. AC_DEFUN([AC_LIB_LINKFLAGS_BODY], [ AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])]) pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])]) dnl Autoconf >= 2.61 supports dots in --with options. pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[m4_translit(PACK,[.],[_])],PACK)]) dnl By default, look in $includedir and $libdir. use_additional=yes AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) AC_ARG_WITH(P_A_C_K[-prefix], [[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib --without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]], [ if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) else additional_includedir="$withval/include" additional_libdir="$withval/$acl_libdirstem" if test "$acl_libdirstem2" != "$acl_libdirstem" \ && ! test -d "$withval/$acl_libdirstem"; then additional_libdir="$withval/$acl_libdirstem2" fi fi fi ]) dnl Search the library and its dependencies in $additional_libdir and dnl $LDFLAGS. Using breadth-first-seach. LIB[]NAME= LTLIB[]NAME= INC[]NAME= LIB[]NAME[]_PREFIX= dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been dnl computed. So it has to be reset here. HAVE_LIB[]NAME= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='$1 $2' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" dnl See if it was already located by an earlier AC_LIB_LINKFLAGS dnl or AC_LIB_HAVE_LINKFLAGS call. uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" else dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined dnl that this library doesn't exist. So just drop it. : fi else dnl Search the library lib$name in $additional_libdir and $LDFLAGS dnl and the already constructed $LIBNAME/$LTLIBNAME. found_dir= found_la= found_so= found_a= eval libname=\"$acl_libname_spec\" # typically: libname=lib$name if test -n "$acl_shlibext"; then shrext=".$acl_shlibext" # typically: shrext=.so else shrext= fi if test $use_additional = yes; then dir="$additional_libdir" dnl The same code as in the loop below: dnl First look for a shared library. if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi dnl Then look for a static library. if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` dnl First look for a shared library. if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi dnl Then look for a static library. if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then dnl Found the library. LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then dnl Linking with a shared library. We attempt to hardcode its dnl directory into the executable's runpath, unless it's the dnl standard /usr/lib. if test "$enable_rpath" = no \ || test "X$found_dir" = "X/usr/$acl_libdirstem" \ || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then dnl No hardcoding is needed. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else dnl Use an explicit option to hardcode DIR into the resulting dnl binary. dnl Potentially add DIR to ltrpathdirs. dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi dnl The hardcoding into $LIBNAME is system dependent. if test "$acl_hardcode_direct" = yes; then dnl Using DIR/libNAME.so during linking hardcodes DIR into the dnl resulting binary. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then dnl Use an explicit option to hardcode DIR into the resulting dnl binary. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" dnl Potentially add DIR to rpathdirs. dnl The rpathdirs will be appended to $LIBNAME at the end. haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else dnl Rely on "-L$found_dir". dnl But don't add it if it's already contained in the LDFLAGS dnl or the already constructed $LIBNAME haveit= for x in $LDFLAGS $LIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" fi if test "$acl_hardcode_minus_L" != no; then dnl FIXME: Not sure whether we should use dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" dnl here. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH dnl here, because this doesn't fit in flags passed to the dnl compiler. So give up. No hardcoding. This affects only dnl very old systems. dnl FIXME: Not sure whether we should use dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" dnl here. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then dnl Linking with a static library. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" else dnl We shouldn't come here, but anyway it's good to have a dnl fallback. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" fi fi dnl Assume the include files are nearby. additional_includedir= case "$found_dir" in */$acl_libdirstem | */$acl_libdirstem/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` if test "$name" = '$1'; then LIB[]NAME[]_PREFIX="$basedir" fi additional_includedir="$basedir/include" ;; */$acl_libdirstem2 | */$acl_libdirstem2/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` if test "$name" = '$1'; then LIB[]NAME[]_PREFIX="$basedir" fi additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then dnl Potentially add $additional_includedir to $INCNAME. dnl But don't add it dnl 1. if it's the standard /usr/include, dnl 2. if it's /usr/local/include and we are using GCC on Linux, dnl 3. if it's already present in $CPPFLAGS or the already dnl constructed $INCNAME, dnl 4. if it doesn't exist as a directory. if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INC[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then dnl Really add $additional_includedir to $INCNAME. INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" fi fi fi fi fi dnl Look for dependencies. if test -n "$found_la"; then dnl Read the .la file. It defines the variables dnl dlname, library_names, old_library, dependency_libs, current, dnl age, revision, installed, dlopen, dlpreopen, libdir. save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" dnl We use only dependency_libs. for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. dnl But don't add it dnl 1. if it's the standard /usr/lib, dnl 2. if it's /usr/local/lib and we are using GCC on Linux, dnl 3. if it's already present in $LDFLAGS or the already dnl constructed $LIBNAME, dnl 4. if it doesn't exist as a directory. if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then haveit= if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LIBNAME. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LTLIBNAME. LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then dnl Potentially add DIR to rpathdirs. dnl The rpathdirs will be appended to $LIBNAME at the end. haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi dnl Potentially add DIR to ltrpathdirs. dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) dnl Handle this in the next round. names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) dnl Handle this in the next round. Throw away the .la's dnl directory; it is already contained in a preceding -L dnl option. names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) dnl Most likely an immediate library name. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" ;; esac done fi else dnl Didn't find the library; assume it is in the system directories dnl known to the linker and runtime loader. (All the system dnl directories known to the linker should also be known to the dnl runtime loader, otherwise the system is severely misconfigured.) LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$acl_hardcode_libdir_separator"; then dnl Weird platform: only the last -rpath option counts, the user must dnl pass all path elements in one option. We can arrange that for a dnl single library, but not when more than one $LIBNAMEs are used. alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" done dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl. acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" else dnl The -rpath options are cumulative. for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then dnl When using libtool, the option that works for both libraries and dnl executables is -R. The -R options are cumulative. for found_dir in $ltrpathdirs; do LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" done fi popdef([P_A_C_K]) popdef([PACKLIBS]) popdef([PACKUP]) popdef([PACK]) popdef([NAME]) ]) dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, dnl unless already present in VAR. dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes dnl contains two or three consecutive elements that belong together. AC_DEFUN([AC_LIB_APPENDTOVAR], [ for element in [$2]; do haveit= for x in $[$1]; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then [$1]="${[$1]}${[$1]:+ }$element" fi done ]) dnl For those cases where a variable contains several -L and -l options dnl referring to unknown libraries and directories, this macro determines the dnl necessary additional linker options for the runtime path. dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL]) dnl sets LDADDVAR to linker options needed together with LIBSVALUE. dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed, dnl otherwise linking without libtool is assumed. AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS], [ AC_REQUIRE([AC_LIB_RPATH]) AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) $1= if test "$enable_rpath" != no; then if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then dnl Use an explicit option to hardcode directories into the resulting dnl binary. rpathdirs= next= for opt in $2; do if test -n "$next"; then dir="$next" dnl No need to hardcode the standard /usr/lib. if test "X$dir" != "X/usr/$acl_libdirstem" \ && test "X$dir" != "X/usr/$acl_libdirstem2"; then rpathdirs="$rpathdirs $dir" fi next= else case $opt in -L) next=yes ;; -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'` dnl No need to hardcode the standard /usr/lib. if test "X$dir" != "X/usr/$acl_libdirstem" \ && test "X$dir" != "X/usr/$acl_libdirstem2"; then rpathdirs="$rpathdirs $dir" fi next= ;; *) next= ;; esac fi done if test "X$rpathdirs" != "X"; then if test -n ""$3""; then dnl libtool is used for linking. Use -R options. for dir in $rpathdirs; do $1="${$1}${$1:+ }-R$dir" done else dnl The linker is used for linking directly. if test -n "$acl_hardcode_libdir_separator"; then dnl Weird platform: only the last -rpath option counts, the user dnl must pass all path elements in one option. alldirs= for dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" $1="$flag" else dnl The -rpath options are cumulative. for dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$dir" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" $1="${$1}${$1:+ }$flag" done fi fi fi fi fi AC_SUBST([$1]) ]) fswatch-1.11.2/m4/ax_cxx_compile_stdcxx_11.m4000644 000765 000024 00000003215 13174733730 021350 0ustar00enricostaff000000 000000 # ============================================================================= # https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html # ============================================================================= # # SYNOPSIS # # AX_CXX_COMPILE_STDCXX_11([ext|noext], [mandatory|optional]) # # DESCRIPTION # # Check for baseline language coverage in the compiler for the C++11 # standard; if necessary, add switches to CXX and CXXCPP to enable # support. # # This macro is a convenience alias for calling the AX_CXX_COMPILE_STDCXX # macro with the version set to C++11. The two optional arguments are # forwarded literally as the second and third argument respectively. # Please see the documentation for the AX_CXX_COMPILE_STDCXX macro for # more information. If you want to use this macro, you also need to # download the ax_cxx_compile_stdcxx.m4 file. # # LICENSE # # Copyright (c) 2008 Benjamin Kosnik # Copyright (c) 2012 Zack Weinberg # Copyright (c) 2013 Roy Stogner # Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov # Copyright (c) 2015 Paul Norman # Copyright (c) 2015 Moritz Klammler # # 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 18 AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX]) AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [AX_CXX_COMPILE_STDCXX([11], [$1], [$2])]) fswatch-1.11.2/m4/ax_cxx_have_thread_local.m4000644 000765 000024 00000003226 13174733730 021450 0ustar00enricostaff000000 000000 # =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_cxx_have_thread_local.html # =========================================================================== # # SYNOPSIS # # AX_CXX_HAVE_THREAD_LOCAL() # # DESCRIPTION # # This macro checks if the thread_local storage specified, added in C++11, is # supported by the current compiler and libraries. # # If it is, define the ax_cv_cxx_have_thread_local environment variable to # "yes" and define HAVE_CXX_THREAD_LOCAL. # # CONTRIBUTING # # You can contribute changes on GitHub by forking this repository: # # https://github.com/emcrisostomo/CXX-Autoconf-Macros.git # # LICENSE # # Copyright (c) 2014 Enrico M. Crisostomo # # 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 1 AC_DEFUN([AX_CXX_HAVE_THREAD_LOCAL], [AC_CACHE_CHECK( [for thread_local storage specifier], ax_cv_cxx_have_thread_local, [dnl AC_LANG_PUSH([C++]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM( [ [using namespace std;] [static thread_local int x;] ], [] )], [ax_cv_cxx_have_thread_local=yes], [ax_cv_cxx_have_thread_local=no] ) AC_LANG_POP([C++])]) if test x"$ax_cv_cxx_have_thread_local" = "xyes" then AC_DEFINE(HAVE_CXX_THREAD_LOCAL, 1, [Define if the thread_local storage specified is available.]) fi ])fswatch-1.11.2/m4/ax_cflags_warn_all.m4000644 000765 000024 00000011703 13174733730 020257 0ustar00enricostaff000000 000000 # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html # =========================================================================== # # SYNOPSIS # # AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] # AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] # AX_FCFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] # # DESCRIPTION # # Try to find a compiler option that enables most reasonable warnings. # # For the GNU compiler it will be -Wall (and -ansi -pedantic) The result # is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default. # # Currently this macro knows about the GCC, Solaris, Digital Unix, AIX, # HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and # Intel compilers. For a given compiler, the Fortran flags are much more # experimental than their C equivalents. # # - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS # - $2 add-value-if-not-found : nothing # - $3 action-if-found : add value to shellvariable # - $4 action-if-not-found : nothing # # NOTE: These macros depend on AX_APPEND_FLAG. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2010 Rhys Ulerich # # 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_FLAGS_WARN_ALL],[dnl AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings], VAR,[VAR="no, unknown" ac_save_[]FLAGS="$[]FLAGS" for ac_arg dnl in "-warn all % -warn all" dnl Intel "-pedantic % -Wall" dnl GCC "-xstrconst % -v" dnl Solaris C "-std1 % -verbose -w0 -warnprotos" dnl Digital Unix "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX "-ansi -ansiE % -fullwarn" dnl IRIX "+ESlit % +w1" dnl HP-UX C "-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10) "-h conform % -h msglevel 2" dnl Cray C (Unicos) # do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) done FLAGS="$ac_save_[]FLAGS" ]) AS_VAR_POPDEF([FLAGS])dnl AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) case ".$VAR" in .ok|.ok,*) m4_ifvaln($3,$3) ;; .|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;; *) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;; esac AS_VAR_POPDEF([VAR])dnl ])dnl AX_FLAGS_WARN_ALL dnl implementation tactics: dnl the for-argument contains a list of options. The first part of dnl these does only exist to detect the compiler - usually it is dnl a global option to enable -ansi or -extrawarnings. All other dnl compilers will fail about it. That was needed since a lot of dnl compilers will give false positives for some option-syntax dnl like -Woption or -Xoption as they think of it is a pass-through dnl to later compile stages or something. The "%" is used as a dnl delimiter. A non-option comment can be given after "%%" marks dnl which will be shown but not added to the respective C/CXXFLAGS. AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl AC_LANG_PUSH([C]) AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) AC_LANG_POP([C]) ]) AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl AC_LANG_PUSH([C++]) AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) AC_LANG_POP([C++]) ]) AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl AC_LANG_PUSH([Fortran]) AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) AC_LANG_POP([Fortran]) ]) fswatch-1.11.2/m4/gettext.m4000644 000765 000024 00000035615 13175374041 016142 0ustar00enricostaff000000 000000 # gettext.m4 serial 66 (gettext-0.18.2) dnl Copyright (C) 1995-2014 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1995-2000. dnl Bruno Haible , 2000-2006, 2008-2010. dnl Macro to add for using GNU gettext. dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The dnl default (if it is not specified or empty) is 'no-libtool'. dnl INTLSYMBOL should be 'external' for packages with no intl directory, dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. dnl If INTLSYMBOL is 'use-libtool', then a libtool library dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, dnl depending on --{enable,disable}-{shared,static} and on the presence of dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library dnl $(top_builddir)/intl/libintl.a will be created. dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext dnl implementations (in libc or libintl) without the ngettext() function dnl will be ignored. If NEEDSYMBOL is specified and is dnl 'need-formatstring-macros', then GNU gettext implementations that don't dnl support the ISO C 99 formatstring macros will be ignored. dnl INTLDIR is used to find the intl libraries. If empty, dnl the value '$(top_builddir)/intl/' is used. dnl dnl The result of the configuration is one of three cases: dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled dnl and used. dnl Catalog format: GNU --> install in $(datadir) dnl Catalog extension: .mo after installation, .gmo in source tree dnl 2) GNU gettext has been found in the system's C library. dnl Catalog format: GNU --> install in $(datadir) dnl Catalog extension: .mo after installation, .gmo in source tree dnl 3) No internationalization, always use English msgid. dnl Catalog format: none dnl Catalog extension: none dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. dnl The use of .gmo is historical (it was needed to avoid overwriting the dnl GNU format catalogs when building on a platform with an X/Open gettext), dnl but we keep it in order not to force irrelevant filename changes on the dnl maintainers. dnl AC_DEFUN([AM_GNU_GETTEXT], [ dnl Argument checking. ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT ])])])])]) ifelse(ifelse([$1], [], [old])[]ifelse([$1], [no-libtool], [old]), [old], [AC_DIAGNOSE([obsolete], [Use of AM_GNU_GETTEXT without [external] argument is deprecated.])]) ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT ])])])]) define([gt_included_intl], ifelse([$1], [external], ifdef([AM_GNU_GETTEXT_][INTL_SUBDIR], [yes], [no]), [yes])) define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], [])) gt_NEEDS_INIT AM_GNU_GETTEXT_NEED([$2]) AC_REQUIRE([AM_PO_SUBDIRS])dnl ifelse(gt_included_intl, yes, [ AC_REQUIRE([AM_INTL_SUBDIR])dnl ]) dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) dnl Sometimes libintl requires libiconv, so first search for libiconv. dnl Ideally we would do this search only after the dnl if test "$USE_NLS" = "yes"; then dnl if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT dnl the configure script would need to contain the same shell code dnl again, outside any 'if'. There are two solutions: dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not dnl documented, we avoid it. ifelse(gt_included_intl, yes, , [ AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) ]) dnl Sometimes, on Mac OS X, libintl requires linking with CoreFoundation. gt_INTL_MACOSX dnl Set USE_NLS. AC_REQUIRE([AM_NLS]) ifelse(gt_included_intl, yes, [ BUILD_INCLUDED_LIBINTL=no USE_INCLUDED_LIBINTL=no ]) LIBINTL= LTLIBINTL= POSUB= dnl Add a version number to the cache macros. case " $gt_needs " in *" need-formatstring-macros "*) gt_api_version=3 ;; *" need-ngettext "*) gt_api_version=2 ;; *) gt_api_version=1 ;; esac gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc" gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl" dnl If we use NLS figure out what method if test "$USE_NLS" = "yes"; then gt_use_preinstalled_gnugettext=no ifelse(gt_included_intl, yes, [ AC_MSG_CHECKING([whether included gettext is requested]) AC_ARG_WITH([included-gettext], [ --with-included-gettext use the GNU gettext library included here], nls_cv_force_use_gnu_gettext=$withval, nls_cv_force_use_gnu_gettext=no) AC_MSG_RESULT([$nls_cv_force_use_gnu_gettext]) nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" if test "$nls_cv_force_use_gnu_gettext" != "yes"; then ]) dnl User does not insist on using GNU NLS library. Figure out what dnl to use. If GNU gettext is available we use this. Else we have dnl to fall back to GNU NLS library. if test $gt_api_version -ge 3; then gt_revision_test_code=' #ifndef __GNU_GETTEXT_SUPPORTED_REVISION #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) #endif changequote(,)dnl typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; changequote([,])dnl ' else gt_revision_test_code= fi if test $gt_api_version -ge 2; then gt_expression_test_code=' + * ngettext ("", "", 0)' else gt_expression_test_code= fi AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc], [AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #include $gt_revision_test_code extern int _nl_msg_cat_cntr; extern int *_nl_domain_bindings; ]], [[ bindtextdomain ("", ""); return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings ]])], [eval "$gt_func_gnugettext_libc=yes"], [eval "$gt_func_gnugettext_libc=no"])]) if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then dnl Sometimes libintl requires libiconv, so first search for libiconv. ifelse(gt_included_intl, yes, , [ AM_ICONV_LINK ]) dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) dnl because that would add "-liconv" to LIBINTL and LTLIBINTL dnl even if libiconv doesn't exist. AC_LIB_LINKFLAGS_BODY([intl]) AC_CACHE_CHECK([for GNU gettext in libintl], [$gt_func_gnugettext_libintl], [gt_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $INCINTL" gt_save_LIBS="$LIBS" LIBS="$LIBS $LIBINTL" dnl Now see whether libintl exists and does not depend on libiconv. AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #include $gt_revision_test_code extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (const char *); ]], [[ bindtextdomain ("", ""); return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("") ]])], [eval "$gt_func_gnugettext_libintl=yes"], [eval "$gt_func_gnugettext_libintl=no"]) dnl Now see whether libintl exists and depends on libiconv. if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then LIBS="$LIBS $LIBICONV" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #include $gt_revision_test_code extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (const char *); ]], [[ bindtextdomain ("", ""); return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("") ]])], [LIBINTL="$LIBINTL $LIBICONV" LTLIBINTL="$LTLIBINTL $LTLIBICONV" eval "$gt_func_gnugettext_libintl=yes" ]) fi CPPFLAGS="$gt_save_CPPFLAGS" LIBS="$gt_save_LIBS"]) fi dnl If an already present or preinstalled GNU gettext() is found, dnl use it. But if this macro is used in GNU gettext, and GNU dnl gettext is already preinstalled in libintl, we update this dnl libintl. (Cf. the install rule in intl/Makefile.in.) if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \ || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \ && test "$PACKAGE" != gettext-runtime \ && test "$PACKAGE" != gettext-tools; }; then gt_use_preinstalled_gnugettext=yes else dnl Reset the values set by searching for libintl. LIBINTL= LTLIBINTL= INCINTL= fi ifelse(gt_included_intl, yes, [ if test "$gt_use_preinstalled_gnugettext" != "yes"; then dnl GNU gettext is not found in the C library. dnl Fall back on included GNU gettext library. nls_cv_use_gnu_gettext=yes fi fi if test "$nls_cv_use_gnu_gettext" = "yes"; then dnl Mark actions used to generate GNU NLS library. BUILD_INCLUDED_LIBINTL=yes USE_INCLUDED_LIBINTL=yes LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV $LIBTHREAD" LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV $LTLIBTHREAD" LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` fi CATOBJEXT= if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then dnl Mark actions to use GNU gettext tools. CATOBJEXT=.gmo fi ]) if test -n "$INTL_MACOSX_LIBS"; then if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then dnl Some extra flags are needed during linking. LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" fi fi if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then AC_DEFINE([ENABLE_NLS], [1], [Define to 1 if translation of program messages to the user's native language is requested.]) else USE_NLS=no fi fi AC_MSG_CHECKING([whether to use NLS]) AC_MSG_RESULT([$USE_NLS]) if test "$USE_NLS" = "yes"; then AC_MSG_CHECKING([where the gettext function comes from]) if test "$gt_use_preinstalled_gnugettext" = "yes"; then if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then gt_source="external libintl" else gt_source="libc" fi else gt_source="included intl directory" fi AC_MSG_RESULT([$gt_source]) fi if test "$USE_NLS" = "yes"; then if test "$gt_use_preinstalled_gnugettext" = "yes"; then if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then AC_MSG_CHECKING([how to link with libintl]) AC_MSG_RESULT([$LIBINTL]) AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) fi dnl For backward compatibility. Some packages may be using this. AC_DEFINE([HAVE_GETTEXT], [1], [Define if the GNU gettext() function is already present or preinstalled.]) AC_DEFINE([HAVE_DCGETTEXT], [1], [Define if the GNU dcgettext() function is already present or preinstalled.]) fi dnl We need to process the po/ directory. POSUB=po fi ifelse(gt_included_intl, yes, [ dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL dnl to 'yes' because some of the testsuite requires it. if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then BUILD_INCLUDED_LIBINTL=yes fi dnl Make all variables we use known to autoconf. AC_SUBST([BUILD_INCLUDED_LIBINTL]) AC_SUBST([USE_INCLUDED_LIBINTL]) AC_SUBST([CATOBJEXT]) dnl For backward compatibility. Some configure.ins may be using this. nls_cv_header_intl= nls_cv_header_libgt= dnl For backward compatibility. Some Makefiles may be using this. DATADIRNAME=share AC_SUBST([DATADIRNAME]) dnl For backward compatibility. Some Makefiles may be using this. INSTOBJEXT=.mo AC_SUBST([INSTOBJEXT]) dnl For backward compatibility. Some Makefiles may be using this. GENCAT=gencat AC_SUBST([GENCAT]) dnl For backward compatibility. Some Makefiles may be using this. INTLOBJS= if test "$USE_INCLUDED_LIBINTL" = yes; then INTLOBJS="\$(GETTOBJS)" fi AC_SUBST([INTLOBJS]) dnl Enable libtool support if the surrounding package wishes it. INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix AC_SUBST([INTL_LIBTOOL_SUFFIX_PREFIX]) ]) dnl For backward compatibility. Some Makefiles may be using this. INTLLIBS="$LIBINTL" AC_SUBST([INTLLIBS]) dnl Make all documented variables known to autoconf. AC_SUBST([LIBINTL]) AC_SUBST([LTLIBINTL]) AC_SUBST([POSUB]) ]) dnl gt_NEEDS_INIT ensures that the gt_needs variable is initialized. m4_define([gt_NEEDS_INIT], [ m4_divert_text([DEFAULTS], [gt_needs=]) m4_define([gt_NEEDS_INIT], []) ]) dnl Usage: AM_GNU_GETTEXT_NEED([NEEDSYMBOL]) AC_DEFUN([AM_GNU_GETTEXT_NEED], [ m4_divert_text([INIT_PREPARE], [gt_needs="$gt_needs $1"]) ]) dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) fswatch-1.11.2/m4/fswatch_version.m4000644 000765 000024 00000001350 13175367735 017663 0ustar00enricostaff000000 000000 # # Copyright (c) 2014-2017 Enrico M. Crisostomo # # 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, 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 . # m4_define([FSWATCH_VERSION], [1.11.2]) m4_define([FSWATCH_REVISION], [1]) fswatch-1.11.2/m4/ax_require_defined.m4000644 000765 000024 00000002302 13174733730 020266 0ustar00enricostaff000000 000000 # =========================================================================== # 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 fswatch-1.11.2/m4/ax_cxx_compile_stdcxx.m4000644 000765 000024 00000047424 13174733730 021061 0ustar00enricostaff000000 000000 # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html # =========================================================================== # # SYNOPSIS # # AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) # # DESCRIPTION # # Check for baseline language coverage in the compiler for the specified # version of the C++ standard. If necessary, add switches to CXX and # CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) # or '14' (for the C++14 standard). # # The second argument, if specified, indicates whether you insist on an # extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. # -std=c++11). If neither is specified, you get whatever works, with # preference for an extended mode. # # The third argument, if specified 'mandatory' or if left unspecified, # indicates that baseline support for the specified C++ standard is # required and that the macro should error out if no mode with that # support is found. If specified 'optional', then configuration proceeds # regardless, after defining HAVE_CXX${VERSION} if and only if a # supporting mode is found. # # LICENSE # # Copyright (c) 2008 Benjamin Kosnik # Copyright (c) 2012 Zack Weinberg # Copyright (c) 2013 Roy Stogner # Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov # Copyright (c) 2015 Paul Norman # Copyright (c) 2015 Moritz Klammler # Copyright (c) 2016 Krzesimir Nowak # # 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 dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro dnl (serial version number 13). AX_REQUIRE_DEFINED([AC_MSG_WARN]) AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], [$1], [14], [ax_cxx_compile_alternatives="14 1y"], [$1], [17], [ax_cxx_compile_alternatives="17 1z"], [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl m4_if([$2], [], [], [$2], [ext], [], [$2], [noext], [], [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], [$3], [optional], [ax_cxx_compile_cxx$1_required=false], [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) AC_LANG_PUSH([C++])dnl ac_success=no AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, ax_cv_cxx_compile_cxx$1, [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], [ax_cv_cxx_compile_cxx$1=yes], [ax_cv_cxx_compile_cxx$1=no])]) if test x$ax_cv_cxx_compile_cxx$1 = xyes; then ac_success=yes fi m4_if([$2], [noext], [], [dnl if test x$ac_success = xno; then for alternative in ${ax_cxx_compile_alternatives}; do switch="-std=gnu++${alternative}" cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, [ac_save_CXX="$CXX" CXX="$CXX $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], [eval $cachevar=yes], [eval $cachevar=no]) CXX="$ac_save_CXX"]) if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done fi]) m4_if([$2], [ext], [], [dnl if test x$ac_success = xno; then dnl HP's aCC needs +std=c++11 according to: dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf dnl Cray's crayCC needs "-h std=c++11" for alternative in ${ax_cxx_compile_alternatives}; do for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, [ac_save_CXX="$CXX" CXX="$CXX $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], [eval $cachevar=yes], [eval $cachevar=no]) CXX="$ac_save_CXX"]) if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done if test x$ac_success = xyes; then break fi done fi]) AC_LANG_POP([C++]) if test x$ax_cxx_compile_cxx$1_required = xtrue; then if test x$ac_success = xno; then AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) fi fi if test x$ac_success = xno; then HAVE_CXX$1=0 AC_MSG_NOTICE([No compiler with C++$1 support was found]) else HAVE_CXX$1=1 AC_DEFINE(HAVE_CXX$1,1, [define if the compiler supports basic C++$1 syntax]) fi AC_SUBST(HAVE_CXX$1) m4_if([$1], [17], [AC_MSG_WARN([C++17 is not yet standardized, so the checks may change in incompatible ways anytime])]) ]) dnl Test body for checking C++11 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 ) dnl Test body for checking C++14 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 ) m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 ) dnl Tests for new features in C++11 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ // If the compiler admits that it is not ready for C++11, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201103L #error "This is not a C++11 compiler" #else namespace cxx11 { namespace test_static_assert { template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; } namespace test_final_override { struct Base { virtual void f() {} }; struct Derived : public Base { virtual void f() override {} }; } namespace test_double_right_angle_brackets { template < typename T > struct check {}; typedef check single_type; typedef check> double_type; typedef check>> triple_type; typedef check>>> quadruple_type; } namespace test_decltype { int f() { int a = 1; decltype(a) b = 2; return a + b; } } namespace test_type_deduction { template < typename T1, typename T2 > struct is_same { static const bool value = false; }; template < typename T > struct is_same { static const bool value = true; }; template < typename T1, typename T2 > auto add(T1 a1, T2 a2) -> decltype(a1 + a2) { return a1 + a2; } int test(const int c, volatile int v) { static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == false, ""); auto ac = c; auto av = v; auto sumi = ac + av + 'x'; auto sumf = ac + av + 1.0; static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == true, ""); return (sumf > 0.0) ? sumi : add(c, v); } } namespace test_noexcept { int f() { return 0; } int g() noexcept { return 0; } static_assert(noexcept(f()) == false, ""); static_assert(noexcept(g()) == true, ""); } namespace test_constexpr { template < typename CharT > unsigned long constexpr strlen_c_r(const CharT *const s, const unsigned long acc) noexcept { return *s ? strlen_c_r(s + 1, acc + 1) : acc; } template < typename CharT > unsigned long constexpr strlen_c(const CharT *const s) noexcept { return strlen_c_r(s, 0UL); } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("1") == 1UL, ""); static_assert(strlen_c("example") == 7UL, ""); static_assert(strlen_c("another\0example") == 7UL, ""); } namespace test_rvalue_references { template < int N > struct answer { static constexpr int value = N; }; answer<1> f(int&) { return answer<1>(); } answer<2> f(const int&) { return answer<2>(); } answer<3> f(int&&) { return answer<3>(); } void test() { int i = 0; const int c = 0; static_assert(decltype(f(i))::value == 1, ""); static_assert(decltype(f(c))::value == 2, ""); static_assert(decltype(f(0))::value == 3, ""); } } namespace test_uniform_initialization { struct test { static const int zero {}; static const int one {1}; }; static_assert(test::zero == 0, ""); static_assert(test::one == 1, ""); } namespace test_lambdas { void test1() { auto lambda1 = [](){}; auto lambda2 = lambda1; lambda1(); lambda2(); } int test2() { auto a = [](int i, int j){ return i + j; }(1, 2); auto b = []() -> int { return '0'; }(); auto c = [=](){ return a + b; }(); auto d = [&](){ return c; }(); auto e = [a, &b](int x) mutable { const auto identity = [](int y){ return y; }; for (auto i = 0; i < a; ++i) a += b--; return x + identity(a + b); }(0); return a + b + c + d + e; } int test3() { const auto nullary = [](){ return 0; }; const auto unary = [](int x){ return x; }; using nullary_t = decltype(nullary); using unary_t = decltype(unary); const auto higher1st = [](nullary_t f){ return f(); }; const auto higher2nd = [unary](nullary_t f1){ return [unary, f1](unary_t f2){ return f2(unary(f1())); }; }; return higher1st(nullary) + higher2nd(nullary)(unary); } } namespace test_variadic_templates { template struct sum; template struct sum { static constexpr auto value = N0 + sum::value; }; template <> struct sum<> { static constexpr auto value = 0; }; static_assert(sum<>::value == 0, ""); static_assert(sum<1>::value == 1, ""); static_assert(sum<23>::value == 23, ""); static_assert(sum<1, 2>::value == 3, ""); static_assert(sum<5, 5, 11>::value == 21, ""); static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); } // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function // because of this. namespace test_template_alias_sfinae { struct foo {}; template using member = typename T::member_type; template void func(...) {} template void func(member*) {} void test(); void test() { func(0); } } } // namespace cxx11 #endif // __cplusplus >= 201103L ]]) dnl Tests for new features in C++14 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ // If the compiler admits that it is not ready for C++14, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201402L #error "This is not a C++14 compiler" #else namespace cxx14 { namespace test_polymorphic_lambdas { int test() { const auto lambda = [](auto&&... args){ const auto istiny = [](auto x){ return (sizeof(x) == 1UL) ? 1 : 0; }; const int aretiny[] = { istiny(args)... }; return aretiny[0]; }; return lambda(1, 1L, 1.0f, '1'); } } namespace test_binary_literals { constexpr auto ivii = 0b0000000000101010; static_assert(ivii == 42, "wrong value"); } namespace test_generalized_constexpr { template < typename CharT > constexpr unsigned long strlen_c(const CharT *const s) noexcept { auto length = 0UL; for (auto p = s; *p; ++p) ++length; return length; } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("x") == 1UL, ""); static_assert(strlen_c("test") == 4UL, ""); static_assert(strlen_c("another\0test") == 7UL, ""); } namespace test_lambda_init_capture { int test() { auto x = 0; const auto lambda1 = [a = x](int b){ return a + b; }; const auto lambda2 = [a = lambda1(x)](){ return a; }; return lambda2(); } } namespace test_digit_separators { constexpr auto ten_million = 100'000'000; static_assert(ten_million == 100000000, ""); } namespace test_return_type_deduction { auto f(int& x) { return x; } decltype(auto) g(int& x) { return x; } template < typename T1, typename T2 > struct is_same { static constexpr auto value = false; }; template < typename T > struct is_same { static constexpr auto value = true; }; int test() { auto x = 0; static_assert(is_same::value, ""); static_assert(is_same::value, ""); return x; } } } // namespace cxx14 #endif // __cplusplus >= 201402L ]]) dnl Tests for new features in C++17 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ // If the compiler admits that it is not ready for C++17, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus <= 201402L #error "This is not a C++17 compiler" #else #if defined(__clang__) #define REALLY_CLANG #else #if defined(__GNUC__) #define REALLY_GCC #endif #endif #include #include #include namespace cxx17 { #if !defined(REALLY_CLANG) namespace test_constexpr_lambdas { // TODO: test it with clang++ from git constexpr int foo = [](){return 42;}(); } #endif // !defined(REALLY_CLANG) namespace test::nested_namespace::definitions { } namespace test_fold_expression { template int multiply(Args... args) { return (args * ... * 1); } template bool all(Args... args) { return (args && ...); } } namespace test_extended_static_assert { static_assert (true); } namespace test_auto_brace_init_list { auto foo = {5}; auto bar {5}; static_assert(std::is_same, decltype(foo)>::value); static_assert(std::is_same::value); } namespace test_typename_in_template_template_parameter { template typename X> struct D; } namespace test_fallthrough_nodiscard_maybe_unused_attributes { int f1() { return 42; } [[nodiscard]] int f2() { [[maybe_unused]] auto unused = f1(); switch (f1()) { case 17: f1(); [[fallthrough]]; case 42: f1(); } return f1(); } } namespace test_extended_aggregate_initialization { struct base1 { int b1, b2 = 42; }; struct base2 { base2() { b3 = 42; } int b3; }; struct derived : base1, base2 { int d; }; derived d1 {{1, 2}, {}, 4}; // full initialization derived d2 {{}, {}, 4}; // value-initialized bases } namespace test_general_range_based_for_loop { struct iter { int i; int& operator* () { return i; } const int& operator* () const { return i; } iter& operator++() { ++i; return *this; } }; struct sentinel { int i; }; bool operator== (const iter& i, const sentinel& s) { return i.i == s.i; } bool operator!= (const iter& i, const sentinel& s) { return !(i == s); } struct range { iter begin() const { return {0}; } sentinel end() const { return {5}; } }; void f() { range r {}; for (auto i : r) { [[maybe_unused]] auto v = i; } } } namespace test_lambda_capture_asterisk_this_by_value { struct t { int i; int foo() { return [*this]() { return i; }(); } }; } namespace test_enum_class_construction { enum class byte : unsigned char {}; byte foo {42}; } namespace test_constexpr_if { template int f () { if constexpr(cond) { return 13; } else { return 42; } } } namespace test_selection_statement_with_initializer { int f() { return 13; } int f2() { if (auto i = f(); i > 0) { return 3; } switch (auto i = f(); i + 4) { case 17: return 2; default: return 1; } } } #if !defined(REALLY_CLANG) namespace test_template_argument_deduction_for_class_templates { // TODO: test it with clang++ from git template struct pair { pair (T1 p1, T2 p2) : m1 {p1}, m2 {p2} {} T1 m1; T2 m2; }; void f() { [[maybe_unused]] auto p = pair{13, 42u}; } } #endif // !defined(REALLY_CLANG) namespace test_non_type_auto_template_parameters { template struct B {}; B<5> b1; B<'a'> b2; } #if !defined(REALLY_CLANG) namespace test_structured_bindings { // TODO: test it with clang++ from git int arr[2] = { 1, 2 }; std::pair pr = { 1, 2 }; auto f1() -> int(&)[2] { return arr; } auto f2() -> std::pair& { return pr; } struct S { int x1 : 2; volatile double y1; }; S f3() { return {}; } auto [ x1, y1 ] = f1(); auto& [ xr1, yr1 ] = f1(); auto [ x2, y2 ] = f2(); auto& [ xr2, yr2 ] = f2(); const auto [ x3, y3 ] = f3(); } #endif // !defined(REALLY_CLANG) #if !defined(REALLY_CLANG) namespace test_exception_spec_type_system { // TODO: test it with clang++ from git struct Good {}; struct Bad {}; void g1() noexcept; void g2(); template Bad f(T*, T*); template Good f(T1*, T2*); static_assert (std::is_same_v); } #endif // !defined(REALLY_CLANG) namespace test_inline_variables { template void f(T) {} template inline T g(T) { return T{}; } template<> inline void f<>(int) {} template<> int g<>(int) { return 5; } } } // namespace cxx17 #endif // __cplusplus <= 201402L ]]) fswatch-1.11.2/m4/libfswatch_version.m4000644 000765 000024 00000001433 13175367735 020354 0ustar00enricostaff000000 000000 # # Copyright (c) 2014-2017 Enrico M. Crisostomo # # 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, 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 . # m4_define([LIBFSWATCH_VERSION], [1.11.2]) m4_define([LIBFSWATCH_API_VERSION], [9:0:0]) m4_define([LIBFSWATCH_REVISION], [1]) fswatch-1.11.2/m4/progtest.m4000644 000765 000024 00000006040 13175374042 016314 0ustar00enricostaff000000 000000 # progtest.m4 serial 7 (gettext-0.18.2) dnl Copyright (C) 1996-2003, 2005, 2008-2014 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1996. AC_PREREQ([2.50]) # Search path for a program which passes the given test. dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) AC_DEFUN([AM_PATH_PROG_WITH_TEST], [ # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which # contains only /bin. Note that ksh looks also at the FPATH variable, # so we have to set that as well for the test. PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ || PATH_SEPARATOR=';' } fi # Find out how to test for executable files. Don't use a zero-byte file, # as systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then ac_executable_p="test -x" else ac_executable_p="test -f" fi rm -f conf$$.file # Extract the first word of "$2", so it can be a program name with args. set dummy $2; ac_word=[$]2 AC_MSG_CHECKING([for $ac_word]) AC_CACHE_VAL([ac_cv_path_$1], [case "[$]$1" in [[\\/]]* | ?:[[\\/]]*) ac_cv_path_$1="[$]$1" # Let the user override the test with a path. ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in ifelse([$5], , $PATH, [$5]); do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD if [$3]; then ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext" break 2 fi fi done done IFS="$ac_save_IFS" dnl If no 4th arg is given, leave the cache variable unset, dnl so AC_PATH_PROGS will keep looking. ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" ])dnl ;; esac])dnl $1="$ac_cv_path_$1" if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then AC_MSG_RESULT([$][$1]) else AC_MSG_RESULT([no]) fi AC_SUBST([$1])dnl ]) fswatch-1.11.2/m4/iconv.m4000644 000765 000024 00000022064 13175374041 015566 0ustar00enricostaff000000 000000 # iconv.m4 serial 19 (gettext-0.18.2) dnl Copyright (C) 2000-2002, 2007-2014 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], [ dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV dnl accordingly. AC_LIB_LINKFLAGS_BODY([iconv]) ]) AC_DEFUN([AM_ICONV_LINK], [ dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and dnl those with the standalone portable GNU libiconv installed). AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV dnl accordingly. AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) dnl Add $INCICONV to CPPFLAGS before performing the following checks, dnl because if the user has installed libiconv and not disabled its use dnl via --without-libiconv-prefix, he wants to use it. The first dnl AC_LINK_IFELSE will then fail, the second AC_LINK_IFELSE will succeed. am_save_CPPFLAGS="$CPPFLAGS" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [ am_cv_func_iconv="no, consider installing GNU libiconv" am_cv_lib_iconv=no AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #include #include ]], [[iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);]])], [am_cv_func_iconv=yes]) if test "$am_cv_func_iconv" != yes; then am_save_LIBS="$LIBS" LIBS="$LIBS $LIBICONV" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #include #include ]], [[iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);]])], [am_cv_lib_iconv=yes] [am_cv_func_iconv=yes]) LIBS="$am_save_LIBS" fi ]) if test "$am_cv_func_iconv" = yes; then AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [ dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11, dnl Solaris 10. am_save_LIBS="$LIBS" if test $am_cv_lib_iconv = yes; then LIBS="$LIBS $LIBICONV" fi am_cv_func_iconv_works=no for ac_iconv_const in '' 'const'; do AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[ #include #include #ifndef ICONV_CONST # define ICONV_CONST $ac_iconv_const #endif ]], [[int result = 0; /* Test against AIX 5.1 bug: Failures are not distinguishable from successful returns. */ { iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); if (cd_utf8_to_88591 != (iconv_t)(-1)) { static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */ char buf[10]; ICONV_CONST char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_utf8_to_88591, &inptr, &inbytesleft, &outptr, &outbytesleft); if (res == 0) result |= 1; iconv_close (cd_utf8_to_88591); } } /* Test against Solaris 10 bug: Failures are not distinguishable from successful returns. */ { iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); if (cd_ascii_to_88591 != (iconv_t)(-1)) { static ICONV_CONST char input[] = "\263"; char buf[10]; ICONV_CONST char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_ascii_to_88591, &inptr, &inbytesleft, &outptr, &outbytesleft); if (res == 0) result |= 2; iconv_close (cd_ascii_to_88591); } } /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ { iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); if (cd_88591_to_utf8 != (iconv_t)(-1)) { static ICONV_CONST char input[] = "\304"; static char buf[2] = { (char)0xDE, (char)0xAD }; ICONV_CONST char *inptr = input; size_t inbytesleft = 1; char *outptr = buf; size_t outbytesleft = 1; size_t res = iconv (cd_88591_to_utf8, &inptr, &inbytesleft, &outptr, &outbytesleft); if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) result |= 4; iconv_close (cd_88591_to_utf8); } } #if 0 /* This bug could be worked around by the caller. */ /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ { iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); if (cd_88591_to_utf8 != (iconv_t)(-1)) { static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; char buf[50]; ICONV_CONST char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_88591_to_utf8, &inptr, &inbytesleft, &outptr, &outbytesleft); if ((int)res > 0) result |= 8; iconv_close (cd_88591_to_utf8); } } #endif /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is provided. */ if (/* Try standardized names. */ iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1) /* Try IRIX, OSF/1 names. */ && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1) /* Try AIX names. */ && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) /* Try HP-UX names. */ && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) result |= 16; return result; ]])], [am_cv_func_iconv_works=yes], , [case "$host_os" in aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; *) am_cv_func_iconv_works="guessing yes" ;; esac]) test "$am_cv_func_iconv_works" = no || break done LIBS="$am_save_LIBS" ]) case "$am_cv_func_iconv_works" in *no) am_func_iconv=no am_cv_lib_iconv=no ;; *) am_func_iconv=yes ;; esac else am_func_iconv=no am_cv_lib_iconv=no fi if test "$am_func_iconv" = yes; then AC_DEFINE([HAVE_ICONV], [1], [Define if you have the iconv() function and it works.]) fi if test "$am_cv_lib_iconv" = yes; then AC_MSG_CHECKING([how to link with libiconv]) AC_MSG_RESULT([$LIBICONV]) else dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV dnl either. CPPFLAGS="$am_save_CPPFLAGS" LIBICONV= LTLIBICONV= fi AC_SUBST([LIBICONV]) AC_SUBST([LTLIBICONV]) ]) dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to dnl avoid warnings like dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required". dnl This is tricky because of the way 'aclocal' is implemented: dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN. dnl Otherwise aclocal's initial scan pass would miss the macro definition. dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions. dnl Otherwise aclocal would emit many "Use of uninitialized value $1" dnl warnings. m4_define([gl_iconv_AC_DEFUN], m4_version_prereq([2.64], [[AC_DEFUN_ONCE( [$1], [$2])]], [m4_ifdef([gl_00GNULIB], [[AC_DEFUN_ONCE( [$1], [$2])]], [[AC_DEFUN( [$1], [$2])]])])) gl_iconv_AC_DEFUN([AM_ICONV], [ AM_ICONV_LINK if test "$am_cv_func_iconv" = yes; then AC_MSG_CHECKING([for iconv declaration]) AC_CACHE_VAL([am_cv_proto_iconv], [ AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[ #include #include extern #ifdef __cplusplus "C" #endif #if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); #else size_t iconv(); #endif ]], [[]])], [am_cv_proto_iconv_arg1=""], [am_cv_proto_iconv_arg1="const"]) am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` AC_MSG_RESULT([ $am_cv_proto_iconv]) AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1], [Define as const if the declaration of iconv() needs const.]) dnl Also substitute ICONV_CONST in the gnulib generated . m4_ifdef([gl_ICONV_H_DEFAULTS], [AC_REQUIRE([gl_ICONV_H_DEFAULTS]) if test -n "$am_cv_proto_iconv_arg1"; then ICONV_CONST="const" fi ]) fi ]) fswatch-1.11.2/m4/nls.m4000644 000765 000024 00000002315 13175374042 015242 0ustar00enricostaff000000 000000 # nls.m4 serial 5 (gettext-0.18) dnl Copyright (C) 1995-2003, 2005-2006, 2008-2014 Free Software Foundation, dnl Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1995-2000. dnl Bruno Haible , 2000-2003. AC_PREREQ([2.50]) AC_DEFUN([AM_NLS], [ AC_MSG_CHECKING([whether NLS is requested]) dnl Default is enabled NLS AC_ARG_ENABLE([nls], [ --disable-nls do not use Native Language Support], USE_NLS=$enableval, USE_NLS=yes) AC_MSG_RESULT([$USE_NLS]) AC_SUBST([USE_NLS]) ]) fswatch-1.11.2/m4/lib-prefix.m4000644 000765 000024 00000020422 13175374042 016506 0ustar00enricostaff000000 000000 # lib-prefix.m4 serial 7 (gettext-0.18) dnl Copyright (C) 2001-2005, 2008-2014 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't dnl require excessive bracketing. ifdef([AC_HELP_STRING], [AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], [AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed dnl to access previously installed libraries. The basic assumption is that dnl a user will want packages to use other packages he previously installed dnl with the same --prefix option. dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate dnl libraries, but is otherwise very convenient. AC_DEFUN([AC_LIB_PREFIX], [ AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) dnl By default, look in $includedir and $libdir. use_additional=yes AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) AC_LIB_ARG_WITH([lib-prefix], [ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib --without-lib-prefix don't search for libraries in includedir and libdir], [ if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) else additional_includedir="$withval/include" additional_libdir="$withval/$acl_libdirstem" fi fi ]) if test $use_additional = yes; then dnl Potentially add $additional_includedir to $CPPFLAGS. dnl But don't add it dnl 1. if it's the standard /usr/include, dnl 2. if it's already present in $CPPFLAGS, dnl 3. if it's /usr/local/include and we are using GCC on Linux, dnl 4. if it doesn't exist as a directory. if test "X$additional_includedir" != "X/usr/include"; then haveit= for x in $CPPFLAGS; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then if test -d "$additional_includedir"; then dnl Really add $additional_includedir to $CPPFLAGS. CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" fi fi fi fi dnl Potentially add $additional_libdir to $LDFLAGS. dnl But don't add it dnl 1. if it's the standard /usr/lib, dnl 2. if it's already present in $LDFLAGS, dnl 3. if it's /usr/local/lib and we are using GCC on Linux, dnl 4. if it doesn't exist as a directory. if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then haveit= for x in $LDFLAGS; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LDFLAGS. LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" fi fi fi fi fi ]) dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, dnl acl_final_exec_prefix, containing the values to which $prefix and dnl $exec_prefix will expand at the end of the configure script. AC_DEFUN([AC_LIB_PREPARE_PREFIX], [ dnl Unfortunately, prefix and exec_prefix get only finally determined dnl at the end of configure. if test "X$prefix" = "XNONE"; then acl_final_prefix="$ac_default_prefix" else acl_final_prefix="$prefix" fi if test "X$exec_prefix" = "XNONE"; then acl_final_exec_prefix='${prefix}' else acl_final_exec_prefix="$exec_prefix" fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" prefix="$acl_save_prefix" ]) dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the dnl variables prefix and exec_prefix bound to the values they will have dnl at the end of the configure script. AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], [ acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" $1 exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" ]) dnl AC_LIB_PREPARE_MULTILIB creates dnl - a variable acl_libdirstem, containing the basename of the libdir, either dnl "lib" or "lib64" or "lib/64", dnl - a variable acl_libdirstem2, as a secondary possible value for dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or dnl "lib/amd64". AC_DEFUN([AC_LIB_PREPARE_MULTILIB], [ dnl There is no formal standard regarding lib and lib64. dnl On glibc systems, the current practice is that on a system supporting dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine dnl the compiler's default mode by looking at the compiler's library search dnl path. If at least one of its elements ends in /lib64 or points to a dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI. dnl Otherwise we use the default, namely "lib". dnl On Solaris systems, the current practice is that on a system supporting dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib. AC_REQUIRE([AC_CANONICAL_HOST]) acl_libdirstem=lib acl_libdirstem2= case "$host_os" in solaris*) dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment dnl . dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link." dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the dnl symlink is missing, so we set acl_libdirstem2 too. AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit], [AC_EGREP_CPP([sixtyfour bits], [ #ifdef _LP64 sixtyfour bits #endif ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no]) ]) if test $gl_cv_solaris_64bit = yes; then acl_libdirstem=lib/64 case "$host_cpu" in sparc*) acl_libdirstem2=lib/sparcv9 ;; i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; esac fi ;; *) searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` if test -n "$searchpath"; then acl_save_IFS="${IFS= }"; IFS=":" for searchdir in $searchpath; do if test -d "$searchdir"; then case "$searchdir" in */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; */../ | */.. ) # Better ignore directories of this form. They are misleading. ;; *) searchdir=`cd "$searchdir" && pwd` case "$searchdir" in */lib64 ) acl_libdirstem=lib64 ;; esac ;; esac fi done IFS="$acl_save_IFS" fi ;; esac test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" ]) fswatch-1.11.2/m4/ax_append_flag.m4000644 000765 000024 00000005333 13174733730 017403 0ustar00enricostaff000000 000000 # =========================================================================== # 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 fswatch-1.11.2/m4/lt~obsolete.m4000644 000765 000024 00000013774 13175374052 017034 0ustar00enricostaff000000 000000 # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software # Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) fswatch-1.11.2/m4/lib-ld.m4000644 000765 000024 00000007143 13175374042 015615 0ustar00enricostaff000000 000000 # lib-ld.m4 serial 6 dnl Copyright (C) 1996-2003, 2009-2014 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl Subroutines of libtool.m4, dnl with replacements s/_*LT_PATH/AC_LIB_PROG/ and s/lt_/acl_/ to avoid dnl collision with libtool.m4. dnl From libtool-2.4. Sets the variable with_gnu_ld to yes or no. AC_DEFUN([AC_LIB_PROG_LD_GNU], [AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld], [# I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 /dev/null 2>&1 \ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ || PATH_SEPARATOR=';' } fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`echo "$ac_prog"| sed 's%\\\\%/%g'` while echo "$ac_prog" | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL([acl_cv_path_LD], [if test -z "$LD"; then acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$acl_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then acl_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$acl_cv_path_LD" -v 2>&1 ]], [[CFPreferencesCopyAppValue(NULL, NULL)]])], [gt_cv_func_CFPreferencesCopyAppValue=yes], [gt_cv_func_CFPreferencesCopyAppValue=no]) LIBS="$gt_save_LIBS"]) if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], [1], [Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in the CoreFoundation framework.]) fi dnl Check for API introduced in Mac OS X 10.3. AC_CACHE_CHECK([for CFLocaleCopyCurrent], [gt_cv_func_CFLocaleCopyCurrent], [gt_save_LIBS="$LIBS" LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[#include ]], [[CFLocaleCopyCurrent();]])], [gt_cv_func_CFLocaleCopyCurrent=yes], [gt_cv_func_CFLocaleCopyCurrent=no]) LIBS="$gt_save_LIBS"]) if test $gt_cv_func_CFLocaleCopyCurrent = yes; then AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], [1], [Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the CoreFoundation framework.]) fi INTL_MACOSX_LIBS= if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" fi AC_SUBST([INTL_MACOSX_LIBS]) ]) fswatch-1.11.2/libfswatch/Makefile.am000644 000765 000024 00000001261 13175367735 020060 0ustar00enricostaff000000 000000 # # Copyright (c) 2014-2017 Enrico M. Crisostomo # # 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, 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 . # SUBDIRS = src doc fswatch-1.11.2/libfswatch/doc/000755 000765 000024 00000000000 13175374110 016552 5ustar00enricostaff000000 000000 fswatch-1.11.2/libfswatch/src/000755 000765 000024 00000000000 13175374107 016602 5ustar00enricostaff000000 000000 fswatch-1.11.2/libfswatch/src/Makefile.am000644 000765 000024 00000001263 13174733730 020640 0ustar00enricostaff000000 000000 # # Copyright (c) 2014-2015 Enrico M. Crisostomo # # 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, 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 . # SUBDIRS = libfswatch fswatch-1.11.2/libfswatch/src/libfswatch/000755 000765 000024 00000000000 13175374110 020722 5ustar00enricostaff000000 000000 fswatch-1.11.2/libfswatch/src/libfswatch/c++/000755 000765 000024 00000000000 13175374110 021272 5ustar00enricostaff000000 000000 fswatch-1.11.2/libfswatch/src/libfswatch/Makefile.am000644 000765 000024 00000007471 13174733730 022775 0ustar00enricostaff000000 000000 # # Copyright (c) 2014-2015 Enrico M. Crisostomo # # 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, 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 . # LIBFSWATCH_API_VERSION = @AM_LIBFSWATCH_API_VERSION@ # Prepare gettext-related symbols used by programs AM_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" lib_LTLIBRARIES = libfswatch.la libfswatch_la_SOURCES = c/cevent.cpp libfswatch_la_SOURCES += c/libfswatch.cpp libfswatch_la_SOURCES += c/libfswatch_log.cpp libfswatch_la_SOURCES += c++/libfswatch_exception.cpp libfswatch_la_SOURCES += c++/event.cpp libfswatch_la_SOURCES += c++/filter.cpp libfswatch_la_SOURCES += c++/monitor.cpp libfswatch_la_SOURCES += c++/poll_monitor.cpp libfswatch_la_SOURCES += c++/path_utils.cpp libfswatch_la_SOURCES += c++/string/string_utils.cpp libfswatch_la_SOURCES += gettext.h libfswatch_la_SOURCES += gettext_defs.h # Platform-dependent source files if USE_FSEVENTS libfswatch_la_SOURCES += c++/fsevents_monitor.cpp endif if USE_KQUEUE libfswatch_la_SOURCES += c++/kqueue_monitor.cpp endif if USE_FEN libfswatch_la_SOURCES += c++/fen_monitor.cpp endif if USE_INOTIFY libfswatch_la_SOURCES += c++/inotify_monitor.cpp endif if USE_WINDOWS if USE_CYGWIN libfswatch_la_SOURCES += c++/windows_monitor.cpp libfswatch_la_SOURCES += c++/windows/win_handle.cpp libfswatch_la_SOURCES += c++/windows/win_handle.hpp libfswatch_la_SOURCES += c++/windows/win_error_message.cpp libfswatch_la_SOURCES += c++/windows/win_error_message.hpp libfswatch_la_SOURCES += c++/windows/win_strings.cpp libfswatch_la_SOURCES += c++/windows/win_strings.hpp libfswatch_la_SOURCES += c++/windows/win_paths.cpp libfswatch_la_SOURCES += c++/windows/win_paths.hpp libfswatch_la_SOURCES += c++/windows/win_directory_change_event.cpp libfswatch_la_SOURCES += c++/windows/win_directory_change_event.hpp endif endif libfswatch_la_LDFLAGS = -version-info $(LIBFSWATCH_API_VERSION) libfswatch_la_LDFLAGS += @LTLIBINTL@ if OS_CYGWIN libfswatch_la_LDFLAGS += -no-undefined endif if USE_FSEVENTS libfswatch_la_LDFLAGS += -framework CoreServices endif # Define separate include directories for C and C++ headers. libfswatch_cdir = $(includedir)/libfswatch/c libfswatch_cppdir = $(includedir)/libfswatch/c++ # Distribute C headers. libfswatch_c_HEADERS = c/libfswatch.h libfswatch_c_HEADERS += c/libfswatch_types.h libfswatch_c_HEADERS += c/cevent.h libfswatch_c_HEADERS += c/cfilter.h libfswatch_c_HEADERS += c/cmonitor.h libfswatch_c_HEADERS += c/error.h libfswatch_c_HEADERS += c/libfswatch_log.h # Distribute C++ headers conditionally adding available backends. libfswatch_cpp_HEADERS = c++/monitor.hpp libfswatch_cpp_HEADERS += c++/libfswatch_map.hpp libfswatch_cpp_HEADERS += c++/libfswatch_set.hpp libfswatch_cpp_HEADERS += c++/path_utils.hpp libfswatch_cpp_HEADERS += c++/string/string_utils.hpp if USE_FSEVENTS libfswatch_cpp_HEADERS += c++/fsevents_monitor.hpp endif if USE_KQUEUE libfswatch_cpp_HEADERS += c++/kqueue_monitor.hpp endif if USE_FEN libfswatch_cpp_HEADERS += c++/fen_monitor.hpp endif if USE_INOTIFY libfswatch_cpp_HEADERS += c++/inotify_monitor.hpp endif if USE_WINDOWS libfswatch_cpp_HEADERS += c++/windows_monitor.hpp endif libfswatch_cpp_HEADERS += c++/poll_monitor.hpp libfswatch_cpp_HEADERS += c++/filter.hpp libfswatch_cpp_HEADERS += c++/event.hpp libfswatch_cpp_HEADERS += c++/libfswatch_exception.hpp fswatch-1.11.2/libfswatch/src/libfswatch/gettext.h000644 000765 000024 00000023664 13174733730 022600 0ustar00enricostaff000000 000000 /* Convenience header for conditional use of GNU . Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2016 Free Software Foundation, Inc. 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 . */ #ifndef _LIBGETTEXT_H #define _LIBGETTEXT_H 1 /* NLS can be disabled through the configure --disable-nls option. */ #if ENABLE_NLS /* Get declarations of GNU message catalog functions. */ # include /* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by the gettext() and ngettext() macros. This is an alternative to calling textdomain(), and is useful for libraries. */ # ifdef DEFAULT_TEXT_DOMAIN # undef gettext # define gettext(Msgid) \ dgettext (DEFAULT_TEXT_DOMAIN, Msgid) # undef ngettext # define ngettext(Msgid1, Msgid2, N) \ dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) # endif #else /* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which chokes if dcgettext is defined as a macro. So include it now, to make later inclusions of a NOP. We don't include as well because people using "gettext.h" will not include , and also including would fail on SunOS 4, whereas is OK. */ #if defined(__sun) # include #endif /* Many header files from the libstdc++ coming with g++ 3.3 or newer include , which chokes if dcgettext is defined as a macro. So include it now, to make later inclusions of a NOP. */ #if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) # include # if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H # include # endif #endif /* Disabled NLS. The casts to 'const char *' serve the purpose of producing warnings for invalid uses of the value returned from these functions. On pre-ANSI systems without 'const', the config.h file is supposed to contain "#define const". */ # undef gettext # define gettext(Msgid) ((const char *) (Msgid)) # undef dgettext # define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) # undef dcgettext # define dcgettext(Domainname, Msgid, Category) \ ((void) (Category), dgettext (Domainname, Msgid)) # undef ngettext # define ngettext(Msgid1, Msgid2, N) \ ((N) == 1 \ ? ((void) (Msgid2), (const char *) (Msgid1)) \ : ((void) (Msgid1), (const char *) (Msgid2))) # undef dngettext # define dngettext(Domainname, Msgid1, Msgid2, N) \ ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) # undef dcngettext # define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ ((void) (Category), dngettext (Domainname, Msgid1, Msgid2, N)) # undef textdomain # define textdomain(Domainname) ((const char *) (Domainname)) # undef bindtextdomain # define bindtextdomain(Domainname, Dirname) \ ((void) (Domainname), (const char *) (Dirname)) # undef bind_textdomain_codeset # define bind_textdomain_codeset(Domainname, Codeset) \ ((void) (Domainname), (const char *) (Codeset)) #endif /* Prefer gnulib's setlocale override over libintl's setlocale override. */ #ifdef GNULIB_defined_setlocale # undef setlocale # define setlocale rpl_setlocale #endif /* A pseudo function call that serves as a marker for the automated extraction of messages, but does not call gettext(). The run-time translation is done at a different place in the code. The argument, String, should be a literal string. Concatenated strings and other string expressions won't work. The macro's expansion is not parenthesized, so that it is suitable as initializer for static 'char[]' or 'const char[]' variables. */ #define gettext_noop(String) String /* The separator between msgctxt and msgid in a .mo file. */ #define GETTEXT_CONTEXT_GLUE "\004" /* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be short and rarely need to change. The letter 'p' stands for 'particular' or 'special'. */ #ifdef DEFAULT_TEXT_DOMAIN # define pgettext(Msgctxt, Msgid) \ pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) #else # define pgettext(Msgctxt, Msgid) \ pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) #endif #define dpgettext(Domainname, Msgctxt, Msgid) \ pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) #define dcpgettext(Domainname, Msgctxt, Msgid, Category) \ pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category) #ifdef DEFAULT_TEXT_DOMAIN # define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) #else # define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) #endif #define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) #define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \ npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category) #ifdef __GNUC__ __inline #else #ifdef __cplusplus inline #endif #endif static const char * pgettext_aux (const char *domain, const char *msg_ctxt_id, const char *msgid, int category) { const char *translation = dcgettext (domain, msg_ctxt_id, category); if (translation == msg_ctxt_id) return msgid; else return translation; } #ifdef __GNUC__ __inline #else #ifdef __cplusplus inline #endif #endif static const char * npgettext_aux (const char *domain, const char *msg_ctxt_id, const char *msgid, const char *msgid_plural, unsigned long int n, int category) { const char *translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); if (translation == msg_ctxt_id || translation == msgid_plural) return (n == 1 ? msgid : msgid_plural); else return translation; } /* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID can be arbitrary expressions. But for string literals these macros are less efficient than those above. */ #include #if (((__GNUC__ >= 3 || __GNUG__ >= 2) && !defined __STRICT_ANSI__) \ /* || __STDC_VERSION__ >= 199901L */ ) # define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 1 #else # define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0 #endif #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS #include #endif #define pgettext_expr(Msgctxt, Msgid) \ dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES) #define dpgettext_expr(Domainname, Msgctxt, Msgid) \ dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES) #ifdef __GNUC__ __inline #else #ifdef __cplusplus inline #endif #endif static const char * dcpgettext_expr (const char *domain, const char *msgctxt, const char *msgid, int category) { size_t msgctxt_len = strlen (msgctxt) + 1; size_t msgid_len = strlen (msgid) + 1; const char *translation; #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS char msg_ctxt_id[msgctxt_len + msgid_len]; #else char buf[1024]; char *msg_ctxt_id = (msgctxt_len + msgid_len <= sizeof (buf) ? buf : (char *) malloc (msgctxt_len + msgid_len)); if (msg_ctxt_id != NULL) #endif { int found_translation; memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); msg_ctxt_id[msgctxt_len - 1] = '\004'; memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); translation = dcgettext (domain, msg_ctxt_id, category); found_translation = (translation != msg_ctxt_id); #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS if (msg_ctxt_id != buf) free (msg_ctxt_id); #endif if (found_translation) return translation; } return msgid; } #define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \ dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) #define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) #ifdef __GNUC__ __inline #else #ifdef __cplusplus inline #endif #endif static const char * dcnpgettext_expr (const char *domain, const char *msgctxt, const char *msgid, const char *msgid_plural, unsigned long int n, int category) { size_t msgctxt_len = strlen (msgctxt) + 1; size_t msgid_len = strlen (msgid) + 1; const char *translation; #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS char msg_ctxt_id[msgctxt_len + msgid_len]; #else char buf[1024]; char *msg_ctxt_id = (msgctxt_len + msgid_len <= sizeof (buf) ? buf : (char *) malloc (msgctxt_len + msgid_len)); if (msg_ctxt_id != NULL) #endif { int found_translation; memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); msg_ctxt_id[msgctxt_len - 1] = '\004'; memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); found_translation = !(translation == msg_ctxt_id || translation == msgid_plural); #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS if (msg_ctxt_id != buf) free (msg_ctxt_id); #endif if (found_translation) return translation; } return (n == 1 ? msgid : msgid_plural); } #endif /* _LIBGETTEXT_H */ fswatch-1.11.2/libfswatch/src/libfswatch/gettext_defs.h000644 000765 000024 00000001621 13174733730 023566 0ustar00enricostaff000000 000000 /* * Copyright (C) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ #ifndef FSW_GETTEXT_DEFS_H # define FSW_GETTEXT_DEFS_H #include "gettext.h" # ifdef __cplusplus extern "C" { # endif #define _(String) gettext(String) # ifdef __cplusplus } # endif #endif /* FSW_GETTEXT_DEFS_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c/000755 000765 000024 00000000000 13175374107 021152 5ustar00enricostaff000000 000000 fswatch-1.11.2/libfswatch/src/libfswatch/c/error.h000644 000765 000024 00000005174 13174733730 022463 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Error values. * * This header file defines the error values used by the `libfswatch` API. * * @copyright Copyright (c) 2014-2015 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef FSW__ERROR_H # define FSW__ERROR_H # ifdef __cplusplus extern "C" { # endif // Error codes # define FSW_OK 0 /**< The call was successful. */ # define FSW_ERR_UNKNOWN_ERROR (1 << 0) /**< An unknown error has occurred. */ # define FSW_ERR_SESSION_UNKNOWN (1 << 1) /**< The session specified by the handle is unknown. */ # define FSW_ERR_MONITOR_ALREADY_EXISTS (1 << 2) /**< The session already contains a monitor. */ # define FSW_ERR_MEMORY (1 << 3) /**< An error occurred while invoking a memory management routine. */ # define FSW_ERR_UNKNOWN_MONITOR_TYPE (1 << 4) /**< The specified monitor type does not exist. */ # define FSW_ERR_CALLBACK_NOT_SET (1 << 5) /**< The callback has not been set. */ # define FSW_ERR_PATHS_NOT_SET (1 << 6) /**< The paths to watch have not been set. */ # define FSW_ERR_MISSING_CONTEXT (1 << 7) /**< The callback context has not been set. */ # define FSW_ERR_INVALID_PATH (1 << 8) /**< The path is invalid. */ # define FSW_ERR_INVALID_CALLBACK (1 << 9) /**< The callback is invalid. */ # define FSW_ERR_INVALID_LATENCY (1 << 10) /**< The latency is invalid. */ # define FSW_ERR_INVALID_REGEX (1 << 11) /**< The regular expression is invalid. */ # define FSW_ERR_MONITOR_ALREADY_RUNNING (1 << 12) /**< A monitor is already running in the specified session. */ # define FSW_ERR_UNKNOWN_VALUE (1 << 13) /**< The value is unknown. */ # define FSW_ERR_INVALID_PROPERTY (1 << 14) /**< The property is invalid. */ # ifdef __cplusplus } # endif #endif /* FSW__ERROR_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c/libfswatch_types.h000644 000765 000024 00000003015 13174733730 024674 0ustar00enricostaff000000 000000 /* * Copyright (c) 2015 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Header of the `libfswatch` library containing common types. * * This header file defines the types used by the `libfswatch` library. * * @copyright Copyright (c) 2014-2015 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef LIBFSWATCH_TYPES_H #define LIBFSWATCH_TYPES_H #ifdef __cplusplus extern "C" { #endif /** * @brief Opaque type representing a monitoring session. */ struct FSW_SESSION; /** * @brief Handle to a monitoring session. */ typedef struct FSW_SESSION *FSW_HANDLE; /** * @brief Status of a library call. */ typedef int FSW_STATUS; #define FSW_INVALID_HANDLE -1 #if defined(HAVE_CXX_THREAD_LOCAL) # define FSW_THREAD_LOCAL thread_local #else # define FSW_THREAD_LOCAL #endif #ifdef __cplusplus } #endif #endif /* LIBFSWATCH_TYPES_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c/libfswatch_log.cpp000644 000765 000024 00000003157 13174733730 024653 0ustar00enricostaff000000 000000 /* * Copyright (c) 2015 Enrico M. Crisostomo * * 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, 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 . */ #include "libfswatch.h" #include "libfswatch_log.h" #include "../c++/string/string_utils.hpp" #include using namespace std; using namespace fsw; void fsw_log(const char *msg) { if (fsw_is_verbose()) printf("%s", msg); } void fsw_flog(FILE *f, const char *msg) { if (fsw_is_verbose()) fprintf(f, "%s", msg); } void fsw_logf(const char *format, ...) { if (!fsw_is_verbose()) return; va_list args; va_start(args, format); vfprintf(stdout, format, args); va_end(args); } void fsw_flogf(FILE *f, const char *format, ...) { if (!fsw_is_verbose()) return; va_list args; va_start(args, format); vfprintf(f, format, args); va_end(args); } void fsw_log_perror(const char *msg) { if (fsw_is_verbose()) perror(msg); } void fsw_logf_perror(const char *format, ...) { if (!fsw_is_verbose()) return; va_list args; va_start(args, format); perror(string_utils::vstring_from_format(format, args).c_str()); va_end(args); } fswatch-1.11.2/libfswatch/src/libfswatch/c/cfilter.h000644 000765 000024 00000002774 13174733730 022765 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2016 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Header of the `libfswatch` library functions for filter management. * * @copyright Copyright (c) 2014-2016 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef FSW__CFILTER_H # define FSW__CFILTER_H # include "cevent.h" # ifdef __cplusplus extern "C" { # endif /** * @brief Event filter type. */ enum fsw_filter_type { filter_include, filter_exclude }; typedef struct fsw_cmonitor_filter { char * text; enum fsw_filter_type type; bool case_sensitive; bool extended; } fsw_cmonitor_filter; /** * @brief Event type filter. */ typedef struct fsw_event_type_filter { enum fsw_event_flag flag; } fsw_event_type_filter; # ifdef __cplusplus } # endif #endif /* FSW__CFILTER_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c/libfswatch.h000644 000765 000024 00000015707 13174733730 023463 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Header of the `libfswatch` library. * * This header file defines the API of the `libfswatch` library. * * @copyright Copyright (c) 2014-2015 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef LIBFSW_H #define LIBFSW_H #include #include "libfswatch_types.h" #include "cevent.h" #include "cmonitor.h" #include "cfilter.h" #include "error.h" # ifdef __cplusplus extern "C" { # endif /** * The `libfswatch` C API let users create monitor sessions and receive file * system events matching the specified criteria. Most API functions return * a status code of type FSW_STATUS which can take any value specified in * the error.h header. A successful API call returns FSW_OK and the last * error can be obtained calling the fsw_last_error() function. * * If the compiler and the C++ library used to build `libfswatch` support the * thread_local storage specified then this API is thread safe and a * different state is maintained on a per-thread basis. * * Session-modifying API calls (such as fsw_add_path) will take effect the * next time a monitor is started with fsw_start_monitor. * * Currently not all monitors supports being stopped, in which case * fsw_start_monitor is a non-returning API call. * * A basic session needs at least: * * * A path to watch. * * A callback to process the events sent by the monitor. * * as shown in the next example (error checking code was omitted). * * // Use the default monitor. * const FSW_HANDLE handle = fsw_init_session(system_default_monitor_type); * * fsw_add_path(handle, "my/path"); * fsw_set_callback(handle, my_callback); * * fsw_start_monitor(handle); * * A suitable callback function is a function pointer of type * FSW_CEVENT_CALLBACK, that is it is a function conforming with the * following signature: * * void c_process_events(fsw_cevent const * const events, * const unsigned int event_num, * void * data); * * When a monitor receives change events satisfying all the session criteria, * the callback is invoked and passed a copy of the events. */ /** * This function initializes the `libfswatch` library and must be invoked * before any other calls to the C or C++ API. If the function succeeds, it * returns FSW_OK, otherwise the initialization routine failed and the library * should not be usable. */ FSW_STATUS fsw_init_library(); /** * This function creates a new monitor session using the specified monitor * and returns an handle to it. This function is the `libfswatch` API entry * point. * * @see cmonitor.h for a list of all the available monitors. */ FSW_HANDLE fsw_init_session(const enum fsw_monitor_type type); /** * Adds a path to watch to the specified session. At least one path must be * added to the current session in order for it to be valid. */ FSW_STATUS fsw_add_path(const FSW_HANDLE handle, const char * path); /** * Adds the specified monitor property. */ FSW_STATUS fsw_add_property(const FSW_HANDLE handle, const char * name, const char * value); /** * Sets the allow overflow flag of the monitor. When this flag is set, a * monitor is allowed to overflow and report it as a change event. */ FSW_STATUS fsw_set_allow_overflow(const FSW_HANDLE handle, const bool allow_overflow); /** * Sets the callback the monitor invokes when some events are received. The * callback must be set in the current session in order for it to be valid. * * See cevent.h for the definition of FSW_CEVENT_CALLBACK. */ FSW_STATUS fsw_set_callback(const FSW_HANDLE handle, const FSW_CEVENT_CALLBACK callback, void * data); /** * Sets the latency of the monitor. By default, the latency is set to 1 s. */ FSW_STATUS fsw_set_latency(const FSW_HANDLE handle, const double latency); /** * Determines whether the monitor recursively scans each watched path or not. * Recursive scanning is an optional feature which could not be implemented * by all the monitors. By default, recursive scanning is disabled. */ FSW_STATUS fsw_set_recursive(const FSW_HANDLE handle, const bool recursive); /** * Determines whether the monitor only watches a directory when performing a * recursive scan. By default, a monitor accepts all kinds of files. */ FSW_STATUS fsw_set_directory_only(const FSW_HANDLE handle, const bool directory_only); /** * Determines whether a symbolic link is followed or not. By default, a * symbolic link are not followed. */ FSW_STATUS fsw_set_follow_symlinks(const FSW_HANDLE handle, const bool follow_symlinks); /** * Adds an event type filter to the current session. * * See cfilter.h for the definition of fsw_event_type_filter. */ FSW_STATUS fsw_add_event_type_filter(const FSW_HANDLE handle, const fsw_event_type_filter event_type); /** * Adds a filter to the current session. A filter is a regular expression * that, depending on whether the filter type is exclusion or not, must or * must not be matched for an event path for the event to be accepted. * * See cfilter.h for the definition of fsw_cmonitor_filter. */ FSW_STATUS fsw_add_filter(const FSW_HANDLE handle, const fsw_cmonitor_filter filter); /** * Starts the monitor if it is properly configured. Depending on the type of * monitor this call might return when a monitor is stopped or not. */ FSW_STATUS fsw_start_monitor(const FSW_HANDLE handle); /** * Stops a running monitor. */ FSW_STATUS fsw_stop_monitor(const FSW_HANDLE handle); /** * Destroys an existing session and invalidates its handle. */ FSW_STATUS fsw_destroy_session(const FSW_HANDLE handle); /** * Gets the last error code. */ FSW_STATUS fsw_last_error(); /** * Check whether the verbose mode is active. */ bool fsw_is_verbose(); /** * Set the verbose mode. */ void fsw_set_verbose(bool verbose); # ifdef __cplusplus } # endif #endif /* LIBFSW_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c/libfswatch.cpp000644 000765 000024 00000062470 13175131667 024017 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2016 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Main `libfswatch` source file. * @copyright Copyright (c) 2014-2016 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.10.0 */ /** * @mainpage * * @section introduction Introduction * * `fswatch` is a cross-platform file change monitor currently supporting the * following backends: * * - A monitor based on the _FSEvents_ API of Apple OS X. * - A monitor based on _kqueue_, an event notification interface introduced * in FreeBSD 4.1 and supported on most *BSD systems (including OS X). * - A monitor based on _File Events Notification_, an event notification API * of the Solaris/Illumos kernel. * - A monitor based on _inotify_, a Linux kernel subsystem that reports * file system changes to applications. * - A monitor based on the Microsoft Windows' `ReadDirectoryChangesW` * function and reads change events asynchronously. * - A monitor which periodically stats the file system, saves file * modification times in memory and manually calculates file system * changes, which can work on any operating system where stat can be * used. * * Instead of using different APIs, a programmer can use just one: the API of * `libfswatch`. The advantages of using `libfswatch` are many: * * - *Portability*: `libfswatch` supports many backends, effectively giving * support to a great number of operating systems, including Solaris, *BSD * Unix and Linux. * - Ease of use: using `libfswatch` should be easier than using any of the * APIs it supports. * * @section changelog Changelog * * See the @ref history "History" page. * * @section bindings Available Bindings * * `libfswatch` is a C++ library with C bindings which makes it available to a * wide range of programming languages. If a programming language has C * bindings, then `libfswatch` can be used from it. The C binding provides all * the functionality provided by the C++ implementation and it can be used as a * fallback solution when the C++ API cannot be used. * * @section libtools-versioning libtool's versioning scheme * * `libtool`'s versioning scheme is described by three integers: * `current:revision:age` where: * * - `current` is the most recent interface number implemented by the * library. * - `revision` is the implementation number of the current interface. * - `age` is the difference between the newest and the oldest interface that * the library implements. * * @section c-cpp-api The C and the C++ API * * The C API is built on top of the C++ API but the two are very different, to * reflect the fundamental differences between the two languages. * * The \ref cpp-api "C++ API" centres on the concept of _monitor_, a class of * objects modelling the functionality of the file monitoring API. Different * monitor types are modelled as different classes inheriting from the * `fsw::monitor` abstract class, that is the type that defines the core * monitoring API. API clients can pick the current platform's default monitor, * or choose a specific implementation amongst the available ones, configure it * and _run_ it. When running, a monitor gathers file system change events and * communicates them back to the caller using a _callback_. * * The \ref c-api "C API", on the other hand, centres on the concept of * _monitoring session_. A session internally wraps a monitor instance and * represents an opaque C bridge to the C++ monitor _API_. Sessions are * identified by a _session handle_ and they can be thought as a sort of C * facade of the C++ monitor class. In fact there is an evident similarity * between the C library functions operating on a monitoring session and the * methods of the `monitor` class. * * @section thread-safety Thread Safety * * The C++ API does not deal with thread safety explicitly. Rather, it leaves * the responsibility of implementing a thread-safe use of the library to the * callers. The C++ implementation has been designed in order to: * * - Encapsulate all the state of a monitor into its class fields. * - Perform no concurrent access control in methods or class fields. * - Guarantee that functions and _static_ methods are thread safe. * * As a consequence, it is _not_ thread-safe to access a monitor's member, be it * a method or a field, from different threads concurrently. The easiest way to * implement thread-safety when using `libfswatch`, therefore, is segregating * access to each monitor instance from a different thread. * * Similarly, the C API has been designed in order to provide the same * guarantees offered by the C++ API: * * - Concurrently manipulating different monitoring sessions is thread safe. * - Concurrently manipulating the same monitoring session is _not_ thread * safe. * * @section cpp11 C++11 * * There is an additional limitation which affects the C library only: the C * binding implementation internally uses C++11 classes and keywords to provide * the aforementioned guarantees. If compiler or library support is not found * when building `libfswatch` the library will still build, but those guarantees * will _not_ be honoured. A warning such as the following will appear in the * output of `configure` to inform the user: * * configure: WARNING: libfswatch is not thread-safe because the current * combination of compiler and libraries do not support the thread_local * storage specifier. * * @section bug-reports Reporting Bugs and Suggestions * * If you find problems or have suggestions about this program or this manual, * please report them as new issues in the official GitHub repository of * `fswatch` at https://github.com/emcrisostomo/fswatch. Please, read the * `CONTRIBUTING.md` file for detailed instructions on how to contribute to * `fswatch`. */ /** * @page cpp-api C++ API * * The C++ API provides users an easy to use, object-oriented interface to a * wide range of file monitoring APIs. This API provides a common facade to a * set of heterogeneous APIs that not only greatly simplifies their usage, but * provides an indirection layer that makes applications more portable: as far * as there is an available monitor in another platform, an existing application * will just work. * * In reality, a monitor may have platform-specific behaviours that should be * taken into account when writing portable applications using this library. * This differences complicate the task of writing portable applications that * are truly independent of the file monitoring API they may be using. However, * monitors try to ‘compensate’ for any behavioural difference across * implementations. * * The fsw::monitor class is the basic type of the C++ API: it defines the * interface of every monitor and provides common functionality to inheritors of * this class, such as: * * - Configuration and life cycle (fsw::monitor). * - Event filtering (fsw::monitor). * - Path filtering (fsw::monitor). * - Monitor registration (fsw::monitor_factory). * - Monitor discovery (fsw::monitor_factory). * * @section Usage * * The typical usage pattern of this API is similar to the following: * * - An instance of a monitor is either created directly or through the * factory (fsw::monitor_factory). * - The monitor is configured (fsw::monitor). * - The monitor is run and change events are waited for * (fsw::monitor::start()). * * @section cpp-example Example * * // Create the default platform monitor * monitor *active_monitor = * monitor_factory::create_monitor(fsw_monitor_type::system_default_monitor_type, * paths, * process_events); * * // Configure the monitor * active_monitor->set_properties(monitor_properties); * active_monitor->set_allow_overflow(allow_overflow); * active_monitor->set_latency(latency); * active_monitor->set_recursive(recursive); * active_monitor->set_directory_only(directory_only); * active_monitor->set_event_type_filters(event_filters); * active_monitor->set_filters(filters); * active_monitor->set_follow_symlinks(follow_symlinks); * active_monitor->set_watch_access(watch_access); * * // Start the monitor * active_monitor->start(); */ /** * @page c-api C API * * The C API, whose main header file is libfswatch.h, is a C-compatible * lightweight wrapper around the C++ API that provides an easy to use binding * to C clients. The central type in the C API is the _monitoring session_, an * opaque type identified by a handle of type ::FSW_HANDLE that can be * manipulated using the C functions of this library. * * Session-modifying API calls (such as fsw_add_path()) will take effect the * next time a monitor is started with fsw_start_monitor(). * * @section cpp-to-c Translating the C++ API to C * * The conventions used to translate C++ types into C types are simple: * * - `std::string` is represented as a `NUL`-terminated `char *`. * * - Lists are represented as arrays whose length is specified in a separate * field. * * - More complex types are usually translated as a `struct` containing data * fields and a set of functions to operate on it. * * @section c-thread-safety Thread Safety * * If the compiler and the C++ library used to build `libfswatch` support the * `thread_local` storage specifier then this API is thread safe and a * different state is maintained on a per-thread basis. * * Even when `thread_local` is not available, manipulating _different_ * monitoring sessions concurrently from different threads is thread safe, since * they share no data. * * @section c-lib-init Library Initialization * * Before calling any library method, the library must be initialized by calling * the fsw_init_library() function: * * // Initialize the library * FSW_STATUS ret = fsw_init_library(); * if (ret != FSW_OK) * { * exit(1); * } * * @section c-status-code Status Codes and Errors * * Most API functions return a status code of type ::FSW_STATUS, defined in the * error.h header. A successful API call returns ::FSW_OK and the last error * can be obtained calling the fsw_last_error() function. * * @section c-example Example * * This is a basic example of how a monitor session can be constructed and run * using the C API. To be valid, a session needs at least the following * information: * * - A path to watch. * - A _callback_ to process the events sent by the monitor. * * The next code fragment shows how to create and start a basic monitoring * session (error checking code was omitted): * * // Initialize the library * fsw_init_library(); * * // Use the default monitor. * const FSW_HANDLE handle = fsw_init_session(); * fsw_add_path(handle, "my/path"); * fsw_set_callback(handle, my_callback); * fsw_start_monitor(handle); */ /** * @page history History * * @section v900 9:0:0 * * - Add fsw::monitor_filter::read_from_file() to load filters from a file. * - Add fsw_stop_monitor() function to stop a running monitor. * - Change FSW_HANDLE type. * * @section v600 8:0:2 * * - Add a mutex to protect the fsw::monitor::notify_events() method. * - Substitute C++ header names with C names in C headers. * * @section v600 7:0:1 * * - fsw::monitor::~monitor(): update to invoke fsw::monitor::stop(). * - Close resources in monitor::on_stop() instead of doing it in destructors. * - Add inactivity callback. * * @section v600 6:0:0 * * - fsw::monitor::stop(): added. * - fsw::monitor::monitor(): update to move paths instead of copying them. * - fsw::monitor_factory::exists_type(const std::string&): added. * - fsw::monitor_factory::exists_type(const fsw_monitor_type&): added. * - fsw::fsevents_monitor::set_numeric_event(): removed. * - fsw::string_utils::string_from_format: added. * - fsw::string_utils::vstring_from_format: added. * * @section v502 5:0:2 * * - A monitor based on the Solaris/Illumos File Events Notification API has * been added. * * - The possibility of watching for directories only during a recursive scan. * This feature helps reducing the number of open file descriptors if a * generic change event for a directory is acceptable instead of events on * directory children. * * - fsw::fen_monitor: added to provide a monitor based on the Solaris/Illumos * File Events Notification API. * * - fsw::monitor::set_directory_only(): added to set a flag to only watch * directories during a recursive scan. * * - fsw_set_directory_only(): added to set a flag to only watch directories * during a recursive scan. * * - fsw_logf_perror(): added to log a `printf()`-style message using * `perror()`. * * @section v401 4:0:1 * * - fsw::windows_monitor: a monitor for Microsoft Windows was added. * * - A logging function has been added to log verbose messages. * * - A family of functions and macros have been added to log diagnostic * messages: * * - fsw_flog() * - fsw_logf() * - fsw_flogf() * - fsw_log_perror() * - ::FSW_LOG * - ::FSW_ELOG * - ::FSW_LOGF * - ::FSW_ELOGF * - ::FSW_FLOGF * * @section v300 3:0:0 * * - Added ability to filter events _by type_: * * - fsw::monitor::add_event_type_filter() * - fsw::monitor::set_event_type_filters() * * - fsw::monitor::notify_events(): added to centralize event filtering and * dispatching into the monitor base class. * * - Added ability to get event types by name and stringify them: * * - fsw::event::get_event_flag_by_name() * - fsw::event::get_event_flag_name() * - fsw_get_event_flag_by_name() * - fsw_get_event_flag_name() * * - fsw_event_type_filter: added to represent an event type filter. * * - ::FSW_ERR_UNKNOWN_VALUE: added error code. * * - fsw_add_event_type_filter(): added to add an event type filter. */ /** * @page path-filtering Path Filtering * * A _path filter_ (fsw::monitor_filter) can be used to filter event paths. A * filter type (::fsw_filter_type) determines whether the filter regular * expression is used to include and exclude paths from the list of the events * processed by the library. `libfswatch` processes filters this way: * * - If a path matches an including filter, the path is _accepted_ no matter * any other filter. * * - If a path matches an excluding filter, the path is _rejected_. * * - If a path matches no lters, the path is _accepted_. * * Said another way: * * - All paths are accepted _by default_, unless an exclusion filter says * otherwise. * * - Inclusion filters may override any other exclusion filter. * * - The order in the filter definition has no effect. */ #ifdef HAVE_CONFIG_H # include "libfswatch_config.h" #endif #include "gettext_defs.h" #include #include #include #include #include #include #include #include "libfswatch.h" #include "../c++/libfswatch_map.hpp" #include "../c++/filter.hpp" #include "../c++/monitor.hpp" #include "../c++/libfswatch_exception.hpp" using namespace std; using namespace fsw; typedef struct FSW_SESSION { vector paths; fsw_monitor_type type; fsw::monitor *monitor; FSW_CEVENT_CALLBACK callback; double latency; bool allow_overflow; bool recursive; bool directory_only; bool follow_symlinks; vector filters; vector event_type_filters; map properties; void *data; } FSW_SESSION; static bool fsw_libfswatch_verbose = false; static FSW_THREAD_LOCAL FSW_STATUS last_error; // Forward declarations. static FSW_EVENT_CALLBACK libfsw_cpp_callback_proxy; static FSW_SESSION *get_session(const FSW_HANDLE handle); static int create_monitor(FSW_HANDLE handle, const fsw_monitor_type type); static FSW_STATUS fsw_set_last_error(const int error); /* * Library initialization routine. Currently, libfswatch only initializes * gettext. */ FSW_STATUS fsw_init_library() { // Trigger gettext operations #ifdef ENABLE_NLS bindtextdomain(PACKAGE, LOCALEDIR); #endif return FSW_OK; } typedef struct fsw_callback_context { FSW_HANDLE handle; FSW_CEVENT_CALLBACK callback; void *data; } fsw_callback_context; void libfsw_cpp_callback_proxy(const std::vector& events, void *context_ptr) { // TODO: A C friendly error handler should be notified instead of throwing an exception. if (!context_ptr) throw int(FSW_ERR_MISSING_CONTEXT); const fsw_callback_context *context = static_cast (context_ptr); fsw_cevent *const cevents = static_cast (malloc( sizeof(fsw_cevent) * events.size())); if (cevents == nullptr) throw int(FSW_ERR_MEMORY); for (unsigned int i = 0; i < events.size(); ++i) { fsw_cevent *cevt = &cevents[i]; const event& evt = events[i]; // Copy event into C event wrapper. const string path = evt.get_path(); // Copy std::string into char * buffer and null-terminate it. cevt->path = static_cast (malloc( sizeof(char *) * (path.length() + 1))); if (!cevt->path) throw int(FSW_ERR_MEMORY); strncpy(cevt->path, path.c_str(), path.length()); cevt->path[path.length()] = '\0'; cevt->evt_time = evt.get_time(); const vector flags = evt.get_flags(); cevt->flags_num = flags.size(); if (!cevt->flags_num) cevt->flags = nullptr; else { cevt->flags = static_cast ( malloc(sizeof(fsw_event_flag) * cevt->flags_num)); if (!cevt->flags) throw int(FSW_ERR_MEMORY); } for (unsigned int e = 0; e < cevt->flags_num; ++e) { cevt->flags[e] = flags[e]; } } // TODO manage C++ exceptions from C code (*(context->callback))(cevents, events.size(), context->data); // Deallocate memory allocated by events. for (unsigned int i = 0; i < events.size(); ++i) { fsw_cevent *cevt = &cevents[i]; if (cevt->flags) free(static_cast (cevt->flags)); free(static_cast (cevt->path)); } free(static_cast (cevents)); } FSW_HANDLE fsw_init_session(const fsw_monitor_type type) { FSW_SESSION *session = new FSW_SESSION{}; session->type = type; return session; } int create_monitor(const FSW_HANDLE handle, const fsw_monitor_type type) { try { FSW_SESSION *session = get_session(handle); // Check sufficient data is present to build a monitor. if (!session->callback) return fsw_set_last_error(int(FSW_ERR_CALLBACK_NOT_SET)); if (session->monitor) return fsw_set_last_error(int(FSW_ERR_MONITOR_ALREADY_EXISTS)); if (!session->paths.size()) return fsw_set_last_error(int(FSW_ERR_PATHS_NOT_SET)); fsw_callback_context *context_ptr = new fsw_callback_context; context_ptr->handle = session; context_ptr->callback = session->callback; context_ptr->data = session->data; monitor *current_monitor = monitor_factory::create_monitor(type, session->paths, libfsw_cpp_callback_proxy, context_ptr); session->monitor = current_monitor; } catch (libfsw_exception& ex) { return fsw_set_last_error(int(ex)); } catch (int error) { return fsw_set_last_error(error); } return fsw_set_last_error(FSW_OK); } FSW_STATUS fsw_add_path(const FSW_HANDLE handle, const char *path) { if (!path) return fsw_set_last_error(int(FSW_ERR_INVALID_PATH)); FSW_SESSION *session = get_session(handle); session->paths.push_back(path); return fsw_set_last_error(FSW_OK); } FSW_STATUS fsw_add_property(const FSW_HANDLE handle, const char *name, const char *value) { if (!name || !value) return fsw_set_last_error(FSW_ERR_INVALID_PROPERTY); FSW_SESSION *session = get_session(handle); session->properties[name] = value; return fsw_set_last_error(FSW_OK); } FSW_STATUS fsw_set_callback(const FSW_HANDLE handle, const FSW_CEVENT_CALLBACK callback, void *data) { if (!callback) return fsw_set_last_error(int(FSW_ERR_INVALID_CALLBACK)); FSW_SESSION *session = get_session(handle); session->callback = callback; session->data = data; return fsw_set_last_error(FSW_OK); } FSW_STATUS fsw_set_allow_overflow(const FSW_HANDLE handle, const bool allow_overflow) { FSW_SESSION *session = get_session(handle); session->allow_overflow = allow_overflow; return fsw_set_last_error(FSW_OK); } FSW_STATUS fsw_set_latency(const FSW_HANDLE handle, const double latency) { if (latency < 0) return fsw_set_last_error(int(FSW_ERR_INVALID_LATENCY)); FSW_SESSION *session = get_session(handle); session->latency = latency; return fsw_set_last_error(FSW_OK); } FSW_STATUS fsw_set_recursive(const FSW_HANDLE handle, const bool recursive) { FSW_SESSION *session = get_session(handle); session->recursive = recursive; return fsw_set_last_error(FSW_OK); } FSW_STATUS fsw_set_directory_only(const FSW_HANDLE handle, const bool directory_only) { FSW_SESSION *session = get_session(handle); session->directory_only = directory_only; return fsw_set_last_error(FSW_OK); } FSW_STATUS fsw_set_follow_symlinks(const FSW_HANDLE handle, const bool follow_symlinks) { FSW_SESSION *session = get_session(handle); session->follow_symlinks = follow_symlinks; return fsw_set_last_error(FSW_OK); } FSW_STATUS fsw_add_event_type_filter(const FSW_HANDLE handle, const fsw_event_type_filter event_type) { FSW_SESSION *session = get_session(handle); session->event_type_filters.push_back(event_type); return fsw_set_last_error(FSW_OK); } FSW_STATUS fsw_add_filter(const FSW_HANDLE handle, const fsw_cmonitor_filter filter) { FSW_SESSION *session = get_session(handle); session->filters.push_back( {filter.text, filter.type, filter.case_sensitive, filter.extended}); return fsw_set_last_error(FSW_OK); } FSW_STATUS fsw_start_monitor(const FSW_HANDLE handle) { try { FSW_SESSION *session = get_session(handle); if (!session->monitor) create_monitor(handle, session->type); if (session->monitor->is_running()) return fsw_set_last_error(int(FSW_ERR_MONITOR_ALREADY_RUNNING)); session->monitor->set_allow_overflow(session->allow_overflow); session->monitor->set_filters(session->filters); session->monitor->set_event_type_filters(session->event_type_filters); session->monitor->set_follow_symlinks(session->follow_symlinks); if (session->latency) session->monitor->set_latency(session->latency); session->monitor->set_recursive(session->recursive); session->monitor->set_directory_only(session->directory_only); session->monitor->start(); } catch (libfsw_exception& ex) { return fsw_set_last_error(int(ex)); } catch (int error) { return fsw_set_last_error(error); } return fsw_set_last_error(FSW_OK); } FSW_STATUS fsw_stop_monitor(const FSW_HANDLE handle) { try { FSW_SESSION *session = get_session(handle); if (session->monitor == nullptr) return fsw_set_last_error(int(FSW_ERR_UNKNOWN_MONITOR_TYPE)); if (!session->monitor->is_running()) return fsw_set_last_error(int(FSW_OK)); session->monitor->stop(); } catch (libfsw_exception& ex) { return fsw_set_last_error(int(ex)); } catch (int error) { return fsw_set_last_error(error); } return fsw_set_last_error(FSW_OK); } FSW_STATUS fsw_destroy_session(const FSW_HANDLE handle) { int ret = FSW_OK; try { FSW_SESSION *session = get_session(handle); if (session->monitor) { if (session->monitor->is_running()) { return fsw_set_last_error(FSW_ERR_MONITOR_ALREADY_RUNNING); } void *context = session->monitor->get_context(); if (!context) { session->monitor->set_context(nullptr); delete static_cast (context); } delete session->monitor; } } catch (int error) { ret = error; } return fsw_set_last_error(ret); } FSW_SESSION *get_session(const FSW_HANDLE handle) { return handle; } FSW_STATUS fsw_set_last_error(const FSW_STATUS error) { last_error = error; return last_error; } FSW_STATUS fsw_last_error() { return last_error; } bool fsw_is_verbose() { return fsw_libfswatch_verbose; } void fsw_set_verbose(bool verbose) { fsw_libfswatch_verbose = verbose; } fswatch-1.11.2/libfswatch/src/libfswatch/c/cmonitor.h000644 000765 000024 00000003470 13174733730 023161 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Header of the `libfswatch` library defining the monitor types. * * @copyright Copyright (c) 2014-2016 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef FSW__CMONITOR_H # define FSW__CMONITOR_H # include # ifdef __cplusplus extern "C" { # endif /** * @brief Available monitors. * * This enumeration lists all the available monitors, where the special * ::system_default_monitor_type element refers to the platform-specific * default monitor. */ enum fsw_monitor_type { system_default_monitor_type = 0, /**< System default monitor. */ fsevents_monitor_type, /**< OS X FSEvents monitor. */ kqueue_monitor_type, /**< BSD `kqueue` monitor. */ inotify_monitor_type, /**< Linux `inotify` monitor. */ windows_monitor_type, /**< Windows monitor. */ poll_monitor_type, /**< `stat()`-based poll monitor. */ fen_monitor_type /**< Solaris/Illumos monitor. */ }; # ifdef __cplusplus } # endif #endif /* FSW__CMONITOR_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c/cevent.h000644 000765 000024 00000013173 13174733730 022614 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Event type manipulation. * * This header file defines the event types of the `libfswatch` API. * * @copyright Copyright (c) 2014-2015 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef FSW__CEVENT_H # define FSW__CEVENT_H # include # include # include "libfswatch_types.h" # ifdef __cplusplus extern "C" { # endif /** * @brief Backend-agnostic change flags. * * Each element of this enum represents a backend-agnostic change flag. No * direct mapping to backend-specific change types is guaranteed to exist: a * change type may be mapped to multiple `fsw_event_flag` instances included * the `PlatformSpecific` flag. * * The values of event flags are all powers of 2, that is numbers @f$f=2^n@f$ * where @f$n@f$ is an integer. This representation makes it easy to combine * flags into a bit mask and encode multiple events flags into a single integer. * * A monitor implementation is required to map implementation-specific flags * into API flags. Sometimes, though, a perfect match is not possible and the * following situation may arise: * * - One platform-specific flag must be mapped into multiple API flags. * * - Multiple platform-specific flags must be mapped into a single API flag. * * - A mapping is not possible for some flags, in which case they should be * mapped to fsw_event_flag::PlatformSpecific. The API currently offers no * way to retain a platform-specific event flag value in this case. */ enum fsw_event_flag { NoOp = 0, /**< No event has occurred. */ PlatformSpecific = (1 << 0), /**< Platform-specific placeholder for event type that cannot currently be mapped. */ Created = (1 << 1), /**< An object was created. */ Updated = (1 << 2), /**< An object was updated. */ Removed = (1 << 3), /**< An object was removed. */ Renamed = (1 << 4), /**< An object was renamed. */ OwnerModified = (1 << 5), /**< The owner of an object was modified. */ AttributeModified = (1 << 6), /**< The attributes of an object were modified. */ MovedFrom = (1 << 7), /**< An object was moved from this location. */ MovedTo = (1 << 8), /**< An object was moved to this location. */ IsFile = (1 << 9), /**< The object is a file. */ IsDir = (1 << 10), /**< The object is a directory. */ IsSymLink = (1 << 11), /**< The object is a symbolic link. */ Link = (1 << 12), /**< The link count of an object has changed. */ Overflow = (1 << 13) /**< The event queue has overflowed. */ }; extern fsw_event_flag FSW_ALL_EVENT_FLAGS[15]; /** * @brief Get event flag by name. * * This function looks for an event flag called @p name and, if it exists, it * writes its value onto @p flag and @c FSW_OK, otherwise @p flag is not * modified and @c FSW_ERR_UNKNOWN_VALUE is returned. * * @param[in] name The name of the event flag to look for. * @param[out] flag The output variable where the event flag is returned. * @return #FSW_OK if the functions succeeds, #FSW_ERR_UNKNOWN_VALUE * otherwise. */ FSW_STATUS fsw_get_event_flag_by_name(const char *name, enum fsw_event_flag *flag); /** * @brief Get the name of an event flag. * * This function looks for the name of the specified event @p flag. If it * exists, it returns its name, otherwise @c nullptr is returned. * * @param[in] flag The event flag to look for. * @return The name of @p flag, or @c nullptr if it does not exist. */ char *fsw_get_event_flag_name(const enum fsw_event_flag flag); /** * A file change event is represented as an instance of this struct where: * - path is the path where the event was triggered. * - evt_time the time when the event was triggered. * - flags is an array of fsw_event_flag of size flags_num. * - flags_num is the size of the flags array. */ typedef struct fsw_cevent { char * path; time_t evt_time; enum fsw_event_flag * flags; unsigned int flags_num; } fsw_cevent; /** * A function pointer of type FSW_CEVENT_CALLBACK is used by the API as a * callback to provide information about received events. The callback is * passed the following arguments: * - events, a const pointer to an array of events of type const fsw_cevent. * - event_num, the size of the *events array. * - data, optional persisted data for a callback. * * The memory used by the fsw_cevent objects will be freed at the end of the * callback invocation. A callback should copy such data instead of storing * a pointer to it. */ typedef void (*FSW_CEVENT_CALLBACK)(fsw_cevent const *const events, const unsigned int event_num, void *data); # ifdef __cplusplus } # endif #endif /* FSW__CEVENT_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c/libfswatch_log.h000644 000765 000024 00000005525 13174733730 024321 0ustar00enricostaff000000 000000 /* * Copyright (c) 2015 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Header of the `libfswatch` library containing logging functions.. * * @copyright Copyright (c) 2014-2015 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef LIBFSW_LOG_H # define LIBFSW_LOG_H #include /** * Prints the specified message to standard output. */ void fsw_log(const char * msg); /** * Prints the specified message to the specified file. */ void fsw_flog(FILE * f, const char * msg); /** * Formats the specified message and prints it to standard output. The message * string format conforms with printf. */ void fsw_logf(const char * format, ...); /** * Formats the specified message and prints it to the specified file. The * message string format conforms with printf. */ void fsw_flogf(FILE * f, const char * format, ...); /** * Prints the specified message using perror. */ void fsw_log_perror(const char * msg); /** * Prints the specified message using perror. The message string format * conforms with printf. */ void fsw_logf_perror(const char * format, ...); /** * @brief Log the specified message to the standard output prepended by the * source line number. */ # define FSW_LOG(msg) fsw_logf("%s: ", __func__); fsw_log(msg) /** * @brief Log the specified message to the standard error prepended by the * source line number. */ # define FSW_ELOG(msg) fsw_flogf(stderr, "%s: ", __func__); fsw_flog(stderr, msg) /** * @brief Log the specified `printf()`-like message to the standard output * prepended by the source line number. */ # define FSW_LOGF(msg, ...) fsw_logf("%s: ", __func__); fsw_logf(msg, __VA_ARGS__) /** * @brief Log the specified `printf()`-like message to the standard error * prepended by the source line number. */ # define FSW_ELOGF(msg, ...) fsw_flogf(stderr, "%s: ", __func__); fsw_flogf(stderr, msg, __VA_ARGS__) /** * @brief Log the specified `printf()`-like message to the specified file * descriptor prepended by the source line number. */ # define FSW_FLOGF(f, msg, ...) fsw_flogf(f, "%s: ", __func__); fsw_flogf(f, msg, __VA_ARGS__) #endif /* LIBFSW_LOG_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c/cevent.cpp000644 000765 000024 00000003224 13175131667 023145 0ustar00enricostaff000000 000000 /* * Copyright (c) 2015 Enrico M. Crisostomo * * 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, 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 . */ #ifdef HAVE_CONFIG_H # include "libfswatch_config.h" #endif #include "cevent.h" #include #include #include "../c++/event.hpp" #include "../c++/libfswatch_exception.hpp" using namespace std; using namespace fsw; fsw_event_flag FSW_ALL_EVENT_FLAGS[] = { NoOp, PlatformSpecific, Created, Updated, Removed, Renamed, OwnerModified, AttributeModified, MovedFrom, MovedTo, IsFile, IsDir, IsSymLink, Link, Overflow }; FSW_STATUS fsw_get_event_flag_by_name(const char *name, fsw_event_flag *flag) { try { *flag = event::get_event_flag_by_name(name); return FSW_OK; } catch (const libfsw_exception& ex) { return FSW_ERR_UNKNOWN_VALUE; } } char *fsw_get_event_flag_name(const fsw_event_flag flag) { string name = event::get_event_flag_name(flag); char *cstr = static_cast(malloc(name.size() + 1)); if (cstr == nullptr) return nullptr; strcpy(cstr, name.c_str()); return cstr; } fswatch-1.11.2/libfswatch/src/libfswatch/c++/event.hpp000644 000765 000024 00000006360 13174733730 023137 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Header of the fsw::event class. * * @copyright Copyright (c) 2014-2015 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef FSW_EVENT_H # define FSW_EVENT_H # include # include # include # include # include "../c/cevent.h" namespace fsw { /** * @brief Type representing a file change event. * * This class represents a file change event in the `libfswatch` API. An * event contains: * * - The path. * - The time the event was raised. * - A vector of flags specifying the type of the event. */ class event { public: /** * @brief Constructs an event. * * @param path The path the event refers to. * @param evt_time The time the event was raised. * @param flags The vector of flags specifying the type of the event. */ event(std::string path, time_t evt_time, std::vector flags); /** * @brief Destructs an event. * * This is a virtual destructor that performs no operations. */ virtual ~event(); /** * @brief Returns the path of the event. * * @return The path of the event. */ std::string get_path() const; /** * @brief Returns the time of the event. * * @return The time of the event. */ time_t get_time() const; /** * @brief Returns the flags of the event. * * @return The flags of the event. */ std::vector get_flags() const; /** * @brief Get event flag by name. * * @param name The name of the event flag to look for. * @return The event flag whose name is @p name, otherwise * @exception libfsw_exception if no event flag is found. */ static fsw_event_flag get_event_flag_by_name(const std::string& name); /** * @brief Get the name of an event flag. * * @param flag The event flag. * @return The name of @p flag. * @exception libfsw_exception if no event flag is found. */ static std::string get_event_flag_name(const fsw_event_flag& flag); private: std::string path; time_t evt_time; std::vector evt_flags; }; /** * @brief Overload of the `<<` operator to print an event using `iostreams`. * * @param out A reference to the output stream. * @param flag The flag to print. * @return A reference to the stream. */ std::ostream& operator<<(std::ostream& out, const fsw_event_flag flag); } #endif /* FSW_EVENT_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/poll_monitor.hpp000644 000765 000024 00000005367 13174733730 024541 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief `stat()` based monitor. * * @copyright Copyright (c) 2014-2016 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef FSW_POLL_MONITOR_H # define FSW_POLL_MONITOR_H # include "monitor.hpp" # include # include namespace fsw { /** * @brief `stat()`-based monitor. * * This monitor uses the `stat()` function to periodically check the observed * paths and detect changes. */ class poll_monitor : public monitor { REGISTER_MONITOR(poll_monitor, poll_monitor_type); public: /** * @brief Constructs an instance of this class. */ poll_monitor(std::vector paths, FSW_EVENT_CALLBACK *callback, void *context = nullptr); /** * @brief Destroys an instance of this class. */ virtual ~poll_monitor(); protected: void run(); private: static const unsigned int MIN_POLL_LATENCY = 1; poll_monitor(const poll_monitor& orig) = delete; poll_monitor& operator=(const poll_monitor& that) = delete; typedef bool (poll_monitor::*poll_monitor_scan_callback)( const std::string& path, const struct stat& stat); typedef struct watched_file_info { time_t mtime; time_t ctime; } watched_file_info; struct poll_monitor_data; void scan(const std::string& path, poll_monitor_scan_callback fn); void collect_initial_data(); void collect_data(); bool add_path(const std::string& path, const struct stat& fd_stat, poll_monitor_scan_callback poll_callback); bool initial_scan_callback(const std::string& path, const struct stat& stat); bool intermediate_scan_callback(const std::string& path, const struct stat& stat); void find_removed_files(); void swap_data_containers(); poll_monitor_data *previous_data; poll_monitor_data *new_data; std::vector events; time_t curr_time; }; } #endif /* FSW_POLL_MONITOR_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/path_utils.cpp000644 000765 000024 00000004034 13175131667 024163 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ #include "gettext_defs.h" #include "path_utils.hpp" #include "c/libfswatch_log.h" #include #include #include #include #include using namespace std; namespace fsw { vector get_directory_children(const string& path) { vector children; DIR *dir = opendir(path.c_str()); if (!dir) { if (errno == EMFILE || errno == ENFILE) { perror("opendir"); } else { fsw_log_perror("opendir"); } return children; } while (struct dirent *ent = readdir(dir)) { children.push_back(ent->d_name); } closedir(dir); return children; } bool read_link_path(const string& path, string& link_path) { char *real_path = realpath(path.c_str(), nullptr); link_path = (real_path ? real_path : path); bool ret = (real_path != nullptr); free(real_path); return ret; } bool stat_path(const string& path, struct stat& fd_stat) { if (stat(path.c_str(), &fd_stat) != 0) { fsw_logf_perror(_("Cannot stat %s"), path.c_str()); return false; } return true; } bool lstat_path(const string& path, struct stat& fd_stat) { if (lstat(path.c_str(), &fd_stat) != 0) { fsw_logf_perror(_("Cannot lstat %s"), path.c_str()); return false; } return true; } } fswatch-1.11.2/libfswatch/src/libfswatch/c++/fen_monitor.cpp000644 000765 000024 00000024730 13175131667 024333 0ustar00enricostaff000000 000000 /* * Copyright (c) 2015 Enrico M. Crisostomo * * 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, 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 . */ #ifdef HAVE_CONFIG_H # include "libfswatch_config.h" #endif #ifdef HAVE_PORT_H # include # include # include # include # include # include # include # include # include # include "gettext_defs.h" # include "fen_monitor.hpp" # include "libfswatch_map.hpp" # include "libfswatch_set.hpp" # include "libfswatch_exception.hpp" # include "../c/libfswatch_log.h" # include "path_utils.hpp" using namespace std; namespace fsw { struct fen_info { struct file_obj fobj; int events; }; struct fen_monitor_load { int port; fsw_hash_map descriptors_by_file_name; fsw_hash_set descriptors_to_remove; fsw_hash_set paths_to_rescan; void initialize_fen() { if ((port = port_create()) == -1) { perror("port_create"); throw libfsw_exception(_("An error occurred while creating a port.")); } } ~fen_monitor_load() { close_fen(); } void close_fen() { if (!port) close(port); port = 0; } void add_watch(struct fen_info *fd, const string& path, const struct stat& fd_stat) { descriptors_by_file_name[path] = fd; } void remove_watch(const string& path) { struct fen_info *finfo = descriptors_by_file_name[path]; if (finfo) { free(finfo->fobj.fo_name); free(finfo); } descriptors_by_file_name.erase(path); } struct fen_info * get_descriptor_by_name(const string& path) { auto res = descriptors_by_file_name.find(path); if (res == descriptors_by_file_name.end()) return nullptr; return res->second; } }; typedef struct FenFlagType { uint32_t flag; fsw_event_flag type; } FenFlagType; static vector create_flag_type_vector() { vector flags; flags.push_back({FILE_ACCESS, fsw_event_flag::PlatformSpecific}); flags.push_back({FILE_MODIFIED, fsw_event_flag::Updated}); flags.push_back({FILE_ATTRIB, fsw_event_flag::AttributeModified}); flags.push_back({FILE_DELETE, fsw_event_flag::Removed}); flags.push_back({FILE_RENAME_TO, fsw_event_flag::MovedTo}); flags.push_back({FILE_RENAME_FROM, fsw_event_flag::MovedFrom}); flags.push_back({FILE_TRUNC, fsw_event_flag::PlatformSpecific}); flags.push_back({UNMOUNTED, fsw_event_flag::PlatformSpecific}); flags.push_back({MOUNTEDOVER, fsw_event_flag::PlatformSpecific}); return flags; } static const vector event_flag_type = create_flag_type_vector(); REGISTER_MONITOR_IMPL(fen_monitor, fen_monitor_type); fen_monitor::fen_monitor(vector paths_to_monitor, FSW_EVENT_CALLBACK * callback, void * context) : monitor(paths_to_monitor, callback, context), load(new fen_monitor_load()) { } fen_monitor::~fen_monitor() { delete load; } static vector decode_flags(uint32_t flag) { vector evt_flags; for (const FenFlagType &type : event_flag_type) { if (flag & type.flag) { evt_flags.push_back(type.type); } } return evt_flags; } static struct timespec create_timespec_from_latency(double latency) { double seconds; double nanoseconds = modf(latency, &seconds); nanoseconds *= 1000000000; struct timespec ts; ts.tv_sec = seconds; ts.tv_nsec = nanoseconds; return ts; } static int timespec_subtract(timespec& result, timespec& x, timespec& y) { /* Perform the carry for the later subtraction by updating y. */ if (x.tv_nsec < y.tv_nsec) { int nsec = (y.tv_nsec - x.tv_nsec) / 1000000000 + 1; y.tv_nsec -= 1000000000 * nsec; y.tv_sec += nsec; } if (x.tv_nsec - y.tv_nsec > 1000000000) { int nsec = (x.tv_nsec - y.tv_nsec) / 1000000000; y.tv_nsec += 1000000000 * nsec; y.tv_sec -= nsec; } /* Compute the time remaining to wait. tv_nsec is certainly positive. */ result.tv_sec = x.tv_sec - y.tv_sec; result.tv_nsec = x.tv_nsec - y.tv_nsec; /* Return 1 if result is negative. */ return x.tv_sec < y.tv_sec; } bool fen_monitor::associate_port(struct fen_info *finfo, const struct stat &fd_stat) { FSW_ELOGF(_("Associating %s.\n"), finfo->fobj.fo_name); struct file_obj *fobjp = &finfo->fobj; finfo->fobj.fo_atime = fd_stat.st_atim; finfo->fobj.fo_mtime = fd_stat.st_mtim; finfo->fobj.fo_ctime = fd_stat.st_ctim; if (port_associate(load->port, PORT_SOURCE_FILE, reinterpret_cast(fobjp), finfo->events, static_cast(finfo)) != 0) { // File may have been deleted or moved while processing the event. perror("port_associate()"); load->remove_watch(finfo->fobj.fo_name); return false; } return true; } bool fen_monitor::add_watch(const string &path, const struct stat &fd_stat) { // check if the path is already watched and if it is, // skip it and return false. if (is_path_watched(path)) { return false; } FSW_ELOGF(_("Adding %s to list of watched paths.\n"), path.c_str()); struct fen_info *finfo = load->get_descriptor_by_name(path); if (finfo == nullptr) { FSW_ELOG(_("Allocating fen_info.\n")); finfo = static_cast(malloc(sizeof(struct fen_info))); if (!finfo) { perror("malloc()"); throw libfsw_exception(_("Cannot allocate memory")); } if (!(finfo->fobj.fo_name = strdup(path.c_str()))) { free(finfo); perror("strdup()"); throw libfsw_exception(_("Cannot allocate memory")); } } // FILE_NOFOLLOW is currently not used because links are followed manually. finfo->events = FILE_MODIFIED | FILE_ATTRIB | FILE_TRUNC; if (watch_access) finfo->events |= FILE_ACCESS; if (!follow_symlinks) finfo->events |= FILE_NOFOLLOW; // if the descriptor could be opened, track it if (associate_port(finfo, fd_stat)) { load->add_watch(finfo, path, fd_stat); } return true; } bool fen_monitor::is_path_watched(const string& path) const { return (load->descriptors_by_file_name.find(path) != load->descriptors_by_file_name.end()) && (load->paths_to_rescan.find(path) == load->paths_to_rescan.end()); } bool fen_monitor::scan(const string& path, bool is_root_path) { struct stat fd_stat; if (!stat_path(path, fd_stat)) { load->remove_watch(path); return false; } bool is_dir = S_ISDIR(fd_stat.st_mode); if (!is_dir && !is_root_path && directory_only) return true; if (!is_dir && !accept_path(path)) return true; if (!is_dir) return add_watch(path, fd_stat); if (!recursive) return true; vector children = get_directory_children(path); for (string& child : children) { if (child.compare(".") == 0 || child.compare("..") == 0) continue; scan(path + "/" + child, false); } return add_watch(path, fd_stat); } void fen_monitor::scan_root_paths() { for (string& path : paths) { if (is_path_watched(path)) continue; if (!scan(path)) { FSW_ELOGF(_("%s cannot be found. Will retry later.\n"), path.c_str()); } } } void fen_monitor::process_events(struct fen_info *finfo, int event_flags) { time_t curr_time; time(&curr_time); vector events; events.push_back({finfo->fobj.fo_name, curr_time, decode_flags(event_flags)}); // The File Events Notification API requires the caller to associate a file path // each time an event is retrieved. if (event_flags & FILE_DELETE) load->descriptors_to_remove.insert(finfo); else load->paths_to_rescan.insert(finfo->fobj.fo_name); notify_events(events); } void fen_monitor::rescan_removed() { FSW_ELOG(_("Processing deleted descriptors.\n")); auto fd = load->descriptors_to_remove.begin(); while (fd != load->descriptors_to_remove.end()) { struct fen_info *finfo = *fd; if (!port_dissociate(load->port, PORT_SOURCE_FILE, reinterpret_cast(&finfo->fobj)) != 0) { perror("port_dissociate()"); } load->remove_watch(finfo->fobj.fo_name); load->descriptors_to_remove.erase(fd++); } } void fen_monitor::rescan_pending() { FSW_ELOG(_("Rescanning pending descriptors.\n")); auto path = load->paths_to_rescan.begin(); while (path != load->paths_to_rescan.end()) { FSW_ELOGF(_("Rescanning %s.\n"), path->c_str()); scan(*path); load->paths_to_rescan.erase(path++); } } void fen_monitor::run() { load->initialize_fen(); double sec; double frac = modf(latency, &sec); for (;;) { #ifdef HAVE_CXX_MUTEX unique_lock run_guard(run_mutex); if (should_stop) break; run_guard.unlock(); #endif rescan_removed(); rescan_pending(); scan_root_paths(); port_event_t pe; struct timespec timeout; timeout.tv_sec = sec; timeout.tv_nsec = 1000 * 1000 * 1000 * frac; if (port_get(load->port, &pe, &timeout) == 0) { switch (pe.portev_source) { case PORT_SOURCE_FILE: // Process file events. process_events((struct fen_info *)pe.portev_object, pe.portev_events); break; default: const char *msg = _("Event from unexpected source"); perror(msg); throw libfsw_exception(msg); } } else if (errno != ETIME && errno != EINTR) perror("port_get"); } } } #endif /* HAVE_PORT_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/kqueue_monitor.hpp000644 000765 000024 00000005446 13174733730 025070 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2016 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief `kqueue` monitor. * * @copyright Copyright (c) 2014-2016 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef FSW_KQUEUE_MONITOR_H # define FSW_KQUEUE_MONITOR_H # include "monitor.hpp" # include # include # include # include namespace fsw { /** * @brief Opaque structure containing implementation specific details of the * `kqueue` monitor. */ struct kqueue_monitor_load; /** * @brief Solaris/Illumos monitor. * * This monitor is built upon the `kqueue` API of the BSD kernels. */ class kqueue_monitor : public monitor { REGISTER_MONITOR(kqueue_monitor, kqueue_monitor_type); public: /** * @brief Constructs an instance of this class. */ kqueue_monitor(std::vector paths, FSW_EVENT_CALLBACK *callback, void *context = nullptr); /** * @brief Destroys an instance of this class. */ virtual ~kqueue_monitor(); protected: /** * @brief Executes the monitor loop. * * This call does not return until the monitor is stopped. * * @see stop() */ void run(); private: kqueue_monitor(const kqueue_monitor& orig) = delete; kqueue_monitor& operator=(const kqueue_monitor& that) = delete; void initialize_kqueue(); void terminate_kqueue(); bool scan(const std::string& path, bool is_root_path = true); bool add_watch(const std::string& path, const struct stat& fd_stat); bool is_path_watched(const std::string& path) const; void remove_deleted(); void rescan_pending(); void scan_root_paths(); int wait_for_events(const std::vector& changes, std::vector& event_list); void process_events(const std::vector& changes, const std::vector& event_list, int event_num); int kq = -1; // initial load kqueue_monitor_load *load; }; } #endif /* FSW_KQUEUE_MONITOR_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/libfswatch_exception.hpp000644 000765 000024 00000004315 13174733730 026220 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Base exception of the `libfswatch` library. * * @copyright Copyright (c) 2014-2016 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef LIBFSW_EXCEPTION_H # define LIBFSW_EXCEPTION_H # include "../c/error.h" # include # include namespace fsw { /** * @brief Base exception of the `libfswatch` library. * * An instance of this class stores an error message and an integer error * code. */ class libfsw_exception : public std::exception { public: /** * @brief Constructs an exception with the specified @p cause and error * @p code. * * @param cause The error message. * @param code The error code. */ libfsw_exception(std::string cause, int code = FSW_ERR_UNKNOWN_ERROR); libfsw_exception( const libfsw_exception& other ) noexcept; libfsw_exception& operator=(const libfsw_exception&) noexcept; /** * @brief Gets the error message. * * @return The error message. */ virtual const char *what() const noexcept; /** * @brief Gets the error code. * * @return The error code. */ virtual int error_code() const noexcept; /** * @brief Destructs an instance of this class. */ virtual ~libfsw_exception() noexcept; /** * @brief Gets the error code. */ explicit operator int() const noexcept; private: std::string cause; int code; }; } #endif /* LIBFSW_EXCEPTION_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/fsevents_monitor.cpp000644 000765 000024 00000016040 13175131667 025413 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2016 Enrico M. Crisostomo * * 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, 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 . */ #ifdef HAVE_CONFIG_H # include "libfswatch_config.h" #endif #include "fsevents_monitor.hpp" #include "gettext_defs.h" #include "libfswatch_exception.hpp" #include "c/libfswatch_log.h" # ifdef HAVE_CXX_MUTEX # include # endif using namespace std; namespace fsw { typedef struct FSEventFlagType { FSEventStreamEventFlags flag; fsw_event_flag type; } FSEventFlagType; static vector create_flag_type_vector() { vector flags; flags.push_back({kFSEventStreamEventFlagNone, fsw_event_flag::PlatformSpecific}); flags.push_back({kFSEventStreamEventFlagMustScanSubDirs, fsw_event_flag::PlatformSpecific}); flags.push_back({kFSEventStreamEventFlagUserDropped, fsw_event_flag::PlatformSpecific}); flags.push_back({kFSEventStreamEventFlagKernelDropped, fsw_event_flag::PlatformSpecific}); flags.push_back({kFSEventStreamEventFlagEventIdsWrapped, fsw_event_flag::PlatformSpecific}); flags.push_back({kFSEventStreamEventFlagHistoryDone, fsw_event_flag::PlatformSpecific}); flags.push_back({kFSEventStreamEventFlagRootChanged, fsw_event_flag::PlatformSpecific}); flags.push_back({kFSEventStreamEventFlagMount, fsw_event_flag::PlatformSpecific}); flags.push_back({kFSEventStreamEventFlagUnmount, fsw_event_flag::PlatformSpecific}); flags.push_back({kFSEventStreamEventFlagItemCreated, fsw_event_flag::Created}); flags.push_back({kFSEventStreamEventFlagItemRemoved, fsw_event_flag::Removed}); flags.push_back({kFSEventStreamEventFlagItemInodeMetaMod, fsw_event_flag::PlatformSpecific}); flags.push_back({kFSEventStreamEventFlagItemRenamed, fsw_event_flag::Renamed}); flags.push_back({kFSEventStreamEventFlagItemModified, fsw_event_flag::Updated}); flags.push_back({kFSEventStreamEventFlagItemFinderInfoMod, fsw_event_flag::PlatformSpecific}); flags.push_back({kFSEventStreamEventFlagItemChangeOwner, fsw_event_flag::OwnerModified}); flags.push_back({kFSEventStreamEventFlagItemXattrMod, fsw_event_flag::AttributeModified}); flags.push_back({kFSEventStreamEventFlagItemIsFile, fsw_event_flag::IsFile}); flags.push_back({kFSEventStreamEventFlagItemIsDir, fsw_event_flag::IsDir}); flags.push_back({kFSEventStreamEventFlagItemIsSymlink, fsw_event_flag::IsSymLink}); return flags; } static const vector event_flag_type = create_flag_type_vector(); REGISTER_MONITOR_IMPL(fsevents_monitor, fsevents_monitor_type); fsevents_monitor::fsevents_monitor(vector paths_to_monitor, FSW_EVENT_CALLBACK *callback, void *context) : monitor(paths_to_monitor, callback, context) { } fsevents_monitor::~fsevents_monitor() { } void fsevents_monitor::run() { #ifdef HAVE_CXX_MUTEX unique_lock run_loop_lock(run_mutex); #endif if (stream) return; // parsing paths vector dirs; for (string path : paths) { dirs.push_back(CFStringCreateWithCString(NULL, path.c_str(), kCFStringEncodingUTF8)); } if (dirs.size() == 0) return; CFArrayRef pathsToWatch = CFArrayCreate(NULL, reinterpret_cast (&dirs[0]), dirs.size(), &kCFTypeArrayCallBacks); FSEventStreamContext *context = new FSEventStreamContext(); context->version = 0; context->info = this; context->retain = nullptr; context->release = nullptr; context->copyDescription = nullptr; FSW_ELOG(_("Creating FSEvent stream...\n")); stream = FSEventStreamCreate(NULL, &fsevents_monitor::fsevents_callback, context, pathsToWatch, kFSEventStreamEventIdSinceNow, latency, kFSEventStreamCreateFlagFileEvents); if (!stream) throw libfsw_exception(_("Event stream could not be created.")); // Fire the event loop run_loop = CFRunLoopGetCurrent(); #ifdef HAVE_CXX_MUTEX run_loop_lock.unlock(); #endif FSW_ELOG(_("Scheduling stream with run loop...\n")); FSEventStreamScheduleWithRunLoop(stream, run_loop, kCFRunLoopDefaultMode); FSW_ELOG(_("Starting event stream...\n")); FSEventStreamStart(stream); FSW_ELOG(_("Starting run loop...\n")); CFRunLoopRun(); } /* * on_stop() is designed to be invoked with a lock on the run_mutex. */ void fsevents_monitor::on_stop() { if (!run_loop) throw libfsw_exception(_("run loop is null")); FSW_ELOG(_("Stopping run loop...\n")); CFRunLoopStop(run_loop); run_loop = nullptr; FSW_ELOG(_("Stopping event stream...\n")); FSEventStreamStop(stream); FSW_ELOG(_("Invalidating event stream...\n")); FSEventStreamInvalidate(stream); FSW_ELOG(_("Releasing event stream...\n")); FSEventStreamRelease(stream); stream = nullptr; } static vector decode_flags(FSEventStreamEventFlags flag) { vector evt_flags; for (const FSEventFlagType& type : event_flag_type) { if (flag & type.flag) { evt_flags.push_back(type.type); } } return evt_flags; } void fsevents_monitor::fsevents_callback(ConstFSEventStreamRef streamRef, void *clientCallBackInfo, size_t numEvents, void *eventPaths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]) { fsevents_monitor *fse_monitor = static_cast (clientCallBackInfo); if (!fse_monitor) { throw libfsw_exception(_("The callback info cannot be cast to fsevents_monitor.")); } // Build the notification objects. vector events; time_t curr_time; time(&curr_time); for (size_t i = 0; i < numEvents; ++i) { events.push_back({((char **) eventPaths)[i], curr_time, decode_flags(eventFlags[i])}); } if (events.size() > 0) { fse_monitor->notify_events(events); } } } fswatch-1.11.2/libfswatch/src/libfswatch/c++/inotify_monitor.hpp000644 000765 000024 00000005245 13174733730 025247 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Solaris/Illumos monitor. * * @copyright Copyright (c) 2014-2016 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef FSW_INOTIFY_MONITOR_H # define FSW_INOTIFY_MONITOR_H # include "monitor.hpp" # include # include # include # include namespace fsw { /** * @brief Opaque structure containing implementation specific details of the * FSEvents monitor. */ struct inotify_monitor_impl; /** * @brief Solaris/Illumos monitor. * * This monitor is built upon the _File Events Notification_ API of the * Solaris and Illumos kernels. */ class inotify_monitor : public monitor { REGISTER_MONITOR(inotify_monitor, inotify_monitor_type); public: /** * @brief Constructs an instance of this class. */ inotify_monitor(std::vector paths, FSW_EVENT_CALLBACK *callback, void *context = nullptr); /** * @brief Destroys an instance of this class. */ virtual ~inotify_monitor(); protected: /** * @brief Executes the monitor loop. * * This call does not return until the monitor is stopped. * * @see stop() */ void run(); private: inotify_monitor(const inotify_monitor& orig) = delete; inotify_monitor& operator=(const inotify_monitor& that) = delete; void scan_root_paths(); bool is_watched(const std::string& path) const; void preprocess_dir_event(struct inotify_event *event); void preprocess_event(struct inotify_event *event); void preprocess_node_event(struct inotify_event *event); void scan(const std::string& path, const bool accept_non_dirs = true); bool add_watch(const std::string& path, const struct stat& fd_stat); void process_pending_events(); void remove_watch(int fd); inotify_monitor_impl *impl; }; } #endif /* FSW_INOTIFY_MONITOR_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/monitor.cpp000644 000765 000024 00000031014 13175131667 023474 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2016 Enrico M. Crisostomo * * 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, 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 . */ #ifdef HAVE_CONFIG_H # include "libfswatch_config.h" #endif #include "gettext_defs.h" #include "monitor.hpp" #include "libfswatch_exception.hpp" #include "../c/libfswatch_log.h" #include "string/string_utils.hpp" #include #include #include #include #include #include using namespace std; using namespace std::chrono; namespace fsw { struct compiled_monitor_filter { regex_t regex; fsw_filter_type type; }; #ifdef HAVE_CXX_MUTEX #define FSW_MONITOR_RUN_GUARD unique_lock run_guard(run_mutex); #define FSW_MONITOR_RUN_GUARD_LOCK run_guard.lock(); #define FSW_MONITOR_RUN_GUARD_UNLOCK run_guard.unlock(); #define FSW_MONITOR_NOTIFY_GUARD unique_lock notify_guard(notify_mutex); #else #define FSW_MONITOR_RUN_GUARD #define FSW_MONITOR_RUN_GUARD_LOCK #define FSW_MONITOR_RUN_GUARD_UNLOCK #define FSW_MONITOR_NOTIFY_GUARD #endif monitor::monitor(vector paths, FSW_EVENT_CALLBACK *callback, void *context) : paths(std::move(paths)), callback(callback), context(context), latency(1) { if (callback == nullptr) { throw libfsw_exception(_("Callback cannot be null."), FSW_ERR_CALLBACK_NOT_SET); } #ifdef HAVE_INACTIVITY_CALLBACK milliseconds epoch = duration_cast(system_clock::now().time_since_epoch()); last_notification.store(epoch); #endif } void monitor::set_allow_overflow(bool overflow) { allow_overflow = overflow; } void monitor::set_latency(double latency) { if (latency < 0) { throw libfsw_exception(_("Latency cannot be negative."), FSW_ERR_INVALID_LATENCY); } this->latency = latency; } void monitor::set_fire_idle_event(bool fire_idle_event) { this->fire_idle_event = fire_idle_event; } milliseconds monitor::get_latency_ms() const { return milliseconds((long long)(latency * 1000 * 1.1)); } void monitor::set_recursive(bool recursive) { this->recursive = recursive; } void monitor::set_directory_only(bool directory_only) { this->directory_only = directory_only; } void monitor::add_event_type_filter(const fsw_event_type_filter& filter) { this->event_type_filters.push_back(filter); } void monitor::set_event_type_filters(const vector& filters) { event_type_filters.clear(); for (const auto& filter : filters) add_event_type_filter(filter); } void monitor::add_filter(const monitor_filter& filter) { regex_t regex; int flags = 0; if (!filter.case_sensitive) flags |= REG_ICASE; if (filter.extended) flags |= REG_EXTENDED; if (regcomp(®ex, filter.text.c_str(), flags)) { throw libfsw_exception( string_utils::string_from_format( _("An error occurred during the compilation of %s"), filter.text.c_str()), FSW_ERR_INVALID_REGEX); } this->filters.push_back({regex, filter.type}); } void monitor::set_property(const std::string& name, const std::string& value) { properties[name] = value; } void monitor::set_properties(const map options) { properties = std::move(options); } string monitor::get_property(string name) { return properties[name]; } void monitor::set_filters(const vector& filters) { for (const monitor_filter& filter : filters) { add_filter(filter); } } void monitor::set_follow_symlinks(bool follow) { follow_symlinks = follow; } void monitor::set_watch_access(bool access) { watch_access = access; } bool monitor::accept_event_type(fsw_event_flag event_type) const { // If no filters are set, then accept the event. if (event_type_filters.size() == 0) return true; // If filters are set, accept the event only if present amongst the filters. for (const auto& filter : event_type_filters) { if (filter.flag == event_type) { return true; } } // If no filters match, then reject the event. return false; } bool monitor::accept_path(const string& path) const { return accept_path(path.c_str()); } bool monitor::accept_path(const char *path) const { bool is_excluded = false; for (const auto& filter : filters) { if (regexec(&filter.regex, path, 0, nullptr, 0) == 0) { if (filter.type == fsw_filter_type::filter_include) return true; is_excluded = (filter.type == fsw_filter_type::filter_exclude); } } return !is_excluded; } void *monitor::get_context() const { return context; } void monitor::set_context(void *context) { this->context = context; } monitor::~monitor() { stop(); for (auto& re : filters) regfree(&re.regex); } static monitor *create_default_monitor(vector paths, FSW_EVENT_CALLBACK *callback, void *context) { fsw_monitor_type type; #if defined(HAVE_FSEVENTS_FILE_EVENTS) type = fsw_monitor_type::fsevents_monitor_type; #elif defined(HAVE_SYS_EVENT_H) type = fsw_monitor_type::kqueue_monitor_type; #elif defined(HAVE_PORT_H) type = fsw_monitor_type::fen_monitor_type; #elif defined(HAVE_SYS_INOTIFY_H) type = fsw_monitor_type::inotify_monitor_type; #elif defined(HAVE_WINDOWS) type = fsw_monitor_type::windows_monitor_type; #else type = fsw_monitor_type::poll_monitor_type; #endif return monitor_factory::create_monitor(type, paths, callback, context); } monitor *monitor_factory::create_monitor(fsw_monitor_type type, vector paths, FSW_EVENT_CALLBACK *callback, void *context) { switch (type) { case system_default_monitor_type: return create_default_monitor(paths, callback, context); default: auto c = creators_by_type().find(type); if (c == creators_by_type().end()) throw libfsw_exception("Unsupported monitor.", FSW_ERR_UNKNOWN_MONITOR_TYPE); return c->second(paths, callback, context); } } #ifdef HAVE_INACTIVITY_CALLBACK void monitor::inactivity_callback(monitor *mon) { if (!mon) throw libfsw_exception(_("Callback argument cannot be null.")); FSW_ELOG(_("Inactivity notification thread: starting\n")); for (;;) { unique_lock run_guard(mon->run_mutex); if (mon->should_stop) break; run_guard.unlock(); milliseconds elapsed = duration_cast(system_clock::now().time_since_epoch()) - mon->last_notification.load(); // Sleep and loop again if sufficient time has not elapsed yet. if (elapsed < mon->get_latency_ms()) { milliseconds to_sleep = mon->get_latency_ms() - elapsed; seconds max_sleep_time(2); std::this_thread::sleep_for(to_sleep > max_sleep_time ? max_sleep_time : to_sleep); continue; } // Build a fake event. time_t curr_time; time(&curr_time); vector events; events.push_back({"", curr_time, {NoOp}}); mon->notify_events(events); } FSW_ELOG(_("Inactivity notification thread: exiting\n")); } #endif void monitor::start() { FSW_MONITOR_RUN_GUARD; if (this->running) return; this->running = true; FSW_MONITOR_RUN_GUARD_UNLOCK; // Fire the inactivity thread std::unique_ptr inactivity_thread; #ifdef HAVE_INACTIVITY_CALLBACK if (fire_idle_event) inactivity_thread.reset(new std::thread(monitor::inactivity_callback, this)); #endif // Fire the monitor run loop. this->run(); // Join the inactivity thread and wait until it stops. FSW_ELOG(_("Inactivity notification thread: joining\n")); if (inactivity_thread) inactivity_thread->join(); FSW_MONITOR_RUN_GUARD_LOCK; this->running = false; this->should_stop = false; FSW_MONITOR_RUN_GUARD_UNLOCK; } void monitor::stop() { // Stopping a monitor is a cooperative task: the caller request a task to // stop and it's responsibility of each monitor to check for this flag and // timely stop the processing loop. FSW_MONITOR_RUN_GUARD; if (!this->running || this->should_stop) return; FSW_ELOG(_("Stopping the monitor.\n")); this->should_stop = true; on_stop(); } bool monitor::is_running() { FSW_MONITOR_RUN_GUARD; return this->running; } vector monitor::filter_flags(const event& evt) const { // If there is nothing to filter, just return the original vector. if (event_type_filters.size() == 0) return evt.get_flags(); vector filtered_flags; for (auto const& flag : evt.get_flags()) { if (accept_event_type(flag)) filtered_flags.push_back(flag); } return filtered_flags; } void monitor::notify_overflow(const string& path) const { if (!allow_overflow) throw libfsw_exception(_("Event queue overflow.")); time_t curr_time; time(&curr_time); notify_events({{path, curr_time, {fsw_event_flag::Overflow}}}); } void monitor::notify_events(const vector& events) const { FSW_MONITOR_NOTIFY_GUARD; // Update the last notification timestamp #ifdef HAVE_INACTIVITY_CALLBACK milliseconds now = duration_cast(system_clock::now().time_since_epoch()); last_notification.store(now); #endif vector filtered_events; for (auto const& event : events) { // Filter flags vector filtered_flags = filter_flags(event); if (filtered_flags.size() == 0) continue; if (!accept_path(event.get_path())) continue; filtered_events.push_back( {event.get_path(), event.get_time(), filtered_flags}); } if (filtered_events.size() > 0) { FSW_ELOG(string_utils::string_from_format(_("Notifying events #: %d.\n"), filtered_events.size()).c_str()); callback(filtered_events, context); } } map& monitor_factory::creators_by_string() { static map creator_by_string_map; return creator_by_string_map; } map& monitor_factory::creators_by_type() { static map creator_by_type_map; return creator_by_type_map; } monitor *monitor_factory::create_monitor(const string& name, vector paths, FSW_EVENT_CALLBACK *callback, void *context) { auto i = creators_by_string().find(name); if (i == creators_by_string().end()) return nullptr; return i->second(paths, callback, context); } bool monitor_factory::exists_type(const string& name) { auto i = creators_by_string().find(name); return (i != creators_by_string().end()); } bool monitor_factory::exists_type(const fsw_monitor_type& type) { auto i = creators_by_type().find(type); return (i != creators_by_type().end()); } void monitor_factory::register_creator(const string& name, FSW_FN_MONITOR_CREATOR creator) { creators_by_string()[name] = creator; } void monitor_factory::register_creator_by_type(const fsw_monitor_type& type, FSW_FN_MONITOR_CREATOR creator) { creators_by_type()[type] = creator; } vector monitor_factory::get_types() { vector types; for (const auto& i : creators_by_string()) { types.push_back(i.first); } return types; } void monitor::on_stop() { // No-op implementation. } } fswatch-1.11.2/libfswatch/src/libfswatch/c++/libfswatch_map.hpp000644 000765 000024 00000003456 13174733730 025004 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Header defining the associative container used by the library. * * @copyright Copyright (c) 2014-2016 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef LIBFSW_MAP_H # define LIBFSW_MAP_H # ifdef HAVE_CONFIG_H # include "libfswatch_config.h" # endif # if defined(HAVE_UNORDERED_MAP) # include namespace fsw { /** * @brief Default associative container type used by `libfswatch`. * * This type definition will be a synonym of `std::unordered_map` if the C++ * library contains it, otherwise it will default to `std::map`. */ template using fsw_hash_map = std::unordered_map; } # else # include namespace fsw { /** * @brief Default associative container type used by `libfswatch`. * * This type definition will be a synonym of `std::unordered_map` if the C++ * library contains it, otherwise it will default to `std::map`. */ template using fsw_hash_map = std::map; } # endif #endif /* LIBFSW_MAP_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/filter.cpp000644 000765 000024 00000010500 13175131667 023267 0ustar00enricostaff000000 000000 /* * Copyright (c) 2016 Enrico M. Crisostomo * * 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, 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 . */ #ifdef HAVE_CONFIG_H # include "libfswatch_config.h" #endif #include "gettext_defs.h" #include "filter.hpp" #include #include #include using namespace std; namespace fsw { static inline bool parse_filter(std::string filter, monitor_filter& filter_object, void (*err_handler)(std::string)); static inline bool is_unescaped_space(string& filter, long i); vector monitor_filter::read_from_file(const string& path, void (*err_handler)( string)) { vector filters; ifstream f(path); if (!f.is_open()) throw invalid_argument(string(_("File not found: ")) + path); string line; monitor_filter filter; while (getline(f, line)) { if (parse_filter(line, filter, err_handler)) { filters.push_back(filter); } } return filters; } bool is_unescaped_space(string& filter, long i) { if (filter[i] != ' ') return false; unsigned int backslashes = 0; while (--i >= 0 && filter[i] == '\\') ++backslashes; return (backslashes % 2 == 0); } bool parse_filter(string filter, monitor_filter& filter_object, void (*err_handler)(string)) { #define handle_error(t) if (err_handler) err_handler(t); // Skip empty strings. if (filter.length() == 0) return false; // Strip comments. if (filter[0] == '#') return false; // Valid filters have the following structure: // type pattern // where type may contains the following characters: // - '+' or '-', to indicate whether the filter is an inclusion or an exclusion filter. // - 'e', for an extended regular expression. // - 'i', for a case insensitive regular expression. regex filter_grammar("^([+-])([ei]*) (.+)$", regex_constants::extended); smatch fragments; if (!regex_match(filter, fragments, filter_grammar)) { handle_error(filter); return false; } // Reset the filter object to its default values. filter_object = {}; filter_object.case_sensitive = true; // Name the fragments string frag_type = fragments[1].str(); string frag_flag = fragments[2].str(); string frag_filter = fragments[3].str(); // Build the filter switch (frag_type[0]) { case '+': filter_object.type = fsw_filter_type::filter_include; break; case '-': filter_object.type = fsw_filter_type::filter_exclude; break; default: throw invalid_argument(string(_("Unknown filter type: ")) + frag_type[0]); } // Parse the flags for (char c : frag_flag) { switch (c) { case 'e': filter_object.extended = true; break; case 'i': filter_object.case_sensitive = false; break; default: throw invalid_argument(string(_("Unknown flag: ")) + c); } } // Parse the filter // Trim unescaped trailing spaces. for (auto i = frag_filter.length() - 1; i > 0; --i) { if (is_unescaped_space(frag_filter, i)) frag_filter.erase(i, 1); else break; } // If a single space is the only character left then the filter is invalid. if (frag_filter.length() == 1 && frag_filter[0] == ' ') { handle_error(filter); return false; } // Ignore empty lines. if (frag_filter.length() == 0) { handle_error(filter); return false; } // Copy filter to output. filter_object.text = frag_filter; return true; } } fswatch-1.11.2/libfswatch/src/libfswatch/c++/windows_monitor.hpp000644 000765 000024 00000004667 13174733730 025267 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2016 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Windows monitor. * * @copyright Copyright (c) 2014-2016 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef FSW_WINDOWS_MONITOR_H # define FSW_WINDOWS_MONITOR_H # include "monitor.hpp" # include # include namespace fsw { /** * @brief Opaque structure containing implementation specific details of the * Windows monitor. */ struct windows_monitor_load; /** * @brief Windows monitor. * * This monitor is built upon the `ReadDirectoryChanges` API of the Windows * operating systems. */ class windows_monitor : public monitor { REGISTER_MONITOR(windows_monitor, windows_monitor_type); public: /** * @brief Constructs an instance of this class. */ windows_monitor(std::vector paths, FSW_EVENT_CALLBACK *callback, void *context = nullptr); /** * @brief Destroys an instance of this class. */ virtual ~windows_monitor(); protected: /** * @brief Executes the monitor loop. * * This call does not return until the monitor is stopped. * * @see stop() */ void run(); private: windows_monitor(const windows_monitor& orig) = delete; windows_monitor& operator=(const windows_monitor& that) = delete; void configure_monitor(); void initialize_windows_path_list(); void initialize_events(); bool init_search_for_path(const std::wstring path); void stop_search_for_path(const std::wstring path); void process_path(const std::wstring& path); bool is_path_watched(std::wstring path); // initial load windows_monitor_load *load; }; } #endif /* FSW_WINDOWS_MONITOR_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/fsevents_monitor.hpp000644 000765 000024 00000004777 13174733730 025434 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2016 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief OS X FSEvents monitor. * * @copyright Copyright (c) 2014-2016 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef FSW_FSEVENT_MONITOR_H # define FSW_FSEVENT_MONITOR_H # include "monitor.hpp" # include namespace fsw { /** * @brief OS X FSEvents monitor. * * This monitor is built upon the _FSEvents_ API of the Apple OS X kernel. */ class fsevents_monitor : public monitor { REGISTER_MONITOR(fsevents_monitor, fsevents_monitor_type); public: /** * @brief Constructs an instance of this class. */ fsevents_monitor(std::vector paths, FSW_EVENT_CALLBACK *callback, void *context = nullptr); /** * @brief Destroys an instance of this class. */ virtual ~fsevents_monitor(); protected: /** * @brief Executes the monitor loop. * * This call does not return until the monitor is stopped. * * @see stop() */ void run() override; /** * @brief Execute an implementation-specific stop handler. */ void on_stop() override; private: fsevents_monitor(const fsevents_monitor& orig) = delete; fsevents_monitor& operator=(const fsevents_monitor& that) = delete; static void fsevents_callback(ConstFSEventStreamRef streamRef, void *clientCallBackInfo, size_t numEvents, void *eventPaths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]); FSEventStreamRef stream = nullptr; CFRunLoopRef run_loop = nullptr; }; } #endif /* FSW_FSEVENT_MONITOR_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/inotify_monitor.cpp000644 000765 000024 00000033224 13174733730 025240 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ #ifdef HAVE_CONFIG_H # include "libfswatch_config.h" #endif #include "gettext_defs.h" #include "inotify_monitor.hpp" #include #include #ifdef __sun # define NAME_MAX 255 /* # chars in a file name */ #endif #include #include #include #include #include #include #include "libfswatch_exception.hpp" #include "../c/libfswatch_log.h" #include "libfswatch_map.hpp" #include "libfswatch_set.hpp" #include "path_utils.hpp" using namespace std; namespace fsw { struct inotify_monitor_impl { int inotify_monitor_handle = -1; vector events; /* * A map of file names by descriptor is kept in sync because the name field * of the inotify_event structure is present only when it identifies a * child of a watched directory. In all the other cases, we store the path * for easy retrieval. */ fsw_hash_set watched_descriptors; fsw_hash_map path_to_wd; /* * Since the inotify API maintains only works with watch * descriptors a cache maintaining a relationship between a watch * descriptor and the path used to get it is required to be able to map an * event to the path it refers to. From man inotify: * * The inotify API identifies events via watch descriptors. It is the * application's responsibility to cache a mapping (if one is needed) * between watch descriptors and pathnames. Be aware that directory * renamings may affect multiple cached pathnames. */ fsw_hash_map wd_to_path; fsw_hash_set descriptors_to_remove; fsw_hash_set watches_to_remove; vector paths_to_rescan; time_t curr_time; }; static const unsigned int BUFFER_SIZE = (10 * ((sizeof(struct inotify_event)) + NAME_MAX + 1)); REGISTER_MONITOR_IMPL(inotify_monitor, inotify_monitor_type); inotify_monitor::inotify_monitor(vector paths_to_monitor, FSW_EVENT_CALLBACK *callback, void *context) : monitor(paths_to_monitor, callback, context), impl(new inotify_monitor_impl()) { impl->inotify_monitor_handle = inotify_init(); if (impl->inotify_monitor_handle == -1) { perror("inotify_init"); throw libfsw_exception(_("Cannot initialize inotify.")); } } inotify_monitor::~inotify_monitor() { // close inotify watchers for (auto inotify_desc_pair : impl->watched_descriptors) { ostringstream log; log << _("Removing: ") << inotify_desc_pair << "\n"; FSW_ELOG(log.str().c_str()); if (inotify_rm_watch(impl->inotify_monitor_handle, inotify_desc_pair)) { perror("inotify_rm_watch"); } } // close inotify if (impl->inotify_monitor_handle > 0) { close(impl->inotify_monitor_handle); } delete impl; } bool inotify_monitor::add_watch(const string& path, const struct stat& fd_stat) { // TODO: Consider optionally adding the IN_EXCL_UNLINK flag. int inotify_desc = inotify_add_watch(impl->inotify_monitor_handle, path.c_str(), IN_ALL_EVENTS); if (inotify_desc == -1) { perror("inotify_add_watch"); } else { impl->watched_descriptors.insert(inotify_desc); impl->wd_to_path[inotify_desc] = path; impl->path_to_wd[path] = inotify_desc; ostringstream log; log << _("Added: ") << path << "\n"; FSW_ELOG(log.str().c_str()); } return (inotify_desc != -1); } void inotify_monitor::scan(const string& path, const bool accept_non_dirs) { struct stat fd_stat; if (!lstat_path(path, fd_stat)) return; if (follow_symlinks && S_ISLNK(fd_stat.st_mode)) { string link_path; if (read_link_path(path, link_path)) scan(link_path, accept_non_dirs); return; } bool is_dir = S_ISDIR(fd_stat.st_mode); /* * When watching a directory the inotify API will return change events of * first-level children. Therefore, we do not need to manually add a watch * for a child unless it is a directory. By default, accept_non_dirs is * true to allow watching a file when first invoked on a node. * * For the same reason, the directory_only flag is ignored and treated as if * it were always set to true. */ if (!accept_non_dirs && !is_dir) return; if (!is_dir && directory_only && !accept_non_dirs) return; if (!is_dir && !accept_path(path)) return; if (!add_watch(path, fd_stat)) return; if (!recursive || !is_dir) return; vector children = get_directory_children(path); for (const string& child : children) { if (child.compare(".") == 0 || child.compare("..") == 0) continue; /* * Scan children but only watch directories. */ scan(path + "/" + child, false); } } bool inotify_monitor::is_watched(const string& path) const { return (impl->path_to_wd.find(path) != impl->path_to_wd.end()); } void inotify_monitor::scan_root_paths() { for (string& path : paths) { if (!is_watched(path)) scan(path); } } void inotify_monitor::preprocess_dir_event(struct inotify_event *event) { vector flags; if (event->mask & IN_ISDIR) flags.push_back(fsw_event_flag::IsDir); if (event->mask & IN_MOVE_SELF) flags.push_back(fsw_event_flag::Updated); if (event->mask & IN_UNMOUNT) flags.push_back(fsw_event_flag::PlatformSpecific); if (flags.size()) { impl->events.push_back({impl->wd_to_path[event->wd], impl->curr_time, flags}); } // If a new directory has been created, it should be rescanned if the if ((event->mask & IN_ISDIR) && (event->mask & IN_CREATE)) { impl->paths_to_rescan.push_back(impl->wd_to_path[event->wd]); } } void inotify_monitor::preprocess_node_event(struct inotify_event *event) { vector flags; if (event->mask & IN_ACCESS) flags.push_back(fsw_event_flag::PlatformSpecific); if (event->mask & IN_ATTRIB) flags.push_back(fsw_event_flag::AttributeModified); if (event->mask & IN_CLOSE_NOWRITE) flags.push_back(fsw_event_flag::PlatformSpecific); if (event->mask & IN_CLOSE_WRITE) flags.push_back(fsw_event_flag::Updated); if (event->mask & IN_CREATE) flags.push_back(fsw_event_flag::Created); if (event->mask & IN_DELETE) flags.push_back(fsw_event_flag::Removed); if (event->mask & IN_MODIFY) flags.push_back(fsw_event_flag::Updated); if (event->mask & IN_MOVED_FROM) { flags.push_back(fsw_event_flag::Removed); flags.push_back(fsw_event_flag::MovedFrom); } if (event->mask & IN_MOVED_TO) { flags.push_back(fsw_event_flag::Created); flags.push_back(fsw_event_flag::MovedTo); } if (event->mask & IN_OPEN) flags.push_back(fsw_event_flag::PlatformSpecific); // Build the file name. ostringstream filename_stream; filename_stream << impl->wd_to_path[event->wd]; if (event->len > 1) { filename_stream << "/"; filename_stream << event->name; } if (flags.size()) { impl->events.push_back({filename_stream.str(), impl->curr_time, flags}); } { ostringstream log; log << _("Generic event: ") << event->wd << "::" << filename_stream.str() << "\n"; FSW_ELOG(log.str().c_str()); } /* * inotify automatically removes the watch of a watched item that has been * removed and posts an IN_IGNORED event after an IN_DELETE_SELF. */ if (event->mask & IN_IGNORED) { ostringstream log; log << "IN_IGNORED: " << event->wd << "::" << filename_stream.str() << "\n"; FSW_ELOG(log.str().c_str()); impl->descriptors_to_remove.insert(event->wd); } /* * inotify sends an IN_MOVE_SELF event when a watched object is moved into * the same filesystem and keeps watching it. Since its path has changed, * we remove the watch so that recreation is attempted at the next * iteration. * * Beware that a race condition exists which may result in events go * unnoticed when a watched file x is removed and a new file named x is * created thereafter. In this case, fswatch could be blocked on read and * it would not have any chance to create a new watch descriptor for x until * an event is received and read unblocks. */ if (event->mask & IN_MOVE_SELF) { ostringstream log; log << "IN_MOVE_SELF: " << event->wd << "::" << filename_stream.str() << "\n"; FSW_ELOG(log.str().c_str()); impl->watches_to_remove.insert(event->wd); impl->descriptors_to_remove.insert(event->wd); } /* * An file could be moved to a path which is being observed. The clobbered * file is handled by the corresponding IN_DELETE_SELF event. */ /* * inotify automatically removes the watch of the object the IN_DELETE_SELF * event is related to. */ if (event->mask & IN_DELETE_SELF) { ostringstream log; log << "IN_DELETE_SELF: " << event->wd << "::" << filename_stream.str() << "\n"; FSW_ELOG(log.str().c_str()); impl->descriptors_to_remove.insert(event->wd); } } void inotify_monitor::preprocess_event(struct inotify_event *event) { if (event->mask & IN_Q_OVERFLOW) { notify_overflow(impl->wd_to_path[event->wd]); } preprocess_dir_event(event); preprocess_node_event(event); } void inotify_monitor::remove_watch(int wd) { /* * No need to remove the inotify watch because it is removed automatically * when a watched element is deleted. */ impl->wd_to_path.erase(wd); } void inotify_monitor::process_pending_events() { // Remove watches. auto wtd = impl->watches_to_remove.begin(); while (wtd != impl->watches_to_remove.end()) { if (inotify_rm_watch(impl->inotify_monitor_handle, *wtd) != 0) { perror("inotify_rm_watch"); } else { ostringstream log; log << _("Removed: ") << *wtd << "\n"; FSW_ELOG(log.str().c_str()); } impl->watches_to_remove.erase(wtd++); } // Clean up descriptors. auto fd = impl->descriptors_to_remove.begin(); while (fd != impl->descriptors_to_remove.end()) { const string& curr_path = impl->wd_to_path[*fd]; impl->path_to_wd.erase(curr_path); impl->wd_to_path.erase(*fd); impl->watched_descriptors.erase(*fd); impl->descriptors_to_remove.erase(fd++); } // Process paths to be rescanned std::for_each(impl->paths_to_rescan.begin(), impl->paths_to_rescan.end(), [this] (const string& p) { this->scan(p); } ); impl->paths_to_rescan.clear(); } void inotify_monitor::run() { char buffer[BUFFER_SIZE]; double sec; double frac = modf(this->latency, &sec); for(;;) { #ifdef HAVE_CXX_MUTEX unique_lock run_guard(run_mutex); if (should_stop) break; run_guard.unlock(); #endif process_pending_events(); scan_root_paths(); // If no files can be watched, sleep and repeat the loop. if (!impl->watched_descriptors.size()) { sleep(latency); continue; } // Use select to timeout on file descriptor read the amount specified by // the monitor latency. This way, the monitor has a chance to update its // watches with at least the periodicity expected by the user. fd_set set; struct timeval timeout; FD_ZERO(&set); FD_SET(impl->inotify_monitor_handle, &set); timeout.tv_sec = sec; timeout.tv_usec = 1000 * 1000 * frac; int rv = select(impl->inotify_monitor_handle + 1, &set, nullptr, nullptr, &timeout); if (rv == -1) { fsw_log_perror("select"); continue; } // In case of read timeout just repeat the loop. if (rv == 0) continue; ssize_t record_num = read(impl->inotify_monitor_handle, buffer, BUFFER_SIZE); { ostringstream log; log << _("Number of records: ") << record_num << "\n"; FSW_ELOG(log.str().c_str()); } if (!record_num) { throw libfsw_exception(_("read() on inotify descriptor read 0 records.")); } if (record_num == -1) { perror("read()"); throw libfsw_exception(_("read() on inotify descriptor returned -1.")); } time(&impl->curr_time); for (char *p = buffer; p < buffer + record_num;) { struct inotify_event *event = reinterpret_cast (p); preprocess_event(event); p += (sizeof(struct inotify_event)) + event->len; } if (impl->events.size()) { notify_events(impl->events); impl->events.clear(); } sleep(latency); } } } fswatch-1.11.2/libfswatch/src/libfswatch/c++/monitor.hpp000644 000765 000024 00000066117 13174733730 023513 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Header of the fsw::monitor class. * * This header file defines the fsw::monitor class, the base type of a * `libfswatch` monitor and fundamental type of the C++ API. * * If `HAVE_CXX_MUTEX` is defined, this header includes ``. * * @copyright Copyright (c) 2014-2015 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef FSW__MONITOR_H # define FSW__MONITOR_H # include "filter.hpp" # include # include # ifdef HAVE_CXX_MUTEX # include # endif # include # include # include # include "event.hpp" # include "../c/cmonitor.h" /** * @brief Main namespace of `libfswatch`. */ namespace fsw { /** * @brief Function definition of an event callback. * * The event callback is a user-supplied function that is invoked by the * monitor when an event is detected. The following parameters are passed to * the callback: * * * A reference to the vector of events. * * A pointer to the _context data_ set by the caller. */ typedef void FSW_EVENT_CALLBACK(const std::vector&, void *); struct compiled_monitor_filter; /** * @brief Base class of all monitors. * * The fsw::monitor class is the base class of all monitors. This class * encapsulates the common functionality of a monitor: * * - Accessors to configuration parameters. * - start() and stop() lifecycle. * - Event filtering. * - Event notification to user-provided callback function. * * Since some methods are designed to be called from different threads, this * class provides an internal mutex (monitor::run_mutex) that implementors * should lock on when accessing shared state. The mutex is available only * when `HAVE_CXX_MUTEX` is defined. * * At least the following tasks must be performed to implement a monitor: * * - Providing an implementation of the run() method. * - Providing an implementation of the on_stop() method if the * monitor cannot be stopped cooperatively from the run() method. * * A basic monitor needs to implement the run() method, whose skeleton is * often similar to the following: * * void run() * { * initialize_api(); * * for (;;) * { * #ifdef HAVE_CXX_MUTEX * unique_lock run_guard(run_mutex); * if (should_stop) break; * run_guard.unlock(); * #endif * * scan_paths(); * wait_for_events(); * * vector evts = get_changes(); * vector events; * * for (auto & evt : evts) * { * if (accept(evt.get_path)) * { * events.push_back({event from evt}); * } * } * * if (events.size()) notify_events(events); * } * * terminate_api(); * } * * Despite being a minimal implementation, it performs all the tasks commonly * performed by a monitor: * * - It initializes the API it uses to detect file system change events. * * - It enters a loop, often infinite, where change events are waited for. * * - If `HAVE_CXX_MUTEX` is defined, it locks on monitor::run_mutex to * check whether monitor::should_stop is set to @c true. If it is, the * monitor breaks the loop to return from run() as soon as possible. * * - It scans the paths that must be observed: this step might be necessary * for example because some path may not have existed during the previous * iteration of the loop, or because some API may require the user to * re-register a watch on a path after events are retrieved. * * - Events are waited for and the wait should respect the specified * _latency_. * * - Events are _filtered_ to exclude those referring to paths that do not * satisfy the configured filters. * * - The notify_events() method is called to filter the event types and * notify the caller. */ class monitor { public: /** * @brief Constructs a monitor watching the specified @p paths. * * The monitor will notify change events to the specified @p callback, * passing it the pointer to the specified @p context. * * @param paths The list of paths to watch. * @param callback The callback to which change events will be notified. * The callback cannot be null, otherwise a libfsw_exception * will be thrown. * @param context An optional pointer to context data. The monitor stores a * copy of this pointer to pass it to the @p callback. */ monitor(std::vector paths, FSW_EVENT_CALLBACK *callback, void *context = nullptr); /** * @brief Destructs a monitor instance. * * This destructor performs the following operations: * * - Stops the monitor. * * - Frees the compiled regular expression of the path filters, if any. * * @warning Destroying a monitor in the _running_ state results in undefined * behaviour. * * @see stop() */ virtual ~monitor(); /** * @brief This class is not copy constructible. */ monitor(const monitor& orig) = delete; /** * @brief This class is not copy assignable. */ monitor& operator=(const monitor& that) = delete; /** * @brief Sets a custom property. * * This method sets the custom property @p name to @p value. * * @param name The name of the property. * @param value The value of the property. */ void set_property(const std::string& name, const std::string& value); /** * @brief Sets the custom properties. * * This method _replaces_ all the existing properties using the pairs * contained into @p options. * * @param options The map containing the properties to set. */ void set_properties(const std::map options); /** * @brief Gets the value of a property. * * This method gets the value of the property @p name. If the property * @p name is not set, this method returns an empty string. * * @param name The name of the property. * @return The value of the property. */ std::string get_property(std::string name); /** * @brief Sets the latency. * * This method sets the _latency_ of the monitor to @p latency. The latency * is a positive number that indicates to a monitor implementation how often * events must be retrieved or waited for: the shortest the latency, the * quicker events are processed. * * @warning The behaviour associated with this flag depends on the * implementation. * * @param latency The latency value. */ void set_latency(double latency); /** * @brief Sets the _fire idle event_ flag. * * When @c true, the _fire idle event_ flag instructs the monitor to fire a * fake event at the event of an _idle_ cycle. An idle cycle is a period of * time whose length is 110% of the monitor::latency where no change events * were detected. * * @param fire_idle_event @c true if idle events should be fired, @c false * otherwise. */ void set_fire_idle_event(bool fire_idle_event); /** * @brief Notify buffer overflows as change events. * * If this flag is set, the monitor will report a monitor buffer overflow as * a change event of type fsw_event_flag::Overflow. * * @warning The behaviour associated with this flag depends on the * implementation. * * @param overflow @c true if overflow should be notified, @c false * otherwise. */ void set_allow_overflow(bool overflow); /** * @brief Recursively scan subdirectories. * * This function sets the recursive flag of the monitor to indicate whether * the monitor should recursively observe the contents of directories. The * behaviour associated with this flag is an implementation-specific detail. * This class only stores the value of the flag. * * @warning The behaviour associated with this flag depends on the * implementation. * * @param recursive @c true if directories should be recursively, @c false * otherwise. */ void set_recursive(bool recursive); /** * @brief Watch directories only. * * This function sets the directory only flag to the specified value. If * this flag is set, then the monitor will only watch directories during a * recursive scan. This functionality is only supported by monitors whose * backend fires change events on a directory when one its children is * changed. If a monitor backend does not support this functionality, the * flag is ignored. * * @warning The behaviour associated with this flag depends on the * implementation. * * @param directory_only @c true if only directories should be watched, * @c flase otherwise. */ void set_directory_only(bool directory_only); /** * @brief Add a path filter. * * This function adds a monitor_filter instance instance to the filter list. * * @param filter The filter to add. */ void add_filter(const monitor_filter& filter); /** * @brief Set the path filters. * * This function sets the list of path filters, substituting existing * filters if any. * * @param filters The filters to set. */ void set_filters(const std::vector& filters); /** * @brief Follow symlinks. * * This function sets the follow_symlinks flag of the monitor to indicate * whether the monitor should follow symbolic links or observe the links * themselves. * * @warning The behaviour associated with this flag depends on the * implementation. * * @param follow @c true if symbolic links should be followed, @c false * otherwise. */ void set_follow_symlinks(bool follow); /** * @brief Get the pointer to the context data. * * This function gets the pointer to the context data that is passed to the * callback by the monitor. * * @return The pointer to the context data. */ void *get_context() const; /** * @brief Set the context data. * * This function sets the pointer to the _context data_. The context data * is opaque data that the monitor passes to the event callback. * * @warning The monitor stores the pointer to the context data throughout * its life. The caller must ensure it points to valid data until the * monitor is running. * * @param context The pointer to the context data. */ void set_context(void *context); /** * @brief Start the monitor. * * The monitor status is marked as _running_ and it starts watching for * change events. This function performs the following tasks: * * * Atomically marks the thread state as _running_, locking on * monitor::run_mutex. * * Calls the run() function: the monitor::run_mutex is **not** locked * during this call. * * When run() returns, it atomically marks the thread state as * _stopped_, locking on monitor::run_mutex. * * This call does _not_ return until the monitor is stopped and events are * notified from its thread. * * State changes are performed thread-safely locking on monitor::run_mutex. * * @see run() * @see stop() */ void start(); /** * @brief Stop the monitor. * * This function asks the monitor to stop. Since start() is designed to * execute the monitoring loop in its thread and to not return until the * monitor is stopped, stop() is designed to be called from another thread. * stop() is a cooperative signal that must be handled in an * implementation-specific way in the run() function. * * State changes are performed thread-safely locking on monitor::run_mutex. * * @see run() * @see start() */ void stop(); /** * @brief Check whether the monitor is running. * * State is checked thread-safely locking on monitor::run_mutex. * * @return @c true if the monitor is running, @c false otherwise. */ bool is_running(); /** * @brief Add an event type filter. * * Adds a fsw_event_type_filter instance to filter events by _type_. * * @param filter The event type filter to add. */ void add_event_type_filter(const fsw_event_type_filter& filter); /** * @brief Set the event type filters. * * This function sets the list of event type filters, substituting existing * filters if any. * * @param filters The filters to set. */ void set_event_type_filters( const std::vector& filters); /** * @brief Monitor file access. * * @warning The ability of monitoring file access depends on a monitor * implementation. */ void set_watch_access(bool access); protected: /** * @brief Check whether an event should be accepted. * * This function checks @p event_type against the event type filters of the * monitor to determine whether it should be _accepted_. * * @param event_type The event type to check. * @return @c true if the event is accepted, @c false otherwise. */ bool accept_event_type(fsw_event_flag event_type) const; /** * @brief Check whether a path should be accepted. * * This function checks @p path against the path filters of the monitor to * determine whether it should be _accepted_. * * @param event_type The path to check. * @return @c true if the path is accepted, @c false otherwise. */ bool accept_path(const std::string& path) const; /** * @brief Check whether a path should be accepted. * * This function checks @p path against the path filters of the monitor to * determine whether it should be _accepted_. * * @param event_type The path to check. * @return @c true if the path is accepted, @c false otherwise. */ bool accept_path(const char *path) const; /** * @brief Notify change events. * * This function notifies change events using the provided callback. * * @see monitor() */ void notify_events(const std::vector& events) const; /** * @brief Notify an overflow event. * * This function notifies an overflow event using the provided callback. * * @warning Experiencing an overflow and the ability to notify it is an * implementation-defined behaviour. * * @see monitor() */ void notify_overflow(const std::string& path) const; /** * @brief Filter event types. * * This function filters the event types of an event leaving only the types * allowed by the configured filters. * * @param evt The event whose types must be filtered. * @return A vector containing the acceptable events. */ std::vector filter_flags(const event& evt) const; /** * @brief Execute monitor loop. * * This function implements the monitor event watching logic. This function * is called from start() and it is executed on its thread. This function * should _block_ until the monitoring loop terminates: when it returns, the * monitor is marked as stopped. * * This function should cooperatively check the monitor::should_stop field * locking monitor::run_mutex and return if set to @c true. * * @see start() * @see stop() */ virtual void run() = 0; /** * @brief Execute an implementation-specific stop handler. * * This function is executed by the stop() method, after requesting the * monitor to stop. This handler is required if the thread running run() is * not able to preemptively stop its execution by checking the * monitor::should_stop flag. * * @see stop() */ virtual void on_stop(); protected: /** * @brief List of paths to watch. * * @see monitor::monitor() */ std::vector paths; /** * @brief Map of custom properties. * * @see monitor::set_property() * @see monitor::set_properties() */ std::map properties; /** * @brief Callback to which change events should be notified. * * @see monitor::monitor() */ FSW_EVENT_CALLBACK *callback; /** * @brief Pointer to context data that will be passed to the monitor::callback. */ void *context = nullptr; /** * @brief Latency of the monitor. */ double latency = 1.0; /** * @brief If @c true, the monitor will notify an event when idle. * * An idle cycle is long as 110% of the monitor::latency value. */ bool fire_idle_event = false; /** * @brief If @c true, queue overflow events will be notified to the caller, * otherwise the monitor will throw a libfsw_exception. */ bool allow_overflow = false; /** * @brief If @c true, directories will be scanned recursively. */ bool recursive = false; /** * @brief If @c true, symbolic links are followed. */ bool follow_symlinks = false; /** * @brief Flag indicating whether only directories should be monitored. */ bool directory_only = false; /** * @brief Flag indicating whether file access should be watched. */ bool watch_access = false; /** * @brief Flag indicating whether the monitor is in the running state. */ bool running = false; /** * @brief Flag indicating whether the monitor should preemptively stop. */ bool should_stop = false; # ifdef HAVE_CXX_MUTEX /** * @brief Mutex used to serialize access to the monitor state from multiple * threads. */ mutable std::mutex run_mutex; /** * @brief Mutex used to serialize access to the notify_events() method. */ mutable std::mutex notify_mutex; # endif private: std::chrono::milliseconds get_latency_ms() const; std::vector filters; std::vector event_type_filters; #ifdef HAVE_CXX_MUTEX # ifdef HAVE_CXX_ATOMIC # define HAVE_INACTIVITY_CALLBACK static void inactivity_callback(monitor *mon); mutable std::atomic last_notification; # endif #endif }; typedef monitor *(*FSW_FN_MONITOR_CREATOR)(std::vector paths, FSW_EVENT_CALLBACK *callback, void *context); /** * @brief Object factory class for fsw::monitor instances. * * Since multiple monitor implementations exist and the caller potentially * ignores which monitors will be available at run time, there must exist a * way to query the API for the list of available monitor and request a * particular instance. The fsw::monitor_factory is an object factory class * that provides basic monitor _registration_ and _discovery_ functionality: * API clients can query the monitor registry to get a list of available * monitors and get an instance of a monitor either by _type_ or by _name_. * * In order for monitor types to be visible to the factory they have to be * _registered_. Currently, monitor implementations can be registered using * the register_creator() and register_creator_by_type(), or using: * * * The fsw::monitor_registrant helper class. * * The ::REGISTER_MONITOR macro. * * The ::REGISTER_MONITOR_IMPL macro. * * The same monitor type cannot be used to register multiple monitor * implementations. No checks are in place to detect this situation and the * registration will succeed; however, the registration process of multiple * monitor implementations for the same monitor type is _not_ deterministic. */ class monitor_factory { public: /** * @brief Creates a monitor of the specified @p type. * * The other parameters are forwarded to the fsw::monitor() constructor. * * @param type The monitor type. * @param paths The paths to watch. * @param callback The callback to invoke during the notification of a * change event. * @return The newly created monitor. * @throw libfsw_exception if a monitor of the specified @p type cannot be * found. * @see fsw::monitor() */ static monitor *create_monitor(fsw_monitor_type type, std::vector paths, FSW_EVENT_CALLBACK *callback, void *context = nullptr); /** * @brief Creates a monitor whose type is the specified by @p name. * * The other parameters are forwarded to the fsw::monitor() constructor. * * @param name The monitor type. * @param paths The paths to watch. * @param callback The callback to invoke during the notification of a * change event. * @return The newly created monitor. * @throw libfsw_exception if a monitor of the type specified by @p name * cannot be found. * @see fsw::monitor() */ static monitor *create_monitor(const std::string& name, std::vector paths, FSW_EVENT_CALLBACK *callback, void *context = nullptr); /** * @brief Get the available monitor types. * * @return A vector with the available monitor types. */ static std::vector get_types(); /** * @brief Checks whether a monitor of the type specified by @p name exists. * * @return `true` if @p name specifies a valid monitor type, `false` * otherwise. * * @param name The name of the monitor type to look for. * @return `true` if the type @p name exists, `false` otherwise. */ static bool exists_type(const std::string& name); /** * @brief Checks whether a monitor of the type specified @p type. * * @param type The type of the monitor to look for. * @return `true` if @p name specifies a valid monitor type, `false` * otherwise. */ static bool exists_type(const fsw_monitor_type& type); /** * @brief Registers a @p creator for the specified monitor type @p name. * * @param name The name of the monitor type. * @param creator The monitor creator function. */ static void register_creator(const std::string& name, FSW_FN_MONITOR_CREATOR creator); /** * @brief Registers a @p creator for the specified monitor @p type. * * @param type The monitor type. * @param creator The monitor creator function. */ static void register_creator_by_type(const fsw_monitor_type& type, FSW_FN_MONITOR_CREATOR creator); monitor_factory() = delete; monitor_factory(const monitor_factory& orig) = delete; monitor_factory& operator=(const monitor_factory& that) = delete; private: static std::map& creators_by_string(); static std::map& creators_by_type(); }; /** * @brief Helper class to register monitor factories. * * The constructor of this class perform the registration of the given * (name, type) pair in the monitor_factory registry. This class is used by * the REGISTER_MONITOR and REGISTER_MONITOR_IMPL macros. * * @see fsw::monitor_factory */ template class monitor_registrant { public: /** * @brief Constructs a monitor registrant for the specified @p type. * * @param name The name of the type whose factory is being registered. * @param type The type whose factory is being registered. */ monitor_registrant(const std::string& name, const fsw_monitor_type& type) { FSW_FN_MONITOR_CREATOR default_creator = [](std::vector paths, FSW_EVENT_CALLBACK *callback, void *context = nullptr) -> monitor * { return new M(paths, callback, context); }; monitor_factory::register_creator(name, default_creator); monitor_factory::register_creator_by_type(type, default_creator); } }; /** * This macro is used to simplify the registration process of a monitor * type. Since registration of a monitor type is usually performed once, a * static private instance monitor_factory_registrant of the * monitor_registrant class is declared by this macro in the enclosing class. * * Beware that since this macro adds a private qualifier, every field * declared after it must be correctly qualified. * * The use of the REGISTER_MONITOR macro in a class * must always be matched by a corresponding use of the REGISTER_MONITOR_IMPL * macro in the class definition. * * To register class my_monitor with type my_type, * use the REGISTER_MONITOR macro as in the following example: * * [my_class.h] * class my_monitor * { * REGISTER_MONITOR(my_monitor, my_monitor_type); * ... * }; * */ # define REGISTER_MONITOR(classname, monitor_type) \ private: \ static const monitor_registrant monitor_factory_registrant; /** * This macro is used to simplify the registration process of a monitor * type. Since registration of a monitor type is usually performed once, a * static private instance monitor_factory_registrant of the * monitor_registrant class is defined in the monitor class specified by * classname. * * A invocation of the REGISTER_MONITOR_IMPL macro must always be matched by * an invocation of the REGISTER_MONITOR macro in the class declaration. * * To register class my_monitor with type my_type, * use the REGISTER_MONITOR macro as in the following example: * * [my_class.cpp] * * REGISTER_MONITOR_IMPL(my_monitor, my_monitor_type); */ # define REGISTER_MONITOR_IMPL(classname, monitor_type) \ const monitor_registrant classname::monitor_factory_registrant(#classname, monitor_type); } #endif /* FSW__MONITOR_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/libfswatch_set.hpp000644 000765 000024 00000003347 13174733730 025021 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Header defining the default set type used by the library. * * @copyright Copyright (c) 2014-2016 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef LIBFSW_SET_H # define LIBFSW_SET_H # ifdef HAVE_CONFIG_H # include "libfswatch_config.h" # endif # if defined(HAVE_UNORDERED_SET) # include namespace fsw { /** * @brief Default set type used by `libfswatch`. * * This type definition will be a synonym of `std::unordered_set` if the C++ * library contains it, otherwise it will default to `std::set`. */ template using fsw_hash_set = std::unordered_set; } # else # include namespace fsw { /** * @brief Default set type used by `libfswatch`. * * This type definition will be a synonym of `std::unordered_set` if the C++ * library contains it, otherwise it will default to `std::set`. */ template using fsw_hash_set = std::set; } # endif #endif /* LIBFSW_SET_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/filter.hpp000644 000765 000024 00000010027 13174733730 023276 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Header of the fsw::monitor_filter class. * * This header file defines the fsw::monitor_filter class, a type that * represents a path filter. * * @copyright Copyright (c) 2014-2015 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef FSW__FILTER_H # define FSW__FILTER_H # include # include "../c/cfilter.h" # include namespace fsw { /** * @brief Path filters used to accept or reject file change events. * * A path filter is a regular expression used to accept or reject file change * events based on the value of their path. A filter has the following * characteristics: * * - It has a _regular expression_ (monitor_filter::text), used to match the * paths. * * - It can be an _inclusion_ or an _exclusion_ filter * (monitor_filter::type). * * - It can be case _sensitive_ or _insensitive_ * (monitor_filter::case_sensitive). * * - It can be an _extended_ regular expression (monitor_filter::extended). * * Further information about how filtering works in `libfswatch` can be found * in @ref path-filtering. */ typedef struct monitor_filter { /** * @brief Regular expression used to match the paths. * * Further information about regular expressions can be found here: * * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html */ std::string text; /** * @brief Filter type. */ fsw_filter_type type; /** * @brief Flag indicating whether monitor_filter::text is a case sensitive * regular expression. */ bool case_sensitive; /** * @brief Flag indicating whether monitor_filter::text is an extended * regular expression. * * Further information about extended regular expressions can be found here: * * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04 */ bool extended; /** * @brief Load filters from the specified file. * * Filters can be loaded from a text file containing one filter per line. * A filter has the following structure: * * - It is validated by the following regular expression: * `^([+-])([ei]*) (.+)$` * * - The first character is the filter type: `+` if it is an _inclusion_ * filter, `-` if it is an _exclusion_ filter. * * - An optional list of flags: * * - `e` if it is an _extended_ regular expression. * * - `i` if it is a _case insensitive_ regular expression. * * - A space. * * - The filter regular expression text. * * Parsing errors are notified through an optional error handler. The valid * filters are returned in a vector. * * @param path The path of the file to read filters from. * @param err_handler An optional error handler. * @return A vector containing the valid filters. * @throw invalid_argument If the specified path cannot be opened. */ static std::vector read_from_file(const std::string& path, void (*err_handler)( std::string) = nullptr); } monitor_filter; } #endif /* FSW__FILTER_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/windows_monitor.cpp000644 000765 000024 00000015526 13174733730 025256 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ #ifdef HAVE_CONFIG_H # include "libfswatch_config.h" #endif #ifdef HAVE_WINDOWS # include "gettext_defs.h" # include "windows_monitor.hpp" # include "libfswatch_map.hpp" # include "libfswatch_set.hpp" # include "libfswatch_exception.hpp" # include "../c/libfswatch_log.h" # include # include # include # include # include # include # include # include # include # include # include # include # include "./windows/win_handle.hpp" # include "./windows/win_error_message.hpp" # include "./windows/win_strings.hpp" # include "./windows/win_paths.hpp" # include "./windows/win_directory_change_event.hpp" using namespace std; namespace fsw { REGISTER_MONITOR_IMPL(windows_monitor, windows_monitor_type); struct windows_monitor_load { fsw_hash_set win_paths; fsw_hash_map dce_by_path; fsw_hash_map event_by_path; long buffer_size = 128; }; windows_monitor::windows_monitor(vector paths_to_monitor, FSW_EVENT_CALLBACK * callback, void * context) : monitor(paths_to_monitor, callback, context), load(new windows_monitor_load()) { SetConsoleOutputCP(CP_UTF8); } windows_monitor::~windows_monitor() { delete load; } void windows_monitor::initialize_windows_path_list() { for (const auto & path : paths) { load->win_paths.insert(win_paths::posix_to_win_w(path)); } } void windows_monitor::initialize_events() { for (const wstring & path : load->win_paths) { FSW_ELOGF(_("Creating event for %s.\n"), win_strings::wstring_to_string(path).c_str()); HANDLE h = CreateEvent(nullptr, TRUE, FALSE, nullptr); if (h == NULL) throw libfsw_exception(_("CreateEvent failed.")); FSW_ELOGF(_("Event %d created for %s.\n"), h, win_strings::wstring_to_string(path).c_str()); load->event_by_path.emplace(path, h); } } bool windows_monitor::init_search_for_path(const wstring path) { FSW_ELOGF(_("Initializing search structures for %s.\n"), win_strings::wstring_to_string(path).c_str()); HANDLE h = CreateFileW(path.c_str(), GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, nullptr); if (!win_handle::is_valid(h)) { fprintf(stderr, _("Invalid handle when opening %s.\n"), win_strings::wstring_to_string(path).c_str()); return false; } FSW_ELOGF(_("Open file handle: %d.\n"), h); directory_change_event dce(load->buffer_size); dce.path = path; dce.handle = h; dce.overlapped.get()->hEvent = load->event_by_path[path]; if (!dce.read_changes_async()) { FSW_ELOGF("ReadDirectoryChangesW: %s\n", win_strings::wstring_to_string(win_error_message::current()).c_str()); return false; } load->dce_by_path[path] = move(dce); return true; } void windows_monitor::stop_search_for_path(const wstring path) { load->dce_by_path.erase(path); } bool windows_monitor::is_path_watched(wstring path) { return (load->dce_by_path.find(path) != load->dce_by_path.end()); } void windows_monitor::process_path(const wstring & path) { FSW_ELOGF(_("Processing %s.\n"), win_strings::wstring_to_string(path).c_str()); // If the path is not currently watched, then initialize the search // structures. If the initalization fails, skip the path altogether // until the next iteration. if (!is_path_watched(path)) { if (!init_search_for_path(path)) return; } auto it = load->dce_by_path.find(path); if (it == load->dce_by_path.end()) throw libfsw_exception(_("Initialization failed.")); directory_change_event & dce = it->second; if (!dce.try_read()) { if (dce.is_io_incomplete()) { FSW_ELOG(_("I/O incomplete.\n")); return; } if (dce.is_buffer_overflowed()) { notify_overflow(win_paths::win_w_to_posix(path)); } stop_search_for_path(path); return; } FSW_ELOGF(_("GetOverlappedResult returned %d bytes\n"), dce.bytes_returned); if (dce.bytes_returned == 0) { notify_overflow(win_paths::win_w_to_posix(path)); } else { vector events = dce.get_events(); if (events.size()) notify_events(events); } if (!dce.read_changes_async()) { FSW_ELOGF(_("ReadDirectoryChangesW: %s\n"), win_strings::wstring_to_string(win_error_message::current()).c_str()); stop_search_for_path(path); } } void windows_monitor::configure_monitor() { string buffer_size_value = get_property("windows.ReadDirectoryChangesW.buffer.size"); if (buffer_size_value.empty()) return; long parsed_value = strtol(buffer_size_value.c_str(), nullptr, 0); if (parsed_value <= 0) { string msg = string(_("Invalid value: ")) + buffer_size_value; throw libfsw_exception(msg.c_str()); } load->buffer_size = parsed_value; } void windows_monitor::run() { // Since the file handles are open with FILE_SHARE_DELETE, it may happen // that file is deleted when a handle to it is being used. A call to // either ReadDirectoryChangesW or GetOverlappedResult will return with // an error if the file system object being observed is deleted. // Unfortunately, the error reported by Windows is `Access denied', // preventing fswatch to report better messages to the user. configure_monitor(); initialize_windows_path_list(); initialize_events(); for (;;) { #ifdef HAVE_CXX_MUTEX unique_lock run_guard(run_mutex); if (should_stop) break; run_guard.unlock(); #endif sleep(latency); for (const auto & path : load->win_paths) { process_path(path); } } } } #endif /* HAVE_WINDOWS */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/string/000755 000765 000024 00000000000 13175374110 022600 5ustar00enricostaff000000 000000 fswatch-1.11.2/libfswatch/src/libfswatch/c++/event.cpp000644 000765 000024 00000006504 13175131667 023134 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ #include "gettext_defs.h" #include "event.hpp" #include "libfswatch_exception.hpp" #include using namespace std; namespace fsw { event::event(string path, time_t evt_time, vector flags) : path(std::move(path)), evt_time(evt_time), evt_flags(std::move(flags)) { } event::~event() { } string event::get_path() const { return path; } time_t event::get_time() const { return evt_time; } vector event::get_flags() const { return evt_flags; } fsw_event_flag event::get_event_flag_by_name(const string& name) { #define FSW_MAKE_PAIR_FROM_NAME(p) {#p, p} static const map flag_by_names = { FSW_MAKE_PAIR_FROM_NAME(NoOp), FSW_MAKE_PAIR_FROM_NAME(PlatformSpecific), FSW_MAKE_PAIR_FROM_NAME(Created), FSW_MAKE_PAIR_FROM_NAME(Updated), FSW_MAKE_PAIR_FROM_NAME(Removed), FSW_MAKE_PAIR_FROM_NAME(Renamed), FSW_MAKE_PAIR_FROM_NAME(OwnerModified), FSW_MAKE_PAIR_FROM_NAME(AttributeModified), FSW_MAKE_PAIR_FROM_NAME(MovedFrom), FSW_MAKE_PAIR_FROM_NAME(MovedTo), FSW_MAKE_PAIR_FROM_NAME(IsFile), FSW_MAKE_PAIR_FROM_NAME(IsDir), FSW_MAKE_PAIR_FROM_NAME(IsSymLink), FSW_MAKE_PAIR_FROM_NAME(Link), FSW_MAKE_PAIR_FROM_NAME(Overflow) }; #undef FSW_MAKE_PAIR_FROM_NAME auto flag = flag_by_names.find(name); if (flag == flag_by_names.end()) throw libfsw_exception(_("Unknown event type: ") + name, FSW_ERR_UNKNOWN_VALUE); return flag->second; } string event::get_event_flag_name(const fsw_event_flag& flag) { #define FSW_MAKE_PAIR_FROM_NAME(p) {p, #p} static const map names_by_flag = { FSW_MAKE_PAIR_FROM_NAME(NoOp), FSW_MAKE_PAIR_FROM_NAME(PlatformSpecific), FSW_MAKE_PAIR_FROM_NAME(Created), FSW_MAKE_PAIR_FROM_NAME(Updated), FSW_MAKE_PAIR_FROM_NAME(Removed), FSW_MAKE_PAIR_FROM_NAME(Renamed), FSW_MAKE_PAIR_FROM_NAME(OwnerModified), FSW_MAKE_PAIR_FROM_NAME(AttributeModified), FSW_MAKE_PAIR_FROM_NAME(MovedFrom), FSW_MAKE_PAIR_FROM_NAME(MovedTo), FSW_MAKE_PAIR_FROM_NAME(IsFile), FSW_MAKE_PAIR_FROM_NAME(IsDir), FSW_MAKE_PAIR_FROM_NAME(IsSymLink), FSW_MAKE_PAIR_FROM_NAME(Link), FSW_MAKE_PAIR_FROM_NAME(Overflow) }; #undef FSW_MAKE_PAIR_FROM_NAME auto name = names_by_flag.find(flag); if (name == names_by_flag.end()) throw libfsw_exception(_("Unknown event type."), FSW_ERR_UNKNOWN_VALUE); return name->second; } ostream& operator<<(ostream& out, const fsw_event_flag flag) { return out << event::get_event_flag_name(flag); } } fswatch-1.11.2/libfswatch/src/libfswatch/c++/poll_monitor.cpp000644 000765 000024 00000012660 13174733730 024526 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ #ifdef HAVE_CONFIG_H # include "libfswatch_config.h" #endif #include "gettext_defs.h" #include "poll_monitor.hpp" #include #include #include #include #include "c/libfswatch_log.h" #include "path_utils.hpp" #include "libfswatch_map.hpp" using namespace std; #if defined HAVE_STRUCT_STAT_ST_MTIME # define FSW_MTIME(stat) (stat.st_mtime) # define FSW_CTIME(stat) (stat.st_ctime) #elif defined HAVE_STRUCT_STAT_ST_MTIMESPEC # define FSW_MTIME(stat) (stat.st_mtimespec.tv_sec) # define FSW_CTIME(stat) (stat.st_ctimespec.tv_sec) #endif namespace fsw { typedef struct poll_monitor::poll_monitor_data { fsw_hash_map tracked_files; } poll_monitor_data; REGISTER_MONITOR_IMPL(poll_monitor, poll_monitor_type); poll_monitor::poll_monitor(vector paths, FSW_EVENT_CALLBACK *callback, void *context) : monitor(paths, callback, context) { previous_data = new poll_monitor_data(); new_data = new poll_monitor_data(); time(&curr_time); } poll_monitor::~poll_monitor() { delete previous_data; delete new_data; } bool poll_monitor::initial_scan_callback(const string& path, const struct stat& stat) { if (previous_data->tracked_files.count(path)) return false; watched_file_info wfi{FSW_MTIME(stat), FSW_CTIME(stat)}; previous_data->tracked_files[path] = wfi; return true; } bool poll_monitor::intermediate_scan_callback(const string& path, const struct stat& stat) { if (new_data->tracked_files.count(path)) return false; watched_file_info wfi{FSW_MTIME(stat), FSW_CTIME(stat)}; new_data->tracked_files[path] = wfi; if (previous_data->tracked_files.count(path)) { watched_file_info pwfi = previous_data->tracked_files[path]; vector flags; if (FSW_MTIME(stat) > pwfi.mtime) { flags.push_back(fsw_event_flag::Updated); } if (FSW_CTIME(stat) > pwfi.ctime) { flags.push_back(fsw_event_flag::AttributeModified); } if (flags.size() > 0) { events.push_back({path, curr_time, flags}); } previous_data->tracked_files.erase(path); } else { vector flags; flags.push_back(fsw_event_flag::Created); events.push_back({path, curr_time, flags}); } return true; } bool poll_monitor::add_path(const string& path, const struct stat& fd_stat, poll_monitor_scan_callback poll_callback) { return ((*this).*(poll_callback))(path, fd_stat); } void poll_monitor::scan(const string& path, poll_monitor_scan_callback fn) { struct stat fd_stat; if (!lstat_path(path, fd_stat)) return; if (follow_symlinks && S_ISLNK(fd_stat.st_mode)) { string link_path; if (read_link_path(path, link_path)) scan(link_path, fn); return; } if (!S_ISDIR(fd_stat.st_mode) && !accept_path(path)) return; if (!add_path(path, fd_stat, fn)) return; if (!recursive) return; if (!S_ISDIR(fd_stat.st_mode)) return; vector children = get_directory_children(path); for (string& child : children) { if (child.compare(".") == 0 || child.compare("..") == 0) continue; scan(path + "/" + child, fn); } } void poll_monitor::find_removed_files() { vector flags; flags.push_back(fsw_event_flag::Removed); for (auto& removed : previous_data->tracked_files) { events.push_back({removed.first, curr_time, flags}); } } void poll_monitor::swap_data_containers() { delete previous_data; previous_data = new_data; new_data = new poll_monitor_data(); } void poll_monitor::collect_data() { poll_monitor_scan_callback fn = &poll_monitor::intermediate_scan_callback; for (string& path : paths) { scan(path, fn); } find_removed_files(); swap_data_containers(); } void poll_monitor::collect_initial_data() { poll_monitor_scan_callback fn = &poll_monitor::initial_scan_callback; for (string& path : paths) { scan(path, fn); } } void poll_monitor::run() { collect_initial_data(); for (;;) { #ifdef HAVE_CXX_MUTEX unique_lock run_guard(run_mutex); if (should_stop) break; run_guard.unlock(); #endif FSW_ELOG(_("Done scanning.\n")); sleep(latency < MIN_POLL_LATENCY ? MIN_POLL_LATENCY : latency); time(&curr_time); collect_data(); if (events.size()) { notify_events(events); events.clear(); } } } } fswatch-1.11.2/libfswatch/src/libfswatch/c++/windows/000755 000765 000024 00000000000 13175374110 022764 5ustar00enricostaff000000 000000 fswatch-1.11.2/libfswatch/src/libfswatch/c++/path_utils.hpp000644 000765 000024 00000005101 13174733730 024162 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Header defining utility functions to manipulate paths. * * @copyright Copyright (c) 2014-2016 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef FSW_PATH_UTILS_H # define FSW_PATH_UTILS_H # include # include # include namespace fsw { /** * @brief Gets a vector of direct directory children. * * @param path The directory whose children must be returned. * @return A vector containing the list of children of @p path. */ std::vector get_directory_children(const std::string& path); /** * @brief Resolves a path name. * * This function resolves @p path using @c realpath() and stores the absolute * pathname into @p link_path. The function returns @c true if it succeeds, * @c false otherwise. * * @param path The path to resolve. * @param link_path A reference to a `std::string` where the resolved absolute * path should be copied to. * @return @c true if the function succeeds, @c false otherwise. */ bool read_link_path(const std::string& path, std::string& link_path); /** * @brief Wraps a @c lstat(path, fd_stat) call that invokes @c perror() if it * fails. * * @param path The path to @c lstat(). * @param fd_stat The @c stat structure where @c lstat() writes its results. * @return @c true if the function succeeds, @c false otherwise. */ bool lstat_path(const std::string& path, struct stat& fd_stat); /** * @brief Wraps a @c stat(path, fd_stat) call that invokes @c perror() if it * fails. * * @param path The path to @c stat(). * @param fd_stat The @c stat structure where @c stat() writes its results. * @return @c true if the function succeeds, @c false otherwise. */ bool stat_path(const std::string& path, struct stat& fd_stat); } #endif /* FSW_PATH_UTILS_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/fen_monitor.hpp000644 000765 000024 00000005220 13174733730 024327 0ustar00enricostaff000000 000000 /* * Copyright (c) 2015-2016 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Solaris/Illumos monitor. * * @copyright Copyright (c) 2014-2016 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef FSW_FEN_MONITOR_H # define FSW_FEN_MONITOR_H # include "monitor.hpp" # include # include namespace fsw { /** * @brief Opaque structure containing implementation specific details of the * Solaris/Illumos monitor. */ struct fen_monitor_load; /** * @brief Opaque structure containing implementation specific details of the * Solaris/Illumos monitor. */ struct fen_info; /** * @brief Solaris/Illumos monitor. * * This monitor is built upon the _File Events Notification_ API of the * Solaris and Illumos kernels. */ class fen_monitor : public monitor { REGISTER_MONITOR(fen_monitor, fen_monitor_type); public: /** * @brief Constructs an instance of this class. */ fen_monitor(std::vector paths, FSW_EVENT_CALLBACK *callback, void *context = nullptr); /** * @brief Destroys an instance of this class. */ virtual ~fen_monitor(); protected: /** * @brief Executes the monitor loop. * * This call does not return until the monitor is stopped. * * @see stop() */ void run() override; private: fen_monitor(const fen_monitor& orig) = delete; fen_monitor& operator=(const fen_monitor& that) = delete; void scan_root_paths(); bool scan(const std::string& path, bool is_root_path = true); bool is_path_watched(const std::string& path) const; bool add_watch(const std::string& path, const struct stat& fd_stat); bool associate_port(struct fen_info *finfo, const struct stat& fd_stat); void process_events(struct fen_info *obj, int events); void rescan_removed(); void rescan_pending(); // pimpl fen_monitor_load *load; }; } #endif /* FSW_FEN_MONITOR_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/kqueue_monitor.cpp000644 000765 000024 00000026113 13175131667 025057 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ #ifdef HAVE_CONFIG_H # include "libfswatch_config.h" #endif #ifdef HAVE_SYS_EVENT_H # include "gettext_defs.h" # include "kqueue_monitor.hpp" # include "libfswatch_map.hpp" # include "libfswatch_set.hpp" # include "libfswatch_exception.hpp" # include "../c/libfswatch_log.h" # include "path_utils.hpp" # include # include # include # include # include # include # include using namespace std; namespace fsw { struct kqueue_monitor_load { fsw_hash_map descriptors_by_file_name; fsw_hash_map file_names_by_descriptor; fsw_hash_map file_modes; fsw_hash_set descriptors_to_remove; fsw_hash_set descriptors_to_rescan; void add_watch(int fd, const string& path, const struct stat& fd_stat) { descriptors_by_file_name[path] = fd; file_names_by_descriptor[fd] = path; file_modes[fd] = fd_stat.st_mode; } void remove_watch(int fd) { string name = file_names_by_descriptor[fd]; file_names_by_descriptor.erase(fd); descriptors_by_file_name.erase(name); file_modes.erase(fd); close(fd); } void remove_watch(const string& path) { int fd = descriptors_by_file_name[path]; descriptors_by_file_name.erase(path); file_names_by_descriptor.erase(fd); file_modes.erase(fd); close(fd); } }; typedef struct KqueueFlagType { uint32_t flag; fsw_event_flag type; } KqueueFlagType; static vector create_flag_type_vector() { vector flags; flags.push_back({NOTE_DELETE, fsw_event_flag::Removed}); flags.push_back({NOTE_WRITE, fsw_event_flag::Updated}); flags.push_back({NOTE_EXTEND, fsw_event_flag::PlatformSpecific}); flags.push_back({NOTE_ATTRIB, fsw_event_flag::AttributeModified}); flags.push_back({NOTE_LINK, fsw_event_flag::Link}); flags.push_back({NOTE_RENAME, fsw_event_flag::Renamed}); flags.push_back({NOTE_REVOKE, fsw_event_flag::PlatformSpecific}); return flags; } static const vector event_flag_type = create_flag_type_vector(); REGISTER_MONITOR_IMPL(kqueue_monitor, kqueue_monitor_type); kqueue_monitor::kqueue_monitor(vector paths_to_monitor, FSW_EVENT_CALLBACK *callback, void *context) : monitor(paths_to_monitor, callback, context), load(new kqueue_monitor_load()) { } kqueue_monitor::~kqueue_monitor() { terminate_kqueue(); delete load; } static vector decode_flags(uint32_t flag) { vector evt_flags; for (const KqueueFlagType& type : event_flag_type) { if (flag & type.flag) { evt_flags.push_back(type.type); } } return evt_flags; } static struct timespec create_timespec_from_latency(double latency) { double seconds; double nanoseconds = modf(latency, &seconds); nanoseconds *= 1000000000; struct timespec ts; ts.tv_sec = seconds; ts.tv_nsec = nanoseconds; return ts; } bool kqueue_monitor::is_path_watched(const string& path) const { return load->descriptors_by_file_name.find(path) != load->descriptors_by_file_name.end(); } bool kqueue_monitor::add_watch(const string& path, const struct stat& fd_stat) { // check if the path is already watched and if it is, // skip it and return false. if (is_path_watched(path)) { return false; } int o_flags = 0; # ifdef O_SYMLINK o_flags |= O_SYMLINK; # endif # ifdef O_EVTONLY // The descriptor is requested for event notifications only. o_flags |= O_EVTONLY; # else o_flags |= O_RDONLY; # endif int fd = open(path.c_str(), o_flags); if (fd == -1) { fsw_logf_perror(_("Cannot open %s"), path.c_str()); return false; } // if the descriptor could be opened, track it load->add_watch(fd, path, fd_stat); return true; } bool kqueue_monitor::scan(const string& path, bool is_root_path) { struct stat fd_stat; if (!lstat_path(path, fd_stat)) return false; if (follow_symlinks && S_ISLNK(fd_stat.st_mode)) { string link_path; if (read_link_path(path, link_path)) return scan(link_path); return false; } bool is_dir = S_ISDIR(fd_stat.st_mode); if (!is_dir && !is_root_path && directory_only) return true; if (!is_dir && !accept_path(path)) return true; if (!add_watch(path, fd_stat)) return false; if (!recursive) return true; if (!is_dir) return true; vector children = get_directory_children(path); for (string& child : children) { if (child.compare(".") == 0 || child.compare("..") == 0) continue; scan(path + "/" + child, false); } return true; } void kqueue_monitor::remove_deleted() { auto fd = load->descriptors_to_remove.begin(); while (fd != load->descriptors_to_remove.end()) { load->remove_watch(*fd); load->descriptors_to_remove.erase(fd++); } } void kqueue_monitor::rescan_pending() { auto fd = load->descriptors_to_rescan.begin(); while (fd != load->descriptors_to_rescan.end()) { string fd_path = load->file_names_by_descriptor[*fd]; // Rescan the hierarchy rooted at fd_path. // If the path does not exist any longer, nothing needs to be done since // kqueue(2) says: // // EV_DELETE Events which are attached to file descriptors are // automatically deleted on the last close of the descriptor. // // If the descriptor which has vanished is a directory, we don't bother // EV_DELETEing all its children the event from kqueue for the same // reason. load->remove_watch(fd_path); scan(fd_path); load->descriptors_to_rescan.erase(fd++); } } void kqueue_monitor::scan_root_paths() { for (string& path : paths) { if (is_path_watched(path)) continue; if (!scan(path)) { FSW_ELOGF(_("%s cannot be found. Will retry later.\n"), path.c_str()); } } } void kqueue_monitor::initialize_kqueue() { if (kq != -1) throw libfsw_exception(_("kqueue already running.")); kq = kqueue(); if (kq == -1) { perror("kqueue()"); throw libfsw_exception(_("kqueue failed.")); } } void kqueue_monitor::terminate_kqueue() { if (kq != -1) close(kq); kq = -1; } int kqueue_monitor::wait_for_events(const vector& changes, vector& event_list) { struct timespec ts = create_timespec_from_latency(latency); int event_num = kevent(kq, &changes[0], (int) changes.size(), &event_list[0], (int) event_list.size(), &ts); // Ignore errors when kevent() is interrupted by a signal. if (event_num == -1 && errno != EINTR) { perror("kevent"); throw libfsw_exception(_("kevent returned -1, invalid event number.")); } return event_num; } void kqueue_monitor::process_events(const vector& changes, const vector& event_list, int event_num) { time_t curr_time; time(&curr_time); vector events; for (auto i = 0; i < event_num; ++i) { struct kevent e = event_list[i]; if (e.flags & EV_ERROR) { perror(_("Event with EV_ERROR")); continue; } // If a NOTE_DELETE is found or a NOTE_LINK is found on a directory, then // the descriptor should be closed and the node rescanned: removing a // subtree in *BSD usually result in NOTE_REMOVED | NOTE_LINK being logged // for each subdirectory, but sometimes NOTE_WRITE | NOTE_LINK is only // observed. For this reason we mark those descriptors as to be deleted // anyway. // // If a NOTE_RENAME or NOTE_REVOKE flag is found, the file // descriptor should probably be closed and the file should be rescanned. // If a NOTE_WRITE flag is found and the descriptor is a directory, then // the directory needs to be rescanned because at least one file has // either been created or deleted. if ((e.fflags & NOTE_DELETE)) { load->descriptors_to_remove.insert(e.ident); } else if ((e.fflags & NOTE_RENAME) || (e.fflags & NOTE_REVOKE) || ((e.fflags & NOTE_WRITE) && S_ISDIR(load->file_modes[e.ident]))) { load->descriptors_to_rescan.insert(e.ident); } // Invoke the callback passing every path for which an event has been // received with a non empty filter flag. if (e.fflags) { events.push_back({load->file_names_by_descriptor[e.ident], curr_time, decode_flags(e.fflags)}); } } if (events.size()) { notify_events(events); } } void kqueue_monitor::run() { initialize_kqueue(); for(;;) { #ifdef HAVE_CXX_MUTEX unique_lock run_guard(run_mutex); if (should_stop) break; run_guard.unlock(); #endif // remove the deleted descriptors remove_deleted(); // rescan the pending descriptors rescan_pending(); // scan the root paths to check whether someone is missing scan_root_paths(); vector changes; vector event_list; for (const pair& fd_path : load->file_names_by_descriptor) { struct kevent change; EV_SET(&change, fd_path.first, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, NOTE_DELETE | NOTE_EXTEND | NOTE_RENAME | NOTE_WRITE | NOTE_ATTRIB | NOTE_LINK | NOTE_REVOKE, 0, 0); changes.push_back(change); struct kevent event; event_list.push_back(event); } /* * If no files can be observed yet, then wait and repeat the loop. */ if (!changes.size()) { sleep(latency); continue; } const int event_num = wait_for_events(changes, event_list); process_events(changes, event_list, event_num); } terminate_kqueue(); } } #endif /* HAVE_SYS_EVENT_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/libfswatch_exception.cpp000644 000765 000024 00000003100 13175131667 026204 0ustar00enricostaff000000 000000 /* * Copyright (c) 2014-2015 Enrico M. Crisostomo * * 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, 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 . */ #include "libfswatch_exception.hpp" #include #include "gettext_defs.h" using namespace std; namespace fsw { libfsw_exception::libfsw_exception(string cause, int code) : cause(std::move(cause)), code(code) { } const char *libfsw_exception::what() const noexcept { return (string(_("Error: ")) + this->cause).c_str(); } int libfsw_exception::error_code() const noexcept { return code; } libfsw_exception::operator int() const noexcept { return code; } libfsw_exception::~libfsw_exception() noexcept = default; libfsw_exception::libfsw_exception(const libfsw_exception& other) noexcept : cause(other.cause), code(other.code) { } libfsw_exception& libfsw_exception::operator=(const libfsw_exception& that) noexcept { if(&that == this) return *this; this->cause = that.cause; this->code = that.code; return *this; } } fswatch-1.11.2/libfswatch/src/libfswatch/c++/windows/win_handle.cpp000644 000765 000024 00000003627 13174733730 025616 0ustar00enricostaff000000 000000 /* * Copyright (c) 2015 Enrico M. Crisostomo * * 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, 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 . */ #ifdef HAVE_CONFIG_H # include "libfswatch_config.h" #endif #ifdef HAVE_WINDOWS # include "gettext_defs.h" # include "win_handle.hpp" # include "../../c/libfswatch_log.h" using namespace std; namespace fsw { bool win_handle::is_valid(const HANDLE & handle) { return (handle != INVALID_HANDLE_VALUE && handle != nullptr); } win_handle::win_handle() : h(INVALID_HANDLE_VALUE){} win_handle::win_handle(HANDLE handle) : h(handle){} win_handle::~win_handle() { if (is_valid()) { FSW_ELOGF(_("Closing handle: %d.\n"), h); CloseHandle(h); } } win_handle::operator HANDLE() const { return h; } bool win_handle::is_valid() const { return win_handle::is_valid(h); } win_handle& win_handle::operator=(const HANDLE& handle) { if (is_valid() && h != handle) CloseHandle(h); h = handle; return *this; } win_handle::win_handle(win_handle&& other) noexcept { h = other.h; other.h = INVALID_HANDLE_VALUE; } win_handle& win_handle::operator=(win_handle&& other) noexcept { if (this == &other) return *this; if (is_valid() && h != other.h) CloseHandle(h); h = other.h; other.h = INVALID_HANDLE_VALUE; return *this; } } #endif /* HAVE_WINDOWS */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/windows/win_error_message.cpp000644 000765 000024 00000003767 13175131667 027227 0ustar00enricostaff000000 000000 /* * Copyright (c) 2015 Enrico M. Crisostomo * * 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, 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 . */ #ifdef HAVE_CONFIG_H # include "libfswatch_config.h" #endif #ifdef HAVE_WINDOWS # include "gettext_defs.h" # include "win_error_message.hpp" # include "../../c/libfswatch_log.h" using namespace std; namespace fsw { win_error_message win_error_message::current() { return win_error_message(); } win_error_message::win_error_message(DWORD error_code) : err_code{error_code}{} win_error_message::win_error_message() : err_code{GetLastError()}{} DWORD win_error_message::get_error_code() const { return err_code; } wstring win_error_message::get_message() const { if (initialized) return msg; initialized = true; LPWSTR buf = nullptr; DWORD ret_size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err_code, 0, (LPWSTR)&buf, 0, nullptr); if (ret_size > 0) { msg = buf; LocalFree(buf); } else { msg = L"The system error message could not be formatted."; } return msg; } win_error_message::operator wstring() const { return get_message(); } } #endif /* HAVE_WINDOWS */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/windows/win_strings.cpp000644 000765 000024 00000002237 13175131667 026052 0ustar00enricostaff000000 000000 /* * Copyright (c) 2015 Enrico M. Crisostomo * * 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, 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 . */ #include "win_strings.hpp" #include namespace fsw { namespace win_strings { using namespace std; string wstring_to_string(wchar_t * s) { int buf_size = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL); char buf[buf_size]; WideCharToMultiByte(CP_UTF8, 0, s, -1, buf, buf_size, NULL, NULL); return string(buf); } string wstring_to_string(const wstring & s) { return wstring_to_string((wchar_t *)s.c_str()); } } } fswatch-1.11.2/libfswatch/src/libfswatch/c++/windows/win_paths.cpp000644 000765 000024 00000003101 13175131667 025467 0ustar00enricostaff000000 000000 /* * Copyright (c) 2015 Enrico M. Crisostomo * * 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, 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 . */ #include "win_paths.hpp" #include #include "../libfswatch_exception.hpp" #include "../../gettext_defs.h" using namespace std; namespace fsw { namespace win_paths { wstring posix_to_win_w(string path) { void * raw_path = cygwin_create_path(CCP_POSIX_TO_WIN_W, path.c_str()); if (raw_path == nullptr) throw libfsw_exception(_("cygwin_create_path could not allocate memory to convert the path.")); wstring win_path(static_cast (raw_path)); free(raw_path); return win_path; } string win_w_to_posix(wstring path) { void * raw_path = cygwin_create_path(CCP_WIN_W_TO_POSIX, path.c_str()); if (raw_path == nullptr) throw libfsw_exception(_("cygwin_create_path could not allocate memory to convert the path.")); string posix_path(static_cast (raw_path)); free(raw_path); return posix_path; } } } fswatch-1.11.2/libfswatch/src/libfswatch/c++/windows/win_directory_change_event.cpp000644 000765 000024 00000012204 13175131667 031066 0ustar00enricostaff000000 000000 /* * Copyright (c) 2015 Enrico M. Crisostomo * * 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, 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 . */ #ifdef HAVE_CONFIG_H # include "libfswatch_config.h" #endif #include "win_directory_change_event.hpp" #include "win_paths.hpp" #include "win_strings.hpp" #include "../libfswatch_exception.hpp" #include "../../c/libfswatch_log.h" #include "../../gettext_defs.h" #include #include #include namespace fsw { using namespace std; struct win_flag_type { DWORD action; vector types; }; static vector create_flag_type_vector() { vector flags; flags.push_back({FILE_ACTION_ADDED, {fsw_event_flag::Created}}); flags.push_back({FILE_ACTION_REMOVED, {fsw_event_flag::Removed}}); flags.push_back({FILE_ACTION_MODIFIED, {fsw_event_flag::Updated}}); flags.push_back({FILE_ACTION_RENAMED_OLD_NAME, {fsw_event_flag::MovedFrom, fsw_event_flag::Renamed}}); flags.push_back({FILE_ACTION_RENAMED_NEW_NAME, {fsw_event_flag::MovedTo, fsw_event_flag::Renamed}}); return flags; } static const vector event_flag_type = create_flag_type_vector(); static vector decode_flags(DWORD flag) { set evt_flags_set; for (const win_flag_type & event_type : event_flag_type) { if (flag == event_type.action) { for (const auto & type : event_type.types) evt_flags_set.insert(type); } } return vector(evt_flags_set.begin(), evt_flags_set.end()); } directory_change_event::directory_change_event(size_t buffer_length) : handle{INVALID_HANDLE_VALUE}, buffer_size{sizeof (FILE_NOTIFY_INFORMATION) * buffer_length}, bytes_returned{} { buffer.reset(malloc(buffer_size)); if (buffer.get() == nullptr) throw libfsw_exception(_("malloc failed.")); if (overlapped.get() == nullptr) throw libfsw_exception(_("malloc failed.")); } bool directory_change_event::is_io_incomplete() { return (read_error.get_error_code() == ERROR_IO_INCOMPLETE); } bool directory_change_event::is_buffer_overflowed() { return (read_error.get_error_code() == ERROR_NOTIFY_ENUM_DIR); } bool directory_change_event::read_changes_async() { continue_read(); FSW_ELOGF(_("%p.\n"), this); return ReadDirectoryChangesW((HANDLE) handle, buffer.get(), buffer_size, TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_LAST_ACCESS | FILE_NOTIFY_CHANGE_CREATION, &bytes_returned, overlapped.get(), nullptr); } bool directory_change_event::try_read() { bool ret = GetOverlappedResult(handle, overlapped.get(), &bytes_returned, FALSE); read_error = win_error_message::current(); FSW_ELOGF(_("GetOverlappedResult: %s\n"), win_strings::wstring_to_string((wstring) read_error).c_str()); return ret; } void directory_change_event::continue_read() { if (!ResetEvent(overlapped.get()->hEvent)) throw libfsw_exception(_("ResetEvent failed.")); FSW_ELOGF(_("Event %d reset.\n"), overlapped.get()->hEvent); } vector directory_change_event::get_events() { // TO DO: We are relying on callers to know events are ready. vector events; time_t curr_time; time(&curr_time); char * curr_entry = static_cast (buffer.get()); while (curr_entry != nullptr) { FILE_NOTIFY_INFORMATION * currEntry = reinterpret_cast (curr_entry); if (currEntry->FileNameLength > 0) { // The FileName member of the FILE_NOTIFY_INFORMATION structure // has the following characteristics: // // * It's not NUL terminated. // // * Its length is specified in bytes. wstring file_name = path + L"\\" + wstring(currEntry->FileName, currEntry->FileNameLength / sizeof (wchar_t)); events.push_back({win_paths::win_w_to_posix(file_name), curr_time, decode_flags(currEntry->Action)}); } else { cerr << _("File name unexpectedly empty.") << endl; } curr_entry = (currEntry->NextEntryOffset == 0) ? nullptr : curr_entry + currEntry->NextEntryOffset; } return events; } } fswatch-1.11.2/libfswatch/src/libfswatch/c++/windows/win_strings.hpp000644 000765 000024 00000003224 13174733730 026052 0ustar00enricostaff000000 000000 /* * Copyright (c) 2016 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Header of the fsw::win_strings namespace. * * @copyright Copyright (c) 2014-2016 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef FSW_WIN_STRINGS_H # define FSW_WIN_STRINGS_H # include # include namespace fsw { /** * @brief String conversion functions. * * This namespace contains utility functions to convert wide character strings * into strings. */ namespace win_strings { /** * @brief Converts a wide character string into a string. * * @param s The @c wchar_t array to convert. * @return The converted string. */ std::string wstring_to_string(wchar_t *s); /** * @brief Converts a wide character string into a string. * * @param s The string to convert. * @return The converted string. */ std::string wstring_to_string(const std::wstring& s); } } #endif /* FSW_WIN_STRINGS_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/windows/win_paths.hpp000644 000765 000024 00000003233 13174733730 025500 0ustar00enricostaff000000 000000 /* * Copyright (c) 2016 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Header of the fsw::win_paths namespace. * * @copyright Copyright (c) 2014-2016 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef FSW_WIN_PATHS_HPP # define FSW_WIN_PATHS_HPP # include namespace fsw { /** * @brief Path conversion functions. * * This namespace contains utility functions for POSIX to Windows and Windows * to POSIX path conversion functions. */ namespace win_paths { /** * @brief Converts a POSIX path to Windows. * * @param path The POSIX path to convert to a Windows path. * @return The converted Windows path. */ std::wstring posix_to_win_w(std::string path); /** * @brief Converts a Windows path to POSIX. * * @param path The Windows path to convert to POSIX. * @return The converted POSIX path. */ std::string win_w_to_posix(std::wstring path); } } #endif /* FSW_WIN_PATHS_HPP */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/windows/win_directory_change_event.hpp000644 000765 000024 00000004034 13174733730 031073 0ustar00enricostaff000000 000000 /* * Copyright (c) 2015 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Header of the fsw::directory_change_event class. * * @copyright Copyright (c) 2014-2015 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef FSW_WIN_DIRECTORY_CHANGE_EVENT_H # define FSW_WIN_DIRECTORY_CHANGE_EVENT_H # include # include # include # include # include # include "win_handle.hpp" # include "win_error_message.hpp" # include "../event.hpp" namespace fsw { /** * @brief Header of the fsw::directory_change_event class, a helper class to * wrap Microsoft Windows' `ReadDirectoryChangesW` function and a common * workflow to detect file system changes. */ class directory_change_event { public: std::wstring path; win_handle handle; size_t buffer_size; DWORD bytes_returned; std::unique_ptr buffer = {nullptr, free}; std::unique_ptr overlapped = {static_cast (malloc(sizeof (OVERLAPPED))), free}; win_error_message read_error; directory_change_event(size_t buffer_length = 16); bool is_io_incomplete(); bool is_buffer_overflowed(); bool read_changes_async(); bool try_read(); void continue_read(); std::vector get_events(); }; } #endif /* WIN_DIRECTORY_CHANGE_EVENT_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/windows/win_handle.hpp000644 000765 000024 00000007176 13174733730 025626 0ustar00enricostaff000000 000000 /* * Copyright (c) 2015 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Header of the fsw::win_handle class. * * @copyright Copyright (c) 2014-2015 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef FSW_WINDOWS_HANDLE_H # define FSW_WINDOWS_HANDLE_H # include namespace fsw { /** * @brief A RAII wrapper around Microsoft Windows `HANDLE`. * * This class is a movable, non-copyable RAII wrapper on `HANDLE`. */ class win_handle { public: /** * @brief Checks whether @p handle is valid. * * A @p handle is valid is if its value is not `null` and if is not * `INVALID_HANDLE_VALUE`. * * @param handle The handle to check. * @return Returns @c true if @p handle is valid, @c false otherwise. */ static bool is_valid(const HANDLE & handle); /** * @brief Constructs an instance wrapping `INVALID_HANDLE_VALUE`. */ win_handle(); /** * @brief Constructs an instance wrapping @p handle. */ win_handle(HANDLE handle); /** * @brief Destructs a handle. * * If the handle is valid (is_valid()) it is closed invoking * `CloseHandle()`. * * @see is_valid(const HANDLE &) */ virtual ~win_handle(); /** * @brief Returns the handle value as `HANDLE` instance. */ operator HANDLE() const; /** * @brief Checks whether the handle is valid. * * @return Returns @c true if the handle is valid, @c false otherwise. * @see is_valid() */ bool is_valid() const; /** * @brief Deleted copy constructor. */ win_handle(const win_handle&) = delete; /** * @brief Deleted copy assignment operator. */ win_handle& operator=(const win_handle&) = delete; /** * @brief Move constructor. * * The move constructors moves the handle value wrapped by @p other to the * target instance. The handle value in @p other is set to * `INVALID_HANDLE_VALUE`. The previously wrapped instance is closed * invoking `CloseHandle` if it is valid. * * @param other The handle to move. */ win_handle(win_handle&& other) noexcept; /** * @brief Move assignment operator. * * The move assignment operator moves the handle value wrapped by @p other * to the target instance. The handle value in @p other is set to * `INVALID_HANDLE_VALUE`. The previously wrapped instance is closed * invoking `CloseHandle` if it is valid. * * @param other The handle to move. */ win_handle& operator=(win_handle&& other) noexcept; /** * @brief Assigns a @p handle to the current instance. * * The previously wrapped instance is closed invoking `CloseHandle` if it is * valid. * * @param handle The handle value to assign to the current instance. */ win_handle& operator=(const HANDLE& handle); private: HANDLE h; }; } #endif /* FSW_WINDOWS_HANDLE_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/windows/win_error_message.hpp000644 000765 000024 00000005257 13174733730 027226 0ustar00enricostaff000000 000000 /* * Copyright (c) 2015 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Header of the fsw::win_error_message class. * * @copyright Copyright (c) 2014-2015 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef FSW_WINDOWS_ERROR_MESSAGE_H # define FSW_WINDOWS_ERROR_MESSAGE_H # include # include namespace fsw { /** * @brief Helper class to get the system-defined error message for a Microsoft * Windows' error code. * * This class uses the `FormatMessage()` API to returns a std::wstring * instance containing the system-defined error message for a Microsoft * Windows' error code. */ class win_error_message { public: /** * @brief Constructs an instance of this class using the last error code of * the calling thread, returned by a call to `GetLastError()`. * * @see win_error_message() */ static win_error_message current(); /** * @brief Constructs an error message using the specified @p error_code. * * @param error_code The error code. */ win_error_message(DWORD error_code); /** * @brief Constructs an error message using the last error code of the * calling thread, retrieved with a call to `GetLastError()`. * * @see current() */ win_error_message(); /** * @brief Gets the error code. * * @return The error code. */ DWORD get_error_code() const; /** * @brief Gets the system-defined error message. * * The system-defined error message is retrieved with a call to * `FormatMessage` with the `FORMAT_MESSAGE_FROM_SYSTEM` formatting option. * * @return The error message. */ std::wstring get_message() const; /** * @brief Gets ths system-defined error message. * * @see get_message() */ operator std::wstring() const; private: mutable bool initialized = false; mutable std::wstring msg; DWORD err_code; }; } #endif /* FSW_WINDOWS_ERROR_MESSAGE_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/string/string_utils.hpp000644 000765 000024 00000003235 13174733730 026050 0ustar00enricostaff000000 000000 /* * Copyright (c) 2015 Enrico M. Crisostomo * * 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, 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 . */ /** * @file * @brief Header of the fsw::string_utils namespace. * * @copyright Copyright (c) 2014-2015 Enrico M. Crisostomo * @license GNU General Public License v. 3.0 * @author Enrico M. Crisostomo * @version 1.8.0 */ #ifndef FSW_STRING_UTILS_H # define FSW_STRING_UTILS_H #include #include namespace fsw { /** * @brief This namespace contains string manipulation functions. */ namespace string_utils { /** * @brief Create a `std::string` using a `printf()` format and varargs. * * @param format The `printf()` format. * @param ... The arguments to format. */ std::string string_from_format(const char *format, ...); /** * @brief Create a `std::string` using a `printf()` format and a `va_list` * @p args. * * @param format The `printf()` format. * @param args The arguments to format. */ std::string vstring_from_format(const char *format, va_list args); } } #endif /* FSW_STRING_UTILS_H */ fswatch-1.11.2/libfswatch/src/libfswatch/c++/string/string_utils.cpp000644 000765 000024 00000003266 13175131667 026051 0ustar00enricostaff000000 000000 /* * Copyright (c) 2015 Enrico M. Crisostomo * * 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, 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 . */ #include #include #include #include "string_utils.hpp" using namespace std; namespace fsw { namespace string_utils { string vstring_from_format(const char *format, va_list args) { size_t current_buffer_size = 0; int required_chars = 512; vector buffer; do { current_buffer_size += required_chars; buffer.resize(current_buffer_size); required_chars = vsnprintf(&buffer[0], current_buffer_size, format, args); // If an encoding error occurs, break and write an empty string into the // buffer. if (required_chars < 0) { buffer.resize(1); break; } } while ((size_t) required_chars > current_buffer_size); return string(&buffer[0]); } string string_from_format(const char *format, ...) { va_list args; va_start(args, format); string ret = vstring_from_format(format, args); va_end(args); return ret; } } }fswatch-1.11.2/libfswatch/doc/Makefile.am000644 000765 000024 00000001260 13174733730 020613 0ustar00enricostaff000000 000000 # # Copyright (c) 2014-2016 Enrico M. Crisostomo # # 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, 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 . # SUBDIRS = doxygen fswatch-1.11.2/libfswatch/doc/doxygen/000755 000765 000024 00000000000 13175374110 020227 5ustar00enricostaff000000 000000 fswatch-1.11.2/libfswatch/doc/doxygen/Doxyfile.in000644 000765 000024 00000313552 13174733730 022361 0ustar00enricostaff000000 000000 # Doxyfile 1.8.10 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed in # front of the TAG it is preceding. # # All text after a single hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all text # before the first occurrence of this tag. Doxygen uses libiconv (or the iconv # built into libc) for the transcoding. See http://www.gnu.org/software/libiconv # for the list of possible encodings. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded by # double-quotes, unless you are using Doxywizard) that should identify the # project for which the documentation is generated. This name is used in the # title of most generated pages and in a few other places. # The default value is: My Project. PROJECT_NAME = @PACKAGE_NAME@ # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 # pixels and the maximum width should not exceed 200 pixels. Doxygen will copy # the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. OUTPUT_DIRECTORY = # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and # will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes # performance problems for the file system. # The default value is: NO. CREATE_SUBDIRS = NO # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode # U+3044. # The default value is: NO. ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, # Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), # Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, # Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, # Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, # Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, # Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. # The default value is: YES. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found # as the leading text of the brief description, will be stripped from the text # and the result, after processing the whole list, is used as the annotated # text. Otherwise, the brief description is used as-is. If left blank, the # following values are used ($name is automatically replaced with the name of # the entity):The $name class, The $name widget, The $name file, is, provides, # specifies, contains, represents, a, an and the. ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # doxygen will generate a detailed section even if there is only a brief # description. # The default value is: NO. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. # The default value is: NO. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. FULL_PATH_NAMES = YES # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand # part of the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the path to # strip. # # Note that you can specify absolute paths here, but also relative paths, which # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = ../../src # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which # header file to include in order to use a class. If left blank only the name of # the header file containing the class definition is used. Otherwise one should # specify the list of include paths that are normally passed to the compiler # using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't # support long names like on DOS, Mac, or CD-ROM. # The default value is: NO. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the # first line (until the first dot) of a Javadoc-style comment as the brief # description. If set to NO, the Javadoc-style will behave just like regular Qt- # style comments (thus requiring an explicit @brief command for a brief # description.) # The default value is: NO. JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus # requiring an explicit \brief command for a brief description.) # The default value is: NO. QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as # a brief description. This used to be the default behavior. The new default is # to treat a multi-line C++ comment block as a detailed description. Set this # tag to YES if you prefer the old behavior instead. # # Note that setting this tag to YES also means that rational rose comments are # not recognized any more. # The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new # page for each member. If set to NO, the documentation of a member will be part # of the file/class/namespace that contains it. # The default value is: NO. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen # uses this value to replace tabs by spaces in code fragments. # Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that act as commands in # the documentation. An alias has the form: # name=value # For example adding # "sideeffect=@par Side Effects:\n" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading # "Side Effects:". You can put \n's in the value part of an alias to insert # newlines. ALIASES += "license=@par License:\n" # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding "class=itcl::class" # will allow you to use the command class in the itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all # members will be omitted, etc. # The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or # Python sources only. Doxygen will then generate output that is more tailored # for that language. For instance, namespaces will be presented as packages, # qualified scopes will look different, etc. # The default value is: NO. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources. Doxygen will then generate output that is tailored for Fortran. # The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for VHDL. # The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, Javascript, # C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: # FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: # Fortran. In the later case the parser tries to guess whether the code is fixed # or free formatted code, this is the default for Fortran type files), VHDL. For # instance to make doxygen treat .inc files as Fortran files (default is PHP), # and .f files as C (default is Fortran), use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. # The default value is: YES. MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should set this # tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); # versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. # The default value is: NO. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. # The default value is: NO. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: # http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES will make # doxygen to replace the get and set methods by a property in the documentation. # This will only work if the methods are indeed getting or setting a simple # type. If this is not the case, or you want to show the methods anyway, you # should set this option to NO. # The default value is: YES. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. DISTRIBUTE_GROUP_DOC = NO # If one adds a struct or class to a group and this option is enabled, then also # any nested class or struct is added to the same group. By default this option # is disabled and one has to add nested compounds explicitly via \ingroup. # The default value is: NO. GROUP_NESTED_COMPOUNDS = NO # Set the SUBGROUPING tag to YES to allow class member groups of the same type # (for instance a group of public functions) to be put as a subgroup of that # type (e.g. under the Public Functions section). Set it to NO to prevent # subgrouping. Alternatively, this can be done per class using the # \nosubgrouping command. # The default value is: YES. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions # are shown inside the group in which they are included (e.g. using \ingroup) # instead of on a separate page (for HTML and Man pages) or section (for LaTeX # and RTF). # # Note that this feature does not work in combination with # SEPARATE_MEMBER_PAGES. # The default value is: NO. INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions # with only public data fields or simple typedef fields will be shown inline in # the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO, structs, classes, and unions are shown on a separate page (for HTML and # Man pages) or section (for LaTeX and RTF). # The default value is: NO. INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or # enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically be # useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. # The default value is: NO. TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can be # an expensive process and often the same symbol appears multiple times in the # code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small # doxygen will become slower. If the cache is too large, memory is wasted. The # cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range # is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 # symbols. At the end of a run doxygen will report the cache usage and suggest # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. # Note: This will also disable the warnings about undocumented members that are # normally produced when WARNINGS is set to YES. # The default value is: NO. EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES, all static members of a file will be # included in the documentation. # The default value is: NO. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined # locally in source files will be included in the documentation. If set to NO, # only classes defined in header files are included. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. If set to YES, local methods, # which are defined in the implementation section but not in the interface are # included in the documentation. If set to NO, only methods in the interface are # included. # The default value is: NO. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base name of # the file that contains the anonymous namespace. By default anonymous namespace # are hidden. # The default value is: NO. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation # section is generated. This option has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option # has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend # (class|struct|union) declarations. If set to NO, these declarations will be # included in the documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any # documentation blocks found inside the body of a function. If set to NO, these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation that is typed after a # \internal command is included. If the tag is set to NO then the documentation # will be excluded. Set it to YES to include the internal documentation. # The default value is: NO. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file # names in lower-case letters. If set to YES, upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. # The default value is: system dependent. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES, the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO # If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will # append additional text to a page's title, such as Class Reference. If set to # YES the compound reference will be hidden. # The default value is: NO. HIDE_COMPOUND_REFERENCE= NO # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. SHOW_INCLUDE_FILES = YES # If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each # grouped member an include statement to the documentation, telling the reader # which file to include in order to use the member. # The default value is: NO. SHOW_GROUPED_MEMB_INC = NO # If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the # documentation for inline members. # The default value is: YES. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. Note that # this will also influence the order of the classes in the class list. # The default value is: NO. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the # (brief and detailed) documentation of class members so that constructors and # destructors are listed first. If set to NO the constructors will appear in the # respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. # Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief # member documentation. # Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting # detailed member documentation. # The default value is: NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will # appear in their defined order. # The default value is: NO. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by # fully-qualified names, including namespaces. If set to NO, the class list will # be sorted only by class name, not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the alphabetical # list. # The default value is: NO. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper # type resolution of all parameters of a function it will reject a match between # the prototype and the implementation of a member function even if there is # only one candidate or it is obvious which candidate to choose by doing a # simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still # accept a match between prototype and implementation in such cases. # The default value is: NO. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo # list. This list is created by putting \todo commands in the documentation. # The default value is: YES. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test # list. This list is created by putting \test commands in the documentation. # The default value is: YES. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional documentation # sections, marked by \if ... \endif and \cond # ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have for it to appear in the # documentation. If the initializer consists of more lines than specified here # it will be hidden. Use a value of 0 to hide initializers completely. The # appearance of the value of individual variables and macros / defines can be # controlled using \showinitializer or \hideinitializer command in the # documentation regardless of this setting. # Minimum value: 0, maximum value: 10000, default value: 30. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at # the bottom of the documentation of classes and structs. If set to YES, the # list will mention the files that were used to generate the documentation. # The default value is: YES. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. This # will remove the Files entry from the Quick Index and from the Folder Tree View # (if specified). # The default value is: YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # page. This will remove the Namespaces entry from the Quick Index and from the # Folder Tree View (if specified). # The default value is: YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command command input-file, where command is the value of the # FILE_VERSION_FILTER tag, and input-file is the name of an input file provided # by doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml # will be used as the name of the layout file. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool # to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated to # standard output by doxygen. If QUIET is set to YES this implies that the # messages are off. # The default value is: NO. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error (stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. # The default value is: YES. WARNINGS = YES # If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some parameters # in a documented function, or documenting parameters that don't exist or using # markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return # value. If set to NO, doxygen will only warn about wrong or incomplete # parameter documentation, but not about the absence of documentation. # The default value is: NO. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard # error (stderr). WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. INPUT = @top_srcdir@/libfswatch/src # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: http://www.gnu.org/software/libiconv) for the list of # possible encodings. # The default value is: UTF-8. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # read by doxygen. # # If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, # *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, # *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, # *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, # *.vhdl, *.ucf, *.qsf, *.as and *.js. FILE_PATTERNS = # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. # The default value is: NO. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include # command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank all # files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude commands # irrespective of the value of the RECURSIVE tag. # The default value is: NO. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or directories # that contain images that are to be included in the documentation (see the # \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command: # # # # where is the value of the INPUT_FILTER tag, and is the # name of an input file. Doxygen will then use the output that the filter # program writes to standard output. If FILTER_PATTERNS is specified, this tag # will be ignored. # # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: pattern=filter # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) and # it is also possible to disable source filtering for a specific pattern using # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will be # generated. Documented entities will be cross-referenced with these sources. # # Note: To get rid of all source code in the generated output, make sure that # also VERBATIM_HEADERS is set to NO. # The default value is: NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body of functions, # classes and enums directly into the documentation. # The default value is: NO. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and # Fortran comments will always remain visible. # The default value is: YES. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented # function all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES then for each documented function # all documented entities called/used by that function will be listed. # The default value is: NO. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set # to YES then the hyperlinks from functions in REFERENCES_RELATION and # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # link to the documentation. # The default value is: YES. REFERENCES_LINK_SOURCE = YES # If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the # source code will show a tooltip with additional information such as prototype, # brief description and links to the definition and documentation. Since this # will make the HTML file larger and loading of large files a bit slower, you # can opt to disable this feature. # The default value is: YES. # This tag requires that the tag SOURCE_BROWSER is set to YES. SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system # (see http://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global # - Enable SOURCE_BROWSER and USE_HTAGS in the config file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # # Doxygen will invoke htags (and that will in turn invoke gtags), so these # tools must be available from the command line (i.e. in the search path). # # The result: instead of the source browser generated by doxygen, the links to # source code will now point to the output of htags. # The default value is: NO. # This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a # verbatim copy of the header file for each class for which an include is # specified. Set to NO to disable this. # See also: Section \class. # The default value is: YES. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all # compounds will be generated. Enable this if the project contains a lot of # classes, structs, unions or interfaces. # The default value is: YES. ALPHABETICAL_INDEX = YES # The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in # which the alphabetical index list will be split. # Minimum value: 1, maximum value: 20, default value: 5. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all classes will # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag # can be used to specify a prefix (or a list of prefixes) that should be ignored # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # it. # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). # The default value is: .html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a user-defined HTML header file for # each generated HTML page. If the tag is left blank doxygen will generate a # standard header. # # To get valid HTML the header file that includes any scripts and style sheets # that doxygen needs, which is dependent on the configuration options used (e.g. # the setting GENERATE_TREEVIEW). It is highly recommended to start with a # default header using # doxygen -w html new_header.html new_footer.html new_stylesheet.css # YourConfigFile # and then modify the file new_header.html. See also section "Doxygen usage" # for information on how to generate the default header that doxygen normally # uses. # Note: The header is subject to change so you typically have to regenerate the # default header when upgrading to a newer version of doxygen. For a description # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard # footer. See HTML_HEADER for more information on how to generate a default # footer and what special commands can be used inside the footer. See also # section "Doxygen usage" for information on how to generate the default footer # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of # the HTML output. If left blank doxygen will generate a default style sheet. # See also section "Doxygen usage" for information on how to generate the style # sheet that doxygen normally uses. # Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as # it is more robust and this tag (HTML_STYLESHEET) will in the future become # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined # cascading style sheets that are included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefore more robust against future updates. # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the # list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that the # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see # http://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use grayscales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the # luminance component of the colors in the HTML output. Values below 100 # gradually make the output lighter, whereas values above 100 make the output # darker. The value divided by 100 is the actual gamma applied, so 80 represents # a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not # change the gamma. # Minimum value: 40, maximum value: 240, default value: 80. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this # to YES can help to show when doxygen was last run and thus if the # documentation is up to date. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to # such a level that at most the specified number of entries are visible (unless # a fully collapsed tree already exceeds this amount). So setting the number of # entries 1 will produce a full collapsed tree by default. 0 is a special value # representing an infinite number of entries and will result in a full expanded # tree by default. # Minimum value: 0, maximum value: 9999, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development # environment (see: http://developer.apple.com/tools/xcode/), introduced with # OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a # Makefile in the HTML output directory. Running make will produce the docset in # that directory and running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at # startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO # This tag determines the name of the docset feed. A documentation feed provides # an umbrella under which multiple documentation sets from a single provider # (such as a company or product suite) can be grouped. # The default value is: Doxygen generated docs. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project # The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. # The default value is: org.doxygen.Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. # The default value is: Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop # (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on # Windows. # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML # files are now used as the Windows 98 help format, and will replace the old # Windows help format (.hlp) on all Windows platforms in the future. Compressed # HTML files also contain an index, a table of contents, and you can search for # words in the documentation. The HTML workshop also contains a viewer for # compressed HTML files. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = NO # The CHM_FILE tag can be used to specify the file name of the resulting .chm # file. You can add a path in front of the file if the result should not be # written to the html output directory. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler (hhc.exe). If non-empty, # doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated # (YES) or that it should be included in the master .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO # The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated # (YES) or a normal table of contents (NO) in the .chm file. Furthermore it # enables the Previous and Next buttons. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members to # the table of contents of the HTML help documentation and to the tree view. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help # (.qch) of the generated HTML documentation. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify # the file name of the resulting .qch file. The path specified is relative to # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace # (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual # Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- # folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location of Qt's # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the # generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To # install this plugin and make it available under the help contents menu in # Eclipse, the contents of the directory containing the HTML and XML files needs # to be copied into the plugins directory of eclipse. The name of the directory # within the plugins directory should be the same as the ECLIPSE_DOC_ID value. # After copying Eclipse needs to be restarted before the help appears. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO # A unique identifier for the Eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have this # name. Each documentation set should have its own identifier. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project # If you want full control over the layout of the generated HTML pages it might # be necessary to disable the index and replace it with your own. The # DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top # of each HTML page. A value of NO enables the index and the value YES disables # it. Since the tabs in the index contain the same information as the navigation # tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. If the tag # value is set to YES, a side panel will be generated containing a tree-like # index structure (just like the one that is generated for HTML Help). For this # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can # further fine-tune the look of the index. As an example, the default style # sheet generated by doxygen has an example that shows how to put an image at # the root of the tree instead of the PROJECT_NAME. Since the tree basically has # the same information as the tab index, you could consider setting # DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # # Note that a value of 0 will completely suppress the enum values from appearing # in the overview section. # Minimum value: 0, maximum value: 20, default value: 4. # This tag requires that the tag GENERATE_HTML is set to YES. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used # to set the initial width (in pixels) of the frame in which the tree is shown. # Minimum value: 0, maximum value: 1500, default value: 250. # This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 250 # If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML # output directory to force them to be regenerated. # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are not # supported properly for IE 6.0, but are supported on all modern browsers. # # Note that when changing this option you need to delete any form_*.png files in # the HTML output directory before the changes have effect. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # http://www.mathjax.org) which uses client side Javascript for the rendering # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # the MathJax output. See the MathJax site (see: # http://docs.mathjax.org/en/latest/output.html) for more details. # Possible values are: HTML-CSS (which is slower, but has the best # compatibility), NativeMML (i.e. MathML) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the HTML # output directory using the MATHJAX_RELPATH option. The destination directory # should contain the MathJax.js script. For instance, if the mathjax directory # is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of # MathJax from http://www.mathjax.org before deployment. # The default value is: http://cdn.mathjax.org/mathjax/latest. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site # (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and # should work on any modern browser. Note that when using HTML help # (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) # there is already a search function so this one should typically be disabled. # For large projects the javascript based search engine can be slow, then # enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to # search using the keyboard; to jump to the search box use + S # (what the is depends on the OS and browser, but it is typically # , /