diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2014-08-25 19:13:37 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2014-08-25 19:20:00 +0300 |
commit | e26cb120ffe5f7303ddd8b514246ac6874e83f9f (patch) | |
tree | 64ca646b34103a5e8934b42fbbd9ca732a14e034 | |
parent | 713bc0ca4b4ea3114d33f06c57c117de7f9fef11 (diff) | |
download | direvent-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-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile.am | 6 | ||||
-rw-r--r-- | acinclude.m4 | 44 | ||||
-rwxr-xr-x | bootstrap | 1 | ||||
-rw-r--r-- | configure.ac | 9 | ||||
-rw-r--r-- | doc/direvent.texi | 12 | ||||
m--------- | grecs | 0 | ||||
-rw-r--r-- | po/.gitignore | 20 | ||||
-rw-r--r-- | po/Makevars | 41 | ||||
-rw-r--r-- | po/POTFILES.in | 9 | ||||
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/config.c | 103 | ||||
-rw-r--r-- | src/direvent.c | 16 | ||||
-rw-r--r-- | src/direvent.h | 13 | ||||
-rw-r--r-- | src/environ.c | 3 | ||||
-rw-r--r-- | src/gettext.h | 280 | ||||
-rw-r--r-- | src/hashtab.c | 6 | ||||
-rw-r--r-- | src/progman.c | 32 | ||||
-rw-r--r-- | src/watcher.c | 28 | ||||
-rw-r--r-- | tests/re05.at | 2 |
20 files changed, 524 insertions, 105 deletions
@@ -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]) +]) + @@ -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 |