aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2014-08-25 19:13:37 +0300
committerSergey Poznyakoff <gray@gnu.org>2014-08-25 19:20:00 +0300
commite26cb120ffe5f7303ddd8b514246ac6874e83f9f (patch)
tree64ca646b34103a5e8934b42fbbd9ca732a14e034
parent713bc0ca4b4ea3114d33f06c57c117de7f9fef11 (diff)
downloaddirevent-e26cb120ffe5f7303ddd8b514246ac6874e83f9f.tar.gz
direvent-e26cb120ffe5f7303ddd8b514246ac6874e83f9f.tar.bz2
I18N
* .gitignore: Add am * bootstrap: Create am, unless exists. * Makefile.am (SUBDIRS): Add po * acinclude.m4: New file. * configure.ac: Use gettext * doc/direvent.texi: Update * po/.gitignore: New file * po/POTFILES.in: New file. * po/Makevars: New file. * src/Makefile.am (LDADD): Add @LIBINTL@ (noinst_HEADERS): Add gettext.h * src/config.c: gettextize * src/direvent.c: Likewise. * src/environ.c: Likewise. * src/hashtab.c: Likewise. * src/progman.c: Likewise. * src/watcher.c: Likewise. * src/gettext.h: New file. * src/direvent.h: Add missing prototypes. * tests/re05.at: Remove superfluous quoting.
-rw-r--r--.gitignore1
-rw-r--r--Makefile.am6
-rw-r--r--acinclude.m444
-rwxr-xr-xbootstrap1
-rw-r--r--configure.ac9
-rw-r--r--doc/direvent.texi12
m---------grecs0
-rw-r--r--po/.gitignore20
-rw-r--r--po/Makevars41
-rw-r--r--po/POTFILES.in9
-rw-r--r--src/Makefile.am3
-rw-r--r--src/config.c103
-rw-r--r--src/direvent.c16
-rw-r--r--src/direvent.h13
-rw-r--r--src/environ.c3
-rw-r--r--src/gettext.h280
-rw-r--r--src/hashtab.c6
-rw-r--r--src/progman.c32
-rw-r--r--src/watcher.c28
-rw-r--r--tests/re05.at2
20 files changed, 524 insertions, 105 deletions
diff --git a/.gitignore b/.gitignore
index 0417a59..771518c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,6 +14,7 @@ Makefile
Makefile.in
TAGS
aclocal.m4
+am
autom4te.cache
build-aux
config.h
diff --git a/Makefile.am b/Makefile.am
index ea87088..9b13324 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -14,9 +14,9 @@
# You should have received a copy of the GNU General Public License
# along with Direvent. If not, see <http://www.gnu.org/licenses/>.
-ACLOCAL_AMFLAGS = -I grecs/am
+ACLOCAL_AMFLAGS = -I am -I grecs/am
-SUBDIRS=grecs src tests doc
+SUBDIRS= grecs src tests doc po
.PHONY: ChangeLog
ChangeLog:
@@ -25,3 +25,5 @@ ChangeLog:
awk -f $(top_builddir)/grecs/build-aux/git2chg.awk > ChangeLog; \
fi
+
+EXTRA_DIST = build-aux/config.rpath
diff --git a/acinclude.m4 b/acinclude.m4
new file mode 100644
index 0000000..31651bc
--- /dev/null
+++ b/acinclude.m4
@@ -0,0 +1,44 @@
+# This file is part of Direvent -*- autoconf -*-
+# Copyright (C) 2012-2014 Sergey Poznyakoff
+#
+# Direvent 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.
+#
+# Direvent 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 Direvent. If not, see <http://www.gnu.org/licenses/>.
+
+AC_DEFUN([DEVT_CC_OPT],[
+ m4_pushdef([devt_optname],translit($1,[-],[_]))
+ AC_MSG_CHECKING(whether $CC accepts $1)
+ devt_save_cc="$CC"
+ CC="$CC $1"
+ AC_TRY_RUN([int main() { return 0; }],
+ [devt_cv_cc_]devt_optname=yes,
+ [devt_cv_cc_]devt_optname=no,
+ [devt_cv_cc_]devt_optname=no)
+ CC="$devt_save_cc"
+ AC_MSG_RESULT($[devt_cv_cc_]devt_optname)
+
+ if test $[devt_cv_cc_]devt_optname = yes; then
+ ifelse([$2],,:,[$2])
+ ifelse([$3],,,else
+ [$3])
+ fi
+ m4_popdef([devt_optname])
+ ])
+
+AC_DEFUN([DEVT_CC_OPT_CFLAGS],[
+ DEVT_CC_OPT([$1],[CFLAGS="$CFLAGS $1"])
+])
+
+AC_DEFUN([DEVT_CC_PAREN_QUIRK],[
+ DEVT_CC_OPT_CFLAGS([-Wno-parentheses])
+])
+
diff --git a/bootstrap b/bootstrap
index ae677ac..8a0292b 100755
--- a/bootstrap
+++ b/bootstrap
@@ -1,5 +1,6 @@
#! /bin/sh
set -e
+test -d am || mkdir am
git submodule init
git submodule update
autoreconf -f -i -s
diff --git a/configure.ac b/configure.ac
index c4060d8..57cda4b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -28,6 +28,7 @@ AM_SILENT_RULES([yes])
# Checks for programs.
AC_PROG_AWK
AC_PROG_CC
+DEVT_CC_PAREN_QUIRK
AC_PROG_RANLIB
AC_PROG_INSTALL
AC_PROG_MAKE_SET
@@ -65,10 +66,16 @@ AH_TOP([
# Grecs subsystem
GRECS_SETUP([grecs],[tree-api git2chg no-preproc getopt tests])
+GRECS_HOST_PROJECT_INCLUDES='-I$(top_srcdir)/src'
+
+# Gettext.
+AM_ICONV
+AM_GNU_GETTEXT([external], [need-formatstring-macros])
+AM_GNU_GETTEXT_VERSION([0.18])
# Initialize the test suite.
AC_CONFIG_TESTDIR(tests)
-AC_CONFIG_FILES([tests/Makefile tests/atlocal])
+AC_CONFIG_FILES([tests/Makefile tests/atlocal po/Makefile.in])
AM_MISSING_PROG([AUTOM4TE], [autom4te])
AC_CONFIG_COMMANDS([status],[
diff --git a/doc/direvent.texi b/doc/direvent.texi
index 46b9a35..104ced0 100644
--- a/doc/direvent.texi
+++ b/doc/direvent.texi
@@ -4,7 +4,7 @@
@setfilename direvent.info
@settitle GNU Direvent
@c %**end of header
-@setchapternewpage odd
+@c @setchapternewpage odd
@defcodeindex pr
@defcodeindex op
@@ -112,7 +112,7 @@ and system-independent command-level interface. As of version
@GNUDIREVENT{} monitors a set of directories on the file system and
reacts when a file system event occurs in any of them. Directories
and events to monitor are specified in the configuration file. When
-an event occurs the utility reacts by invoking an external command
+an event occurs, the program reacts by invoking an external command
configured for that event.
@cindex events
@@ -146,7 +146,7 @@ ownership, mode, link count, etc.
@cindex watcher, introduced
@cindex handler, introduced
-A @dfn{watcher} is a configuration entity which associates a set of
+A @dfn{watcher} is a configuration entity that associates a set of
directories with a set of events and instructs @command{direvent} to
run a specified external command when any of these events occur in any
of these directories. This external command (called a @dfn{handler})
@@ -181,16 +181,18 @@ statement is a collection of statements enclosed in curly braces.
The following block statement declares a watcher:
@example
+@group
watcher @{
path @var{pathname} [recursive [@var{level}]];
+ file @var{pattern-list};
event @var{event-list};
command @var{command-line};
- file @var{pattern-list};
user @var{name};
timeout @var{number};
environ @var{env-spec};
option @var{string-list};
@}
+@end group
@end example
Each @code{watcher} statement instructs @command{direvent} to monitor
@@ -236,7 +238,7 @@ watcher @{
@end example
On this event, the watcher is to invoke @file{/usr/bin/upload}
-with the name of created file as an argument. To make it
+with the name of the created file as an argument. To make it
possible, the @command{direvent} configuration file provides @dfn{macro
variables}, which can be used in the @code{command} argument at
configuration time and which are expanded to the actual values before
diff --git a/grecs b/grecs
-Subproject 57a00b140954a2c22ba2fdebc93e8e6eda41b2a
+Subproject 477701c059d73e47aa1bac97e96d801542f2bd8
diff --git a/po/.gitignore b/po/.gitignore
new file mode 100644
index 0000000..32545fd
--- /dev/null
+++ b/po/.gitignore
@@ -0,0 +1,20 @@
+*.gmo
+*.po
+*.po~
+.pot
+.reference/
+LINGUAS
+Makefile.in.in
+Makevars.template
+POTFILES
+Rules-quot
+boldquot.sed
+en@boldquot.header
+en@quot.header
+insert-header.sed
+insert-header.sin
+direvent.pot
+quot.sed
+remove-potcdate.sed
+remove-potcdate.sin
+stamp-po
diff --git a/po/Makevars b/po/Makevars
new file mode 100644
index 0000000..33b0663
--- /dev/null
+++ b/po/Makevars
@@ -0,0 +1,41 @@
+# Makefile variables for PO directory in any package using GNU gettext.
+
+# Usually the message domain is the same as the package name.
+DOMAIN = $(PACKAGE)
+
+# These two variables depend on the location of this directory.
+subdir = po
+top_builddir = ..
+
+# These options get passed to xgettext.
+XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
+
+# This is the copyright holder that gets inserted into the header of the
+# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
+# package. (Note that the msgstr strings, extracted from the package's
+# sources, belong to the copyright holder of the package.) Translators are
+# expected to transfer the copyright for their translations to this person
+# or entity, or to disclaim their copyright. The empty string stands for
+# the public domain; in this case the translators are expected to disclaim
+# their copyright.
+COPYRIGHT_HOLDER = Sergey Poznyakoff
+
+# This is the email address or URL to which the translators shall report
+# bugs in the untranslated strings:
+# - Strings which are not entire sentences, see the maintainer guidelines
+# in the GNU gettext documentation, section 'Preparing Strings'.
+# - Strings which use unclear terms or require additional context to be
+# understood.
+# - Strings which make invalid assumptions about notation of date, time or
+# money.
+# - Pluralisation problems.
+# - Incorrect English spelling.
+# - Incorrect formatting.
+# It can be your email address, or a mailing list address where translators
+# can write to without being subscribed, or the URL of a web page through
+# which the translators can contact you.
+MSGID_BUGS_ADDRESS = bug-direvent@gnu.org.ua
+
+# This is the list of locale categories, beyond LC_MESSAGES, for which the
+# message catalogs shall be used. It is usually empty.
+EXTRA_LOCALE_CATEGORIES =
diff --git a/po/POTFILES.in b/po/POTFILES.in
new file mode 100644
index 0000000..5029ee6
--- /dev/null
+++ b/po/POTFILES.in
@@ -0,0 +1,9 @@
+# List of source files which contain translatable strings.
+
+src/cmdline.h
+src/config.c
+src/direvent.c
+src/environ.c
+src/hashtab.c
+src/progman.c
+src/watcher.c
diff --git a/src/Makefile.am b/src/Makefile.am
index c7f1439..8bdf610 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -41,11 +41,12 @@ else
endif
endif
-LDADD=@GRECS_LDADD@
+LDADD=@GRECS_LDADD@ @LIBINTL@
AM_CPPFLAGS=-I$(top_srcdir)/grecs/src/
BUILT_SOURCES=cmdline.h
EXTRA_DIST=cmdline.opt
+noinst_HEADERS=gettext.h
SUFFIXES=.opt .c .h
.opt.h:
diff --git a/src/config.c b/src/config.c
index 9c17124..82262a8 100644
--- a/src/config.c
+++ b/src/config.c
@@ -60,7 +60,7 @@ get_facility(const char *arg)
if (*p == 0 && errno == 0)
return f;
if (trans_strtotok(kwfac, arg, &f)) {
- diag(LOG_CRIT, "unknown syslog facility: %s", arg);
+ diag(LOG_CRIT, _("unknown syslog facility: %s"), arg);
exit(1);
}
return f;
@@ -77,7 +77,7 @@ get_priority(const char *arg)
if (*p == 0 && errno == 0)
return f;
if (trans_strtotok(kwpri, arg, &f)) {
- diag(LOG_CRIT, "unknown syslog priority: %s", arg);
+ diag(LOG_CRIT, _("unknown syslog priority: %s"), arg);
exit(1);
}
return f;
@@ -85,7 +85,7 @@ get_priority(const char *arg)
#define ASSERT_SCALAR(cmd, locus) \
if ((cmd) != grecs_callback_set_value) { \
- grecs_error(locus, 0, "Unexpected block statement"); \
+ grecs_error(locus, 0, _("unexpected block statement")); \
return 1; \
}
@@ -94,12 +94,12 @@ assert_grecs_value_type(grecs_locus_t *locus,
const grecs_value_t *value, int type)
{
if (GRECS_VALUE_EMPTY_P(value)) {
- grecs_error(locus, 0, "expected %s",
+ grecs_error(locus, 0, _("expected %s"),
grecs_data_type_string(type));
return 1;
}
if (value->type != type) {
- grecs_error(locus, 0, "expected %s, but found %s",
+ grecs_error(locus, 0, _("expected %s, but found %s"),
grecs_data_type_string(type),
grecs_data_type_string(value->type));
return 1;
@@ -121,7 +121,7 @@ cb_syslog_facility(enum grecs_callback_command cmd, grecs_node_t *node,
if (trans_strtotok(kwfac, value->v.string, &fac))
grecs_error(&value->locus, 0,
- "Unknown syslog facility `%s'",
+ _("unknown syslog facility `%s'"),
value->v.string);
else
*(int*)varptr = fac;
@@ -130,17 +130,17 @@ cb_syslog_facility(enum grecs_callback_command cmd, grecs_node_t *node,
static struct grecs_keyword syslog_kw[] = {
{ "facility",
- "name",
- "Set syslog facility. Arg is one of the following: user, daemon, "
- "auth, authpriv, mail, cron, local0 through local7 "
- "(case-insensitive), or a facility number.",
+ N_("name"),
+ N_("Set syslog facility. Arg is one of the following: user, daemon, "
+ "auth, authpriv, mail, cron, local0 through local7 "
+ "(case-insensitive), or a facility number."),
grecs_type_string, GRECS_DFLT,
&facility, 0, cb_syslog_facility },
- { "tag", "string", "Tag syslog messages with this string",
+ { "tag", N_("string"), N_("Tag syslog messages with this string"),
grecs_type_string, GRECS_DFLT,
&tag },
- { "print-priority", "arg",
- "Prefix each message with its priority",
+ { "print-priority", N_("arg"),
+ N_("Prefix each message with its priority"),
grecs_type_bool, GRECS_DFLT,
&syslog_include_prio },
{ NULL },
@@ -207,7 +207,7 @@ eventconf_flush(grecs_locus_t *loc)
for (hp = dwp->handler_list; hp; prev = hp, hp = hp->next) {
if (strcmp(dwp->dirname, pe->path) == 0) {
grecs_error(loc, 0,
- "ignoring duplicate definition");
+ _("ignoring duplicate definition"));
return;
}
}
@@ -241,15 +241,16 @@ cb_watcher(enum grecs_callback_command cmd, grecs_node_t *node,
switch (cmd) {
case grecs_callback_section_begin:
- eventconf_init(&node->locus);
+ eventconf_init();
break;
case grecs_callback_section_end:
if (!eventconf.pathlist) {
- grecs_error(&node->locus, 0, "no paths configured");
+ grecs_error(&node->locus, 0, _("no paths configured"));
++err;
}
if (!eventconf.command) {
- grecs_error(&node->locus, 0, "no command configured");
+ grecs_error(&node->locus, 0,
+ _("no command configured"));
++err;
}
if (evtnullp(&eventconf.eventmask))
@@ -260,7 +261,8 @@ cb_watcher(enum grecs_callback_command cmd, grecs_node_t *node,
eventconf_free();
break;
case grecs_callback_set_value:
- grecs_error(&node->locus, 0, "invalid use of block statement");
+ grecs_error(&node->locus, 0,
+ _("invalid use of block statement"));
}
return 0;
}
@@ -305,7 +307,7 @@ cb_path(enum grecs_callback_command cmd, grecs_node_t *node,
return 1;
if (strcmp(val->v.arg.v[1]->v.string, "recursive")) {
grecs_error(&val->v.arg.v[1]->locus, 0,
- "expected \"recursive\" or end of statement");
+ _("expected \"recursive\" or end of statement"));
return 1;
}
switch (val->v.arg.c) {
@@ -320,13 +322,13 @@ cb_path(enum grecs_callback_command cmd, grecs_node_t *node,
break;
default:
grecs_error(&val->v.arg.v[3]->locus, 0,
- "surplus argument");
+ _("surplus argument"));
return 1;
}
s = val->v.arg.v[0]->v.string;
break;
case GRECS_TYPE_LIST:
- grecs_error(locus, 0, "unexpected list");
+ grecs_error(locus, 0, _("unexpected list"));
return 1;
}
pe = pathent_alloc(s, depth);
@@ -357,7 +359,7 @@ cb_eventlist(enum grecs_callback_command cmd, grecs_node_t *node,
case GRECS_TYPE_STRING:
if (getevt(val->v.string, &m)) {
grecs_error(&val->locus, 0,
- "unrecognized event code");
+ _("unrecognized event code"));
return 1;
}
mask->gen_mask |= m.gen_mask;
@@ -372,7 +374,7 @@ cb_eventlist(enum grecs_callback_command cmd, grecs_node_t *node,
return 1;
if (getevt(val->v.arg.v[i]->v.string, &m)) {
grecs_error(&val->v.arg.v[i]->locus, 0,
- "unrecognized event code");
+ _("unrecognized event code"));
return 1;
}
mask->gen_mask |= m.gen_mask;
@@ -387,7 +389,7 @@ cb_eventlist(enum grecs_callback_command cmd, grecs_node_t *node,
return 1;
if (getevt(vp->v.string, &m)) {
grecs_error(&vp->locus, 0,
- "unrecognized event code");
+ _("unrecognized event code"));
return 1;
}
mask->gen_mask |= m.gen_mask;
@@ -469,7 +471,7 @@ cb_user(enum grecs_callback_command cmd, grecs_node_t *node,
grecs_locus_t loc;
loc.beg = val->v.arg.v[2]->locus.beg;
loc.end = val->v.arg.v[val->v.arg.c - 1]->locus.end;
- grecs_error(&loc, 0, "surplus arguments");
+ grecs_error(&loc, 0, _("surplus arguments"));
return 1;
}
uv = val->v.arg.v[0];
@@ -477,20 +479,20 @@ cb_user(enum grecs_callback_command cmd, grecs_node_t *node,
break;
case GRECS_TYPE_LIST:
- grecs_error(locus, 0, "unexpected list");
+ grecs_error(locus, 0, _("unexpected list"));
return 1;
}
pw = getpwnam(uv->v.string);
if (!pw) {
- grecs_error(&uv->locus, 0, "no such user");
+ grecs_error(&uv->locus, 0, _("no such user"));
return 1;
}
if (gv) {
gr = getgrnam(gv->v.string);
if (!gr) {
- grecs_error(&gv->locus, 0, "no such group");
+ grecs_error(&gv->locus, 0, _("no such group"));
return 1;
}
gid = gr->gr_gid;
@@ -529,7 +531,7 @@ cb_option(enum grecs_callback_command cmd, grecs_node_t *node,
else if (strcmp(vp->v.string, "stderr") == 0)
eventconf.flags |= HF_STDERR;
else
- grecs_error(&vp->locus, 0, "unrecognized flag");
+ grecs_error(&vp->locus, 0, _("unrecognized flag"));
}
return 0;
}
@@ -607,7 +609,7 @@ file_name_pattern(struct grecs_list *lp, grecs_value_t *val)
p = strchr(arg+1, '/');
if (!p) {
- grecs_error(&val->locus, 0, "Unterminated regexp");
+ grecs_error(&val->locus, 0, _("unterminated regexp"));
free(pat);
return 1;
}
@@ -621,7 +623,7 @@ file_name_pattern(struct grecs_list *lp, grecs_value_t *val)
break;
default:
grecs_error(&val->locus, 0,
- "Unrecognized flag: %c", *q);
+ _("unrecognized flag: %c"), *q);
free(pat);
return 1;
}
@@ -689,43 +691,44 @@ cb_file_pattern(enum grecs_callback_command cmd, grecs_node_t *node,
}
static struct grecs_keyword watcher_kw[] = {
- { "path", NULL, "Pathname to watch",
+ { "path", NULL, N_("Pathname to watch"),
grecs_type_string, GRECS_DFLT, &eventconf.pathlist, 0,
cb_path },
- { "event", NULL, "Events to watch for",
+ { "event", NULL, N_("Events to watch for"),
grecs_type_string, GRECS_LIST, &eventconf.eventmask, 0,
cb_eventlist },
- { "file", "regexp", "Files to watch for",
+ { "file", N_("regexp"), N_("Files to watch for"),
grecs_type_string, GRECS_LIST, &eventconf.fnames, 0,
cb_file_pattern },
- { "command", NULL, "Command to execute on event",
+ { "command", NULL, N_("Command to execute on event"),
grecs_type_string, GRECS_DFLT, &eventconf.command },
- { "user", "name", "Run command as this user",
+ { "user", N_("name"), N_("Run command as this user"),
grecs_type_string, GRECS_DFLT, NULL, 0,
cb_user },
- { "timeout", "seconds", "Timeout for the command",
+ { "timeout", N_("seconds"), N_("Timeout for the command"),
grecs_type_uint, GRECS_DFLT, &eventconf.timeout },
- { "option", NULL, "List of additional options",
+ { "option", NULL, N_("List of additional options"),
grecs_type_string, GRECS_LIST, NULL, 0,
cb_option },
- { "environ", "<arg: string> <arg: string>...", "Modify environment",
+ { "environ", N_("<arg: string> <arg: string>..."),
+ N_("Modify environment"),
grecs_type_string, GRECS_DFLT, NULL, 0,
cb_environ },
{ NULL }
};
static struct grecs_keyword direvent_kw[] = {
- { "user", NULL, "Run as this user",
+ { "user", NULL, N_("Run as this user"),
grecs_type_string, GRECS_DFLT, &user },
- { "foreground", NULL, "Run in foreground",
+ { "foreground", NULL, N_("Run in foreground"),
grecs_type_bool, GRECS_DFLT, &foreground },
- { "pidfile", "file", "Set pid file name",
+ { "pidfile", N_("file"), N_("Set pid file name"),
grecs_type_string, GRECS_DFLT, &pidfile },
- { "syslog", NULL, "Configure syslog logging",
+ { "syslog", NULL, N_("Configure syslog logging"),
grecs_type_section, GRECS_DFLT, NULL, 0, NULL, NULL, syslog_kw },
- { "debug", "level", "Set debug level",
+ { "debug", N_("level"), N_("Set debug level"),
grecs_type_int, GRECS_DFLT, &debug_level },
- { "watcher", NULL, "Configure event watcher",
+ { "watcher", NULL, N_("Configure event watcher"),
grecs_type_section, GRECS_DFLT, NULL, 0,
cb_watcher, NULL, watcher_kw },
{ NULL }
@@ -736,19 +739,13 @@ void
config_help()
{
static char docstring[] =
- "Configuration file structure for direvent.\n"
- "For more information, use `info direvent configuration'.";
+ N_("Configuration file structure for direvent.\n"
+ "For more information, use `info direvent configuration'.");
grecs_print_docstring(docstring, 0, stdout);
grecs_print_statement_array(direvent_kw, 1, 0, stdout);
}
void
-config_init()
-{
- grecs_log_to_stderr = 1;
-}
-
-void
config_finish(struct grecs_node *tree)
{
if (grecs_tree_process(tree, direvent_kw))
diff --git a/src/direvent.c b/src/direvent.c
index 7cdd2c1..9dca000 100644
--- a/src/direvent.c
+++ b/src/direvent.c
@@ -138,7 +138,7 @@ emalloc(size_t size)
{
void *p = malloc(size);
if (!p) {
- diag(LOG_CRIT, "not enough memory");
+ diag(LOG_CRIT, _("not enough memory"));
exit(2);
}
return p;
@@ -160,7 +160,7 @@ erealloc(void *ptr, size_t size)
{
void *p = realloc(ptr, size);
if (!p) {
- diag(LOG_CRIT, "not enough memory");
+ diag(LOG_CRIT, _("not enough memory"));
exit(2);
}
return p;
@@ -268,7 +268,7 @@ storepid(const char *pidfile)
{
FILE *fp = fopen(pidfile, "w");
if (!fp) {
- diag(LOG_ERR, "cannot open pidfile %s for writing: %s",
+ diag(LOG_ERR, _("cannot open pidfile %s for writing: %s"),
pidfile, strerror(errno));
} else {
fprintf(fp, "%lu\n", (unsigned long) getpid());
@@ -296,7 +296,7 @@ get_user_groups(uid_t uid, size_t *pgidc, gid_t **pgidv)
pw = getpwuid(uid);
if (!pw) {
- diag(LOG_ERR, 0, "no used with UID %lu",
+ diag(LOG_ERR, 0, _("no used with UID %lu"),
(unsigned long)uid);
exit(2);
}
@@ -423,7 +423,7 @@ self_test()
pid = fork();
if (pid == (pid_t)-1) {
diag(LOG_CRIT,
- "cannot run `%s': fork failed: %s",
+ _("cannot run `%s': fork failed: %s"),
self_test_prog, strerror(errno));
exit(2);
}
@@ -473,7 +473,7 @@ main(int argc, char **argv)
switch (argc) {
default:
- diag(LOG_CRIT, "too many arguments");
+ diag(LOG_CRIT, _("too many arguments"));
exit(1);
case 1:
conffile = argv[0];
@@ -519,7 +519,7 @@ main(int argc, char **argv)
log_to_stderr = -1;
}
- diag(LOG_INFO, "%s %s started", program_name, VERSION);
+ diag(LOG_INFO, _("%s %s started"), program_name, VERSION);
/* Write pidfile */
if (pidfile)
@@ -540,7 +540,7 @@ main(int argc, char **argv)
process_cleanup(0);
}
- diag(LOG_INFO, "%s %s stopped", program_name, VERSION);
+ diag(LOG_INFO, _("%s %s stopped"), program_name, VERSION);
if (pidfile)
unlink(pidfile);
diff --git a/src/direvent.h b/src/direvent.h
index 33fa768..069d3d8 100644
--- a/src/direvent.h
+++ b/src/direvent.h
@@ -25,6 +25,11 @@
#include <signal.h>
#include <regex.h>
+#include "gettext.h"
+
+#define _(s) gettext(s)
+#define N_(s) s
+
/* Generic (system-independent) event codes */
#define GENEV_CREATE 0x01
#define GENEV_WRITE 0x02
@@ -189,7 +194,10 @@ struct pathent {
size_t len;
char path[1];
};
-
+
+void config_help(void);
+struct grecs_node;
+void config_finish(struct grecs_node *tree);
void config_parse(const char *file);
int get_facility(const char *arg);
@@ -207,6 +215,9 @@ char *split_pathname(struct dirwatcher *dp, char **dirname);
void unsplit_pathname(struct dirwatcher *dp);
void ev_log(int flags, struct dirwatcher *dp);
+void deliver_ev_create(struct dirwatcher *dp, const char *name);
+int subwatcher_create(struct dirwatcher *parent, const char *dirname,
+ int isdir, int notify);
struct process *process_lookup(pid_t pid);
void process_cleanup(int expect_term);
diff --git a/src/environ.c b/src/environ.c
index 5fbd0ac..f0fcce7 100644
--- a/src/environ.c
+++ b/src/environ.c
@@ -16,12 +16,13 @@
#include "direvent.h"
#include "wordsplit.h"
+#include <ctype.h>
extern char **environ; /* Environment */
#define DEBUG_ENVIRON(l,env) do { \
if (debug_level >= (l)) { \
- diag(LOG_DEBUG, "environment: "); \
+ diag(LOG_DEBUG, _("environment: ")); \
for (i = 0; (env)[i]; i++) \
diag(LOG_DEBUG, "%s ", (env)[i]); \
diag(LOG_DEBUG, "\n"); \
diff --git a/src/gettext.h b/src/gettext.h
new file mode 100644
index 0000000..e76b592
--- /dev/null
+++ b/src/gettext.h
@@ -0,0 +1,280 @@
+/* Convenience header for conditional use of GNU <libintl.h>.
+ Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009 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, 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA. */
+
+#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 <libintl.h>
+
+/* 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 <locale.h> a NOP. We don't include <libintl.h>
+ as well because people using "gettext.h" will not include <libintl.h>,
+ and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
+ is OK. */
+#if defined(__sun)
+# include <locale.h>
+#endif
+
+/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
+ <libintl.h>, which chokes if dcgettext is defined as a macro. So include
+ it now, to make later inclusions of <libintl.h> a NOP. */
+#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
+# include <cstdlib>
+# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
+# include <libintl.h>
+# 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
+
+/* 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