+2001-03-04 Bruno Haible <haible@clisp.cons.org>
+
+ * dcigettext.c (ISSLASH, HAS_DEVICE, IS_ABSOLUTE_PATH,
+ IS_PATH_WITH_DIR): New macros.
+ (DCIGETTEXT): Use IS_ABSOLUTE_PATH and IS_PATH_WITH_DIR. Increment
+ path_max proportionally.
+ * loadinfo.h (PATH_SEPARATOR): New macro.
+ * l10nflist.c (_nl_make_l10nflist): Use PATH_SEPARATOR instead of ':'.
+ * localealias.c (_nl_expand_alias): Likewise.
+ * libgnuintl.h (gettext) [DJGPP]: Define as a macro as well.
+
2001-03-06 Bruno Haible <haible@clisp.cons.org>
* libgnuintl.h (LC_MESSAGES): Don't define on Solaris.
# define PATH_MAX _POSIX_PATH_MAX
#endif
+/* Pathname support.
+ ISSLASH(C) tests whether C is a directory separator character.
+ IS_ABSOLUTE_PATH(P) tests whether P is an absolute path. If it is not,
+ it may be concatenated to a directory pathname.
+ IS_PATH_WITH_DIR(P) tests whether P contains a directory specification.
+ */
+#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__
+ /* Win32, OS/2, DOS */
+# define ISSLASH(C) ((C) == '/' || (C) == '\\')
+# define HAS_DEVICE(P) \
+ ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \
+ && (P)[1] == ':')
+# define IS_ABSOLUTE_PATH(P) (ISSLASH ((P)[0]) || HAS_DEVICE (P))
+# define IS_PATH_WITH_DIR(P) \
+ (strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P))
+#else
+ /* Unix */
+# define ISSLASH(C) ((C) == '/')
+# define IS_ABSOLUTE_PATH(P) ISSLASH ((P)[0])
+# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL)
+#endif
+
/* XPG3 defines the result of `setlocale (category, NULL)' as:
``Directs `setlocale()' to query `category' and return the current
setting of `local'.''
if (binding == NULL)
dirname = (char *) _nl_default_dirname;
- else if (binding->dirname[0] == '/')
+ else if (IS_ABSOLUTE_PATH (binding->dirname))
dirname = binding->dirname;
else
{
path_max = (unsigned int) PATH_MAX;
path_max += 2; /* The getcwd docs say to do this. */
- dirname = (char *) alloca (path_max + dirname_len);
- ADD_BLOCK (block_list, dirname);
-
- __set_errno (0);
- while ((ret = getcwd (dirname, path_max)) == NULL && errno == ERANGE)
+ for (;;)
{
- path_max += PATH_INCR;
dirname = (char *) alloca (path_max + dirname_len);
ADD_BLOCK (block_list, dirname);
+
__set_errno (0);
+ ret = getcwd (dirname, path_max);
+ if (ret != NULL || errno != ERANGE)
+ break;
+
+ path_max += path_max / 2;
+ path_max += PATH_INCR;
}
if (ret == NULL)
/* When this is a SUID binary we must not allow accessing files
outside the dedicated directories. */
- if (ENABLE_SECURE && strchr (single_locale, '/') != NULL)
+ if (ENABLE_SECURE && IS_PATH_WITH_DIR (single_locale))
/* Ingore this entry. */
continue;
}
/* Construct file name. */
memcpy (abs_filename, dirlist, dirlist_len);
- __argz_stringify (abs_filename, dirlist_len, ':');
+ __argz_stringify (abs_filename, dirlist_len, PATH_SEPARATOR);
cp = abs_filename + (dirlist_len - 1);
*cp++ = '/';
cp = stpcpy (cp, language);
implementation of gettext. */
#define __USE_GNU_GETTEXT 1
+/* Resolve a platform specific conflict on DJGPP. GNU gettext takes
+ precedence over _conio_gettext. */
+#ifdef __DJGPP__
+# undef gettext
+# define gettext gettext
+#endif
+
#ifndef PARAMS
# if __STDC__ || defined __cplusplus
# define PARAMS(args) args
-/* Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1996-1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
# define __builtin_expect(expr, val) (expr)
#endif
+/* Separator in PATH like lists of pathnames. */
+#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__
+ /* Win32, OS/2, DOS */
+# define PATH_SEPARATOR ';'
+#else
+ /* Unix */
+# define PATH_SEPARATOR ':'
+#endif
+
/* Encoding of locale name parts. */
#define CEN_REVISION 1
#define CEN_SPONSOR 2
{
const char *start;
- while (locale_alias_path[0] == ':')
+ while (locale_alias_path[0] == PATH_SEPARATOR)
++locale_alias_path;
start = locale_alias_path;
- while (locale_alias_path[0] != '\0' && locale_alias_path[0] != ':')
+ while (locale_alias_path[0] != '\0'
+ && locale_alias_path[0] != PATH_SEPARATOR)
++locale_alias_path;
if (start < locale_alias_path)
+2001-03-04 Bruno Haible <haible@clisp.cons.org>
+
+ * system.h (ISSLASH, HAS_DEVICE, IS_ABSOLUTE_PATH, IS_PATH_WITH_DIR,
+ FILESYSTEM_PREFIX_LEN): New macros.
+ (concatenated_pathname): New declaration.
+ (SET_BINARY): New macro.
+ * concatpath.c: New file.
+ * Makefile.am (libnlsut_a_SOURCES): Add concatpath.c.
+
2001-03-03 Bruno Haible <haible@clisp.cons.org>
* gen-lbrkprop.c: New file.
strcspn.c strncasecmp.c strstr.c strtol.c strtoul.c vasprintf.c \
gen-lbrkprop.c 3level.h
-libnlsut_a_SOURCES = basename.c c-ctype.c fstrcmp.c getopt.c getopt1.c \
-hash.c linebreak.c localcharset.c obstack.c xgetcwd.c xmalloc.c xstrdup.c
+libnlsut_a_SOURCES = basename.c c-ctype.c concatpath.c fstrcmp.c \
+getopt.c getopt1.c hash.c linebreak.c localcharset.c obstack.c xgetcwd.c \
+xmalloc.c xstrdup.c
libnlsut_a_LIBADD = @ALLOCA@ @LIBOBJS@
--- /dev/null
+/* Construct a full pathname from a directory and a filename.
+ Copyright (C) 2001 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 2, 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA. */
+
+/* Written by Bruno Haible <haible@clisp.cons.org>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "system.h"
+
+/* Concatenate a directory pathname, a relative pathname and an optional
+ suffix. The directory may end with the directory separator. The second
+ argument may not start with the directory separator (it is relative).
+ Return a freshly allocated pathname. */
+char *
+concatenated_pathname (directory, filename, suffix)
+ const char *directory;
+ const char *filename;
+ const char *suffix;
+{
+ char *result;
+ char *p;
+
+ if (strcmp (directory, ".") == 0)
+ {
+ /* No need to prepend the directory. */
+ result = (char *) xmalloc (strlen (filename)
+ + (suffix != NULL ? strlen (suffix) : 0)
+ + 1);
+ p = result;
+ }
+ else
+ {
+ size_t directory_len = strlen (directory);
+ int need_slash =
+ (directory_len > FILESYSTEM_PREFIX_LEN (directory)
+ && !ISSLASH (directory[directory_len - 1]));
+ result = (char *) xmalloc (directory_len + need_slash
+ + strlen (filename)
+ + (suffix != NULL ? strlen (suffix) : 0)
+ + 1);
+ memcpy (result, directory, directory_len);
+ p = result + directory_len;
+ if (need_slash)
+ *p++ = '/';
+ }
+ p = stpcpy (p, filename);
+ if (suffix != NULL)
+ stpcpy (p, suffix);
+ return result;
+}
#endif
+/* Pathname support.
+ ISSLASH(C) tests whether C is a directory separator character.
+ IS_ABSOLUTE_PATH(P) tests whether P is an absolute path. If it is not,
+ it may be concatenated to a directory pathname.
+ IS_PATH_WITH_DIR(P) tests whether P contains a directory specification.
+ */
+#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__
+ /* Win32, OS/2, DOS */
+# define ISSLASH(C) ((C) == '/' || (C) == '\\')
+# define HAS_DEVICE(P) \
+ ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \
+ && (P)[1] == ':')
+# define IS_ABSOLUTE_PATH(P) (ISSLASH ((P)[0]) || HAS_DEVICE (P))
+# define IS_PATH_WITH_DIR(P) \
+ (strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P))
+# define FILESYSTEM_PREFIX_LEN(P) (HAS_DEVICE (P) ? 2 : 0)
+#else
+ /* Unix */
+# define ISSLASH(C) ((C) == '/')
+# define IS_ABSOLUTE_PATH(P) ISSLASH ((P)[0])
+# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL)
+# define FILESYSTEM_PREFIX_LEN(P) 0
+#endif
+
+/* Concatenate a directory pathname, a relative pathname and an optional
+ suffix. Return a freshly allocated pathname. */
+extern char *concatenated_pathname PARAMS ((const char *directory,
+ const char *filename,
+ const char *suffix));
+
/* When not using the GNU libc we use the basename implementation we
provide here. */
#ifndef __GNU_LIBRARY__
# define setmode _setmode
# define fileno _fileno
# endif
+# ifdef __DJGPP__
+# include <io.h> /* declares setmode() */
+# include <unistd.h> /* declares isatty() */
+# /* Avoid putting stdin/stdout in binary mode if it is connected to the
+# console, because that would make it impossible for the user to
+# interrupt the program through Ctrl-C or Ctrl-Break. */
+# define SET_BINARY(fd) (!isatty(fd) ? (setmode(fd,O_BINARY), 0) : 0)
+# else
+# define SET_BINARY(fd) setmode(fd,O_BINARY)
+# endif
#else
-# define setmode(fd, mode) /* nothing */
+# define SET_BINARY(fd) /* nothing */
#endif
#endif
+2001-03-04 Bruno Haible <haible@clisp.cons.org>
+
+ * msgcomm.c (main): Use IS_ABSOLUTE_PATH and concatenated_pathname.
+ Fixes an incorrectly computed memory allocation.
+ * xgettext.c (main): Likewise.
+ * open-po.c (open_po_file): Use IS_ABSOLUTE_PATH and
+ concatenated_pathname.
+ * xget-lex.c (xgettext_lex_open): Likewise.
+ * msgfmt.c (main): Use SET_BINARY instead of setmode.
+ * msgunfmt.c (read_mo_file): Likewise.
+
2001-03-04 Bruno Haible <haible@clisp.cons.org>
Check syntax of obsolete entries of PO files, not only in msgmerge.
if (output_dir == NULL)
output_dir = ".";
- /* Construct the name of the ouput file. If the default domain has
+ /* Construct the name of the output file. If the default domain has
the special name "-" we write to stdout. */
if (output_file)
- {
- if (output_file[0] == '/' ||
- strcmp(output_dir, ".") == 0 ||
- strcmp(output_file, "-") == 0
- )
- file_name = xstrdup (output_file);
- else
{
- /* Please do NOT add a .po suffix! */
- file_name = xmalloc (strlen (output_dir) + strlen (default_domain) + 2);
- strcat (strcat (strcpy(file_name, output_dir), "/"), output_file);
+ if (IS_ABSOLUTE_PATH (output_file) || strcmp (output_file, "-") == 0)
+ file_name = xstrdup (output_file);
+ else
+ /* Please do NOT add a .po suffix! */
+ file_name = concatenated_pathname (output_dir, output_file, NULL);
}
- }
else if (strcmp (default_domain, "-") == 0)
file_name = "-";
else
- {
- file_name = (char *) xmalloc (strlen (output_dir)
- + strlen (default_domain)
- + sizeof (".po") + 2);
- stpcpy (stpcpy (stpcpy (stpcpy (file_name, output_dir), "/"),
- default_domain), ".po");
- }
+ file_name = concatenated_pathname (output_dir, default_domain, ".po");
/* Determine list of files we have to process. */
if (files_from != NULL)
if (mp->used > more_than && mp->used < less_than)
++j;
else
- message_list_delete_nth(mlp, j);
+ message_list_delete_nth (mlp, j);
}
/* Sorting the list of messages. */
size_t __msgstr_len,
lex_pos_ty *__msgstr_pos));
static void format_comment_special PARAMS ((po_ty *pop, const char *s));
-static void format_debrief PARAMS((po_ty *));
+static void format_debrief PARAMS ((po_ty *));
static struct msg_domain *new_domain PARAMS ((const char *name));
static int compare_id PARAMS ((const void *pval1, const void *pval2));
static void write_table PARAMS ((FILE *output_file, hash_table *tab));
int
-main(argc, argv)
+main (argc, argv)
int argc;
char *argv[];
{
if (strcmp (domain->domain_name, "-") == 0)
{
output_file = stdout;
- setmode (fileno (output_file), O_BINARY);
+ SET_BINARY (fileno (output_file));
}
else
{
if (strcmp (fn, "-") == 0 || strcmp (fn, "/dev/stdin") == 0)
{
fp = stdin;
- setmode (fileno (fp), O_BINARY);
+ SET_BINARY (fileno (fp));
}
else
{
FILE *ret_val;
int j, k;
const char *dir;
- const char *ext;
if (strcmp (input_name, "-") == 0 || strcmp (input_name, "/dev/stdin") == 0)
{
/* We have a real name for the input file. If the name is absolute,
try the various extensions, but ignore the directory search list. */
- if (*input_name == '/')
+ if (IS_ABSOLUTE_PATH (input_name))
{
for (k = 0; k < SIZEOF (extension); ++k)
{
- ext = extension[k];
- *file_name = xmalloc (strlen (input_name) + strlen (ext) + 1);
- stpcpy (stpcpy (*file_name, input_name), ext);
+ *file_name = concatenated_pathname ("", input_name, extension[k]);
ret_val = fopen (*file_name, "r");
if (ret_val != NULL || errno != ENOENT)
for (j = 0; (dir = dir_list_nth (j)) != NULL; ++j)
for (k = 0; k < SIZEOF (extension); ++k)
{
- ext = extension[k];
- if (dir[0] == '.' && dir[1] == '\0')
- {
- *file_name = xmalloc (strlen(input_name) + strlen(ext) + 1);
- stpcpy (stpcpy (*file_name, input_name), ext);
- }
- else
- {
- *file_name = xmalloc (strlen (dir) + strlen (input_name)
- + strlen (ext) + 2);
- stpcpy (stpcpy (stpcpy (stpcpy (*file_name, dir), "/"),
- input_name),
- ext);
- }
+ *file_name = concatenated_pathname (dir, input_name, extension[k]);
ret_val = fopen (*file_name, "r");
if (ret_val != NULL || errno != ENOENT)
logical_file_name = xstrdup (new_name);
fp = stdin;
}
- else if (*fn == '/')
+ else if (IS_ABSOLUTE_PATH (fn))
{
new_name = xstrdup (fn);
fp = fopen (fn, "r");
}
else
{
- size_t len1, len2;
int j;
- const char *dir;
- len2 = strlen (fn);
for (j = 0; ; ++j)
{
- dir = dir_list_nth (j);
+ const char *dir = dir_list_nth (j);
+
if (dir == NULL)
error (EXIT_FAILURE, ENOENT, _("\
error while opening \"%s\" for reading"), fn);
- if (dir[0] =='.' && dir[1] == '\0')
- new_name = xstrdup (fn);
- else
- {
- len1 = strlen (dir);
- new_name = xmalloc (len1 + len2 + 2);
- stpcpy (stpcpy (stpcpy (new_name, dir), "/"), fn);
- }
+ new_name = concatenated_pathname (dir, fn, NULL);
fp = fopen (new_name, "r");
if (fp != NULL)
if (output_dir == NULL)
output_dir = ".";
- /* Construct the name of the ouput file. If the default domain has
+ /* Construct the name of the output file. If the default domain has
the special name "-" we write to stdout. */
if (output_file)
{
- if (output_file[0] == '/' ||
- strcmp(output_dir, ".") == 0 || strcmp(output_file, "-") == 0)
+ if (IS_ABSOLUTE_PATH (output_file) || strcmp (output_file, "-") == 0)
file_name = xstrdup (output_file);
else
- {
- /* Please do NOT add a .po suffix! */
- file_name = xmalloc (strlen (output_dir)
- + strlen (default_domain) + 2);
- stpcpy (stpcpy (stpcpy (file_name, output_dir), "/"), output_file);
- }
+ /* Please do NOT add a .po suffix! */
+ file_name = concatenated_pathname (output_dir, output_file, NULL);
}
else if (strcmp (default_domain, "-") == 0)
file_name = "-";
else
- {
- file_name = (char *) xmalloc (strlen (output_dir)
- + strlen (default_domain)
- + sizeof (".po") + 2);
- stpcpy (stpcpy (stpcpy (stpcpy (file_name, output_dir), "/"),
- default_domain), ".po");
- }
+ file_name = concatenated_pathname (output_dir, default_domain, ".po");
/* Determine list of files we have to process. */
if (files_from != NULL)
static void
-scan_c_file(filename, mlp)
+scan_c_file (filename, mlp)
const char *filename;
message_list_ty *mlp;
{
table_ty *tp;
for (tp = table; tp < ENDOF(table); ++tp)
- {
- if (strcasecmp(name, tp->name) == 0)
+ if (strcasecmp (name, tp->name) == 0)
return tp->func;
- }
error (EXIT_FAILURE, 0, _("language `%s' unknown"), name);
/* NOTREACHED */
return NULL;
table_ty *tp;
for (tp = table; tp < ENDOF(table); ++tp)
- {
- if (strcmp(extension, tp->extension) == 0)
- return tp->language;
- }
+ if (strcmp (extension, tp->extension) == 0)
+ return tp->language;
return NULL;
}