Imported from ../bash-3.0.tar.gz.
This commit is contained in:
parent
7117c2d221
commit
b80f6443b6
400 changed files with 69247 additions and 13346 deletions
124
lib/glob/glob.c
124
lib/glob/glob.c
|
@ -62,6 +62,10 @@
|
|||
# endif /* __STDC__ */
|
||||
#endif /* !NULL */
|
||||
|
||||
#if !defined (FREE)
|
||||
# define FREE(x) if (x) free (x)
|
||||
#endif
|
||||
|
||||
extern void throw_to_top_level __P((void));
|
||||
extern int test_eaccess __P((char *, int));
|
||||
|
||||
|
@ -118,7 +122,6 @@ glob_pattern_p (pattern)
|
|||
const char *pattern;
|
||||
{
|
||||
#if HANDLE_MULTIBYTE
|
||||
mbstate_t ps;
|
||||
size_t n;
|
||||
wchar_t *wpattern;
|
||||
int r;
|
||||
|
@ -127,15 +130,14 @@ glob_pattern_p (pattern)
|
|||
return (internal_glob_pattern_p (pattern));
|
||||
|
||||
/* Convert strings to wide chars, and call the multibyte version. */
|
||||
memset (&ps, '\0', sizeof (ps));
|
||||
n = xmbsrtowcs (NULL, (const char **)&pattern, 0, &ps);
|
||||
n = xdupmbstowcs (&wpattern, NULL, pattern);
|
||||
if (n == (size_t)-1)
|
||||
/* Oops. Invalid multibyte sequence. Try it as single-byte sequence. */
|
||||
return (internal_glob_pattern_p (pattern));
|
||||
wpattern = (wchar_t *)xmalloc ((n + 1) * sizeof (wchar_t));
|
||||
(void) xmbsrtowcs (wpattern, (const char **)&pattern, n + 1, &ps);
|
||||
|
||||
r = internal_glob_wpattern_p (wpattern);
|
||||
free (wpattern);
|
||||
|
||||
return r;
|
||||
#else
|
||||
return (internal_glob_pattern_p (pattern));
|
||||
|
@ -174,50 +176,36 @@ static int
|
|||
mbskipname (pat, dname)
|
||||
char *pat, *dname;
|
||||
{
|
||||
char *pat_bak, *dn_bak;
|
||||
int ret;
|
||||
wchar_t *pat_wc, *dn_wc;
|
||||
mbstate_t pat_ps, dn_ps;
|
||||
size_t pat_n, dn_n, n;
|
||||
|
||||
n = strlen(pat);
|
||||
pat_bak = (char *) alloca (n + 1);
|
||||
memcpy (pat_bak, pat, n + 1);
|
||||
|
||||
n = strlen(dname);
|
||||
dn_bak = (char *) alloca (n + 1);
|
||||
memcpy (dn_bak, dname, n + 1);
|
||||
|
||||
memset(&pat_ps, '\0', sizeof(mbstate_t));
|
||||
memset(&dn_ps, '\0', sizeof(mbstate_t));
|
||||
|
||||
pat_n = xmbsrtowcs (NULL, (const char **)&pat_bak, 0, &pat_ps);
|
||||
dn_n = xmbsrtowcs (NULL, (const char **)&dn_bak, 0, &dn_ps);
|
||||
pat_n = xdupmbstowcs (&pat_wc, NULL, pat);
|
||||
dn_n = xdupmbstowcs (&dn_wc, NULL, dname);
|
||||
|
||||
ret = 0;
|
||||
if (pat_n != (size_t)-1 && dn_n !=(size_t)-1)
|
||||
{
|
||||
pat_wc = (wchar_t *) alloca ((pat_n + 1) * sizeof(wchar_t));
|
||||
dn_wc = (wchar_t *) alloca ((dn_n + 1) * sizeof(wchar_t));
|
||||
|
||||
(void) xmbsrtowcs (pat_wc, (const char **)&pat_bak, pat_n + 1, &pat_ps);
|
||||
(void) xmbsrtowcs (dn_wc, (const char **)&dn_bak, dn_n + 1, &dn_ps);
|
||||
|
||||
/* If a leading dot need not be explicitly matched, and the
|
||||
pattern doesn't start with a `.', don't match `.' or `..' */
|
||||
if (noglob_dot_filenames == 0 && pat_wc[0] != L'.' &&
|
||||
(pat_wc[0] != L'\\' || pat_wc[1] != L'.') &&
|
||||
(dn_wc[0] == L'.' &&
|
||||
(dn_wc[1] == L'\0' || (dn_wc[1] == L'.' && dn_wc[2] == L'\0'))))
|
||||
return 1;
|
||||
ret = 1;
|
||||
|
||||
/* If a leading dot must be explicity matched, check to see if the
|
||||
pattern and dirname both have one. */
|
||||
else if (noglob_dot_filenames && dn_wc[0] == L'.' &&
|
||||
pat_wc[0] != L'.' &&
|
||||
(pat_wc[0] != L'\\' || pat_wc[1] != L'.'))
|
||||
return 1;
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
FREE (pat_wc);
|
||||
FREE (dn_wc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
|
||||
|
@ -235,7 +223,7 @@ udequote_pathname (pathname)
|
|||
|
||||
pathname[j++] = pathname[i++];
|
||||
|
||||
if (!pathname[i - 1])
|
||||
if (pathname[i - 1] == 0)
|
||||
break;
|
||||
}
|
||||
pathname[j] = '\0';
|
||||
|
@ -250,22 +238,16 @@ wdequote_pathname (pathname)
|
|||
mbstate_t ps;
|
||||
size_t len, n;
|
||||
wchar_t *wpathname;
|
||||
char *pathname_bak;
|
||||
int i, j;
|
||||
wchar_t *orig_wpathname;
|
||||
|
||||
len = strlen (pathname);
|
||||
pathname_bak = (char *) alloca (len + 1);
|
||||
memcpy (pathname_bak, pathname , len + 1);
|
||||
|
||||
/* Convert the strings into wide characters. */
|
||||
memset (&ps, '\0', sizeof (ps));
|
||||
n = xmbsrtowcs (NULL, (const char **)&pathname_bak, 0, &ps);
|
||||
n = xdupmbstowcs (&wpathname, NULL, pathname);
|
||||
if (n == (size_t) -1)
|
||||
/* Something wrong. */
|
||||
return;
|
||||
|
||||
wpathname = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
|
||||
(void) xmbsrtowcs (wpathname, (const char **)&pathname_bak, n + 1, &ps);
|
||||
orig_wpathname = wpathname;
|
||||
|
||||
for (i = j = 0; wpathname && wpathname[i]; )
|
||||
{
|
||||
|
@ -274,7 +256,7 @@ wdequote_pathname (pathname)
|
|||
|
||||
wpathname[j++] = wpathname[i++];
|
||||
|
||||
if (!wpathname[i - 1])
|
||||
if (wpathname[i - 1] == L'\0')
|
||||
break;
|
||||
}
|
||||
wpathname[j] = L'\0';
|
||||
|
@ -283,6 +265,9 @@ wdequote_pathname (pathname)
|
|||
memset (&ps, '\0', sizeof(mbstate_t));
|
||||
n = wcsrtombs(pathname, (const wchar_t **)&wpathname, len, &ps);
|
||||
pathname[len] = '\0';
|
||||
|
||||
/* Can't just free wpathname here; wcsrtombs changes it in many cases. */
|
||||
free (orig_wpathname);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -373,6 +358,9 @@ glob_vector (pat, dir, flags)
|
|||
return ((char **) &glob_error_return);
|
||||
|
||||
nextlink = (struct globval *)alloca (sizeof (struct globval));
|
||||
if (nextlink == NULL)
|
||||
return ((char **) NULL);
|
||||
|
||||
nextlink->next = (struct globval *)0;
|
||||
nextname = (char *) malloc (1);
|
||||
if (nextname == 0)
|
||||
|
@ -418,10 +406,15 @@ glob_vector (pat, dir, flags)
|
|||
{
|
||||
free (nextname);
|
||||
nextlink = (struct globval *)alloca (sizeof (struct globval));
|
||||
nextlink->next = (struct globval *)0;
|
||||
lastlink = nextlink;
|
||||
nextlink->name = npat;
|
||||
count = 1;
|
||||
if (nextlink)
|
||||
{
|
||||
nextlink->next = (struct globval *)0;
|
||||
lastlink = nextlink;
|
||||
nextlink->name = npat;
|
||||
count = 1;
|
||||
}
|
||||
else
|
||||
lose = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -480,6 +473,11 @@ glob_vector (pat, dir, flags)
|
|||
if (REAL_DIR_ENTRY (dp) == 0)
|
||||
continue;
|
||||
|
||||
#if 0
|
||||
if (dp->d_name == 0 || *dp->d_name == 0)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
#if HANDLE_MULTIBYTE
|
||||
if (MB_CUR_MAX > 1 && mbskipname (pat, dp->d_name))
|
||||
continue;
|
||||
|
@ -490,14 +488,14 @@ glob_vector (pat, dir, flags)
|
|||
|
||||
if (strmatch (pat, dp->d_name, mflags) != FNM_NOMATCH)
|
||||
{
|
||||
nextlink = (struct globval *) alloca (sizeof (struct globval));
|
||||
nextlink->next = lastlink;
|
||||
nextname = (char *) malloc (D_NAMLEN (dp) + 1);
|
||||
if (nextname == NULL)
|
||||
nextlink = (struct globval *) alloca (sizeof (struct globval));
|
||||
if (nextlink == 0 || nextname == 0)
|
||||
{
|
||||
lose = 1;
|
||||
break;
|
||||
}
|
||||
nextlink->next = lastlink;
|
||||
lastlink = nextlink;
|
||||
nextlink->name = nextname;
|
||||
bcopy (dp->d_name, nextname, D_NAMLEN (dp) + 1);
|
||||
|
@ -631,6 +629,7 @@ glob_filename (pathname, flags)
|
|||
unsigned int result_size;
|
||||
char *directory_name, *filename;
|
||||
unsigned int directory_len;
|
||||
int free_dirname; /* flag */
|
||||
|
||||
result = (char **) malloc (sizeof (char *));
|
||||
result_size = 1;
|
||||
|
@ -639,6 +638,8 @@ glob_filename (pathname, flags)
|
|||
|
||||
result[0] = NULL;
|
||||
|
||||
directory_name = NULL;
|
||||
|
||||
/* Find the filename. */
|
||||
filename = strrchr (pathname, '/');
|
||||
if (filename == NULL)
|
||||
|
@ -646,15 +647,20 @@ glob_filename (pathname, flags)
|
|||
filename = pathname;
|
||||
directory_name = "";
|
||||
directory_len = 0;
|
||||
free_dirname = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
directory_len = (filename - pathname) + 1;
|
||||
directory_name = (char *) alloca (directory_len + 1);
|
||||
directory_name = (char *) malloc (directory_len + 1);
|
||||
|
||||
if (directory_name == 0) /* allocation failed? */
|
||||
return (NULL);
|
||||
|
||||
bcopy (pathname, directory_name, directory_len);
|
||||
directory_name[directory_len] = '\0';
|
||||
++filename;
|
||||
free_dirname = 1;
|
||||
}
|
||||
|
||||
/* If directory_name contains globbing characters, then we
|
||||
|
@ -669,6 +675,12 @@ glob_filename (pathname, flags)
|
|||
|
||||
directories = glob_filename (directory_name, flags & ~GX_MARKDIRS);
|
||||
|
||||
if (free_dirname)
|
||||
{
|
||||
free (directory_name);
|
||||
directory_name = NULL;
|
||||
}
|
||||
|
||||
if (directories == NULL)
|
||||
goto memory_error;
|
||||
else if (directories == (char **)&glob_error_return)
|
||||
|
@ -746,6 +758,8 @@ glob_filename (pathname, flags)
|
|||
if (result[0] == NULL)
|
||||
goto memory_error;
|
||||
bcopy (directory_name, result[0], directory_len + 1);
|
||||
if (free_dirname)
|
||||
free (directory_name);
|
||||
result[1] = NULL;
|
||||
return (result);
|
||||
}
|
||||
|
@ -770,9 +784,16 @@ glob_filename (pathname, flags)
|
|||
flags & ~GX_MARKDIRS);
|
||||
|
||||
if (temp_results == NULL || temp_results == (char **)&glob_error_return)
|
||||
return (temp_results);
|
||||
{
|
||||
if (free_dirname)
|
||||
free (directory_name);
|
||||
return (temp_results);
|
||||
}
|
||||
|
||||
return (glob_dir_to_array (directory_name, temp_results, flags));
|
||||
result = glob_dir_to_array (directory_name, temp_results, flags);
|
||||
if (free_dirname)
|
||||
free (directory_name);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* We get to memory_error if the program has run out of memory, or
|
||||
|
@ -786,6 +807,9 @@ glob_filename (pathname, flags)
|
|||
free ((char *) result);
|
||||
}
|
||||
|
||||
if (free_dirname && directory_name)
|
||||
free (directory_name);
|
||||
|
||||
QUIT;
|
||||
|
||||
return (NULL);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 1991-2002 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991-2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
|
@ -16,14 +16,15 @@
|
|||
with Bash; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
static int FCT __P((CHAR *, CHAR *, int));
|
||||
int FCT __P((CHAR *, CHAR *, int));
|
||||
|
||||
static int GMATCH __P((CHAR *, CHAR *, CHAR *, CHAR *, int));
|
||||
static CHAR *PARSE_COLLSYM __P((CHAR *, INT *));
|
||||
static CHAR *BRACKMATCH __P((CHAR *, U_CHAR, int));
|
||||
static int EXTMATCH __P((INT, CHAR *, CHAR *, CHAR *, CHAR *, int));
|
||||
static CHAR *PATSCAN __P((CHAR *, CHAR *, INT));
|
||||
|
||||
static int
|
||||
int
|
||||
FCT (pattern, string, flags)
|
||||
CHAR *pattern;
|
||||
CHAR *string;
|
||||
|
@ -134,6 +135,19 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
|
|||
if ((flags & FNM_PATHNAME) && sc == L('/'))
|
||||
/* A slash does not match a wildcard under FNM_PATHNAME. */
|
||||
return FNM_NOMATCH;
|
||||
#ifdef EXTENDED_GLOB
|
||||
else if ((flags & FNM_EXTMATCH) && c == L('?') && *p == L('(')) /* ) */
|
||||
{
|
||||
CHAR *newn;
|
||||
for (newn = n; newn < se; ++newn)
|
||||
{
|
||||
if (EXTMATCH (c, newn, se, p, pe, flags) == 0)
|
||||
return (0);
|
||||
}
|
||||
/* We didn't match. If we have a `?(...)', that's failure. */
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
#endif
|
||||
else if (c == L('?'))
|
||||
{
|
||||
if (sc == L('\0'))
|
||||
|
|
|
@ -362,44 +362,25 @@ xstrmatch (pattern, string, flags)
|
|||
{
|
||||
#if HANDLE_MULTIBYTE
|
||||
int ret;
|
||||
mbstate_t ps;
|
||||
size_t n;
|
||||
char *pattern_bak;
|
||||
wchar_t *wpattern, *wstring;
|
||||
|
||||
if (MB_CUR_MAX == 1)
|
||||
return (internal_strmatch (pattern, string, flags));
|
||||
|
||||
pattern_bak = (char *)xmalloc (strlen (pattern) + 1);
|
||||
strcpy (pattern_bak, pattern);
|
||||
|
||||
memset (&ps, '\0', sizeof (mbstate_t));
|
||||
n = xmbsrtowcs (NULL, (const char **)&pattern, 0, &ps);
|
||||
n = xdupmbstowcs (&wpattern, NULL, pattern);
|
||||
if (n == (size_t)-1 || n == (size_t)-2)
|
||||
{
|
||||
free (pattern_bak);
|
||||
return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags));
|
||||
}
|
||||
return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags));
|
||||
|
||||
wpattern = (wchar_t *)xmalloc ((n + 1) * sizeof (wchar_t));
|
||||
(void) xmbsrtowcs (wpattern, (const char **)&pattern, n + 1, &ps);
|
||||
|
||||
memset (&ps, '\0', sizeof (mbstate_t));
|
||||
n = xmbsrtowcs (NULL, (const char **)&string, 0, &ps);
|
||||
n = xdupmbstowcs (&wstring, NULL, string);
|
||||
if (n == (size_t)-1 || n == (size_t)-2)
|
||||
{
|
||||
free (wpattern);
|
||||
ret = internal_strmatch (pattern_bak, string, flags);
|
||||
free (pattern_bak);
|
||||
return ret;
|
||||
return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags));
|
||||
}
|
||||
|
||||
wstring = (wchar_t *)xmalloc ((n + 1) * sizeof (wchar_t));
|
||||
(void) xmbsrtowcs (wstring, (const char **)&string, n + 1, &ps);
|
||||
|
||||
ret = internal_wstrmatch (wpattern, wstring, flags);
|
||||
|
||||
free (pattern_bak);
|
||||
free (wpattern);
|
||||
free (wstring);
|
||||
|
||||
|
|
|
@ -24,13 +24,9 @@
|
|||
#include "stdc.h"
|
||||
#include "strmatch.h"
|
||||
|
||||
/* Structured this way so that if HAVE_LIBC_FNM_EXTMATCH is defined, the
|
||||
matching portion of the library (smatch.c) is not linked into the shell. */
|
||||
|
||||
#ifndef HAVE_LIBC_FNM_EXTMATCH
|
||||
extern int xstrmatch __P((char *, char *, int));
|
||||
#else
|
||||
# define xstrmatch fnmatch
|
||||
#if defined (HAVE_MULTIBYTE)
|
||||
extern int internal_wstrmatch __P((wchar_t *, wchar_t *, int));
|
||||
#endif
|
||||
|
||||
int
|
||||
|
@ -45,6 +41,20 @@ strmatch (pattern, string, flags)
|
|||
return (xstrmatch (pattern, string, flags));
|
||||
}
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
int
|
||||
wcsmatch (wpattern, wstring, flags)
|
||||
wchar_t *wpattern;
|
||||
wchar_t *wstring;
|
||||
int flags;
|
||||
{
|
||||
if (wstring == 0 || wpattern == 0)
|
||||
return (FNM_NOMATCH);
|
||||
|
||||
return (internal_wstrmatch (wpattern, wstring, flags));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
main (c, v)
|
||||
int c;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991-2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
|
@ -19,11 +19,7 @@ not, write to the Free Software Foundation, Inc.,
|
|||
#ifndef _STRMATCH_H
|
||||
#define _STRMATCH_H 1
|
||||
|
||||
#ifdef HAVE_LIBC_FNM_EXTMATCH
|
||||
|
||||
#include <fnmatch.h>
|
||||
|
||||
#else /* !HAVE_LIBC_FNM_EXTMATCH */
|
||||
#include <config.h>
|
||||
|
||||
#include "stdc.h"
|
||||
|
||||
|
@ -59,6 +55,8 @@ not, write to the Free Software Foundation, Inc.,
|
|||
returning zero if it matches, FNM_NOMATCH if not. */
|
||||
extern int strmatch __P((char *, char *, int));
|
||||
|
||||
#endif /* !HAVE_LIBC_FNM_EXTMATCH */
|
||||
#if HANDLE_MULTIBYTE
|
||||
extern int wcsmatch __P((wchar_t *, wchar_t *, int));
|
||||
#endif
|
||||
|
||||
#endif /* _STRMATCH_H */
|
||||
|
|
|
@ -54,27 +54,25 @@ xmbsrtowcs (dest, src, len, pstate)
|
|||
ps = &local_state;
|
||||
}
|
||||
|
||||
n = strlen(*src) + 1;
|
||||
n = strlen(*src);
|
||||
|
||||
if (dest == NULL)
|
||||
{
|
||||
wchar_t *wsbuf;
|
||||
char *mbsbuf, *mbsbuf_top;
|
||||
const char *mbs;
|
||||
mbstate_t psbuf;
|
||||
|
||||
wsbuf = (wchar_t *) malloc ((n + 1) * sizeof(wchar_t));
|
||||
mbsbuf_top = mbsbuf = (char *) malloc (n + 1);
|
||||
memcpy(mbsbuf, *src, n + 1);
|
||||
mbs = *src;
|
||||
psbuf = *ps;
|
||||
|
||||
wclength = mbsrtowcs (wsbuf, (const char **)&mbsbuf, n, &psbuf);
|
||||
wclength = mbsrtowcs (wsbuf, &mbs, n, &psbuf);
|
||||
|
||||
free (wsbuf);
|
||||
free (mbsbuf_top);
|
||||
return wclength;
|
||||
}
|
||||
|
||||
for(wclength = 0; wclength < len; wclength++, dest++)
|
||||
for (wclength = 0; wclength < len; wclength++, dest++)
|
||||
{
|
||||
if(mbsinit(ps))
|
||||
{
|
||||
|
@ -113,4 +111,135 @@ xmbsrtowcs (dest, src, len, pstate)
|
|||
|
||||
return (wclength);
|
||||
}
|
||||
|
||||
/* Convert a multibyte string to a wide character string. Memory for the
|
||||
new wide character string is obtained with malloc.
|
||||
|
||||
The return value is the length of the wide character string. Returns a
|
||||
pointer to the wide character string in DESTP. If INDICESP is not NULL,
|
||||
INDICESP stores the pointer to the pointer array. Each pointer is to
|
||||
the first byte of each multibyte character. Memory for the pointer array
|
||||
is obtained with malloc, too.
|
||||
If conversion is failed, the return value is (size_t)-1 and the values
|
||||
of DESTP and INDICESP are NULL. */
|
||||
|
||||
#define WSBUF_INC 32
|
||||
|
||||
size_t
|
||||
xdupmbstowcs (destp, indicesp, src)
|
||||
wchar_t **destp; /* Store the pointer to the wide character string */
|
||||
char ***indicesp; /* Store the pointer to the pointer array. */
|
||||
const char *src; /* Multibyte character string */
|
||||
{
|
||||
const char *p; /* Conversion start position of src */
|
||||
wchar_t wc; /* Created wide character by conversion */
|
||||
wchar_t *wsbuf; /* Buffer for wide characters. */
|
||||
char **indices; /* Buffer for indices. */
|
||||
size_t wsbuf_size; /* Size of WSBUF */
|
||||
size_t wcnum; /* Number of wide characters in WSBUF */
|
||||
mbstate_t state; /* Conversion State */
|
||||
|
||||
/* In case SRC or DESP is NULL, conversion doesn't take place. */
|
||||
if (src == NULL || destp == NULL)
|
||||
{
|
||||
*destp = NULL;
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
memset (&state, '\0', sizeof(mbstate_t));
|
||||
wsbuf_size = WSBUF_INC;
|
||||
|
||||
wsbuf = (wchar_t *) malloc (wsbuf_size * sizeof(wchar_t));
|
||||
if (wsbuf == NULL)
|
||||
{
|
||||
*destp = NULL;
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
indices = (char **) malloc (wsbuf_size * sizeof(char *));
|
||||
if (indices == NULL)
|
||||
{
|
||||
free (wsbuf);
|
||||
*destp = NULL;
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
p = src;
|
||||
wcnum = 0;
|
||||
do {
|
||||
size_t mblength; /* Byte length of one multibyte character. */
|
||||
|
||||
if(mbsinit (&state))
|
||||
{
|
||||
if (*p == '\0')
|
||||
{
|
||||
wc = L'\0';
|
||||
mblength = 1;
|
||||
}
|
||||
else if (*p == '\\')
|
||||
{
|
||||
wc = L'\\';
|
||||
mblength = 1;
|
||||
}
|
||||
else
|
||||
mblength = mbrtowc(&wc, p, MB_LEN_MAX, &state);
|
||||
}
|
||||
else
|
||||
mblength = mbrtowc(&wc, p, MB_LEN_MAX, &state);
|
||||
|
||||
/* Conversion failed. */
|
||||
if (MB_INVALIDCH (mblength))
|
||||
{
|
||||
free (wsbuf);
|
||||
free (indices);
|
||||
*destp = NULL;
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
++wcnum;
|
||||
|
||||
/* Resize buffers when they are not large enough. */
|
||||
if (wsbuf_size < wcnum)
|
||||
{
|
||||
wchar_t *wstmp;
|
||||
char **idxtmp;
|
||||
|
||||
wsbuf_size += WSBUF_INC;
|
||||
|
||||
wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t));
|
||||
if (wstmp == NULL)
|
||||
{
|
||||
free (wsbuf);
|
||||
free (indices);
|
||||
*destp = NULL;
|
||||
return (size_t)-1;
|
||||
}
|
||||
wsbuf = wstmp;
|
||||
|
||||
idxtmp = (char **) realloc (indices, wsbuf_size * sizeof (char **));
|
||||
if (idxtmp == NULL)
|
||||
{
|
||||
free (wsbuf);
|
||||
free (indices);
|
||||
*destp = NULL;
|
||||
return (size_t)-1;
|
||||
}
|
||||
indices = idxtmp;
|
||||
}
|
||||
|
||||
wsbuf[wcnum - 1] = wc;
|
||||
indices[wcnum - 1] = (char *)p;
|
||||
p += mblength;
|
||||
} while (MB_NULLWCH (wc) == 0);
|
||||
|
||||
/* Return the length of the wide character string, not including `\0'. */
|
||||
*destp = wsbuf;
|
||||
if (indicesp != NULL)
|
||||
*indicesp = indices;
|
||||
else
|
||||
free (indices);
|
||||
|
||||
return (wcnum - 1);
|
||||
}
|
||||
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
|
|
4
lib/intl/ChangeLog
Normal file
4
lib/intl/ChangeLog
Normal file
|
@ -0,0 +1,4 @@
|
|||
2003-05-22 GNU <bug-gnu-gettext@gnu.org>
|
||||
|
||||
* Version 0.12.1 released.
|
||||
|
463
lib/intl/Makefile.in
Normal file
463
lib/intl/Makefile.in
Normal file
|
@ -0,0 +1,463 @@
|
|||
# Makefile for directory with message catalog handling library of GNU gettext
|
||||
# Copyright (C) 1995-1998, 2000-2003 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Library 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
|
||||
# Library General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library 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.
|
||||
|
||||
PACKAGE = @PACKAGE_NAME@
|
||||
VERSION = @PACKAGE_VERSION@
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
top_builddir = @BUILD_DIR@
|
||||
VPATH = $(srcdir)
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
transform = @program_transform_name@
|
||||
libdir = @libdir@
|
||||
includedir = @includedir@
|
||||
datadir = @datadir@
|
||||
localedir = $(datadir)/locale
|
||||
gettextsrcdir = $(datadir)/gettext/intl
|
||||
aliaspath = $(localedir)
|
||||
subdir = intl
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
MKINSTALLDIRS = @MKINSTALLDIRS@
|
||||
mkinstalldirs = $(SHELL) $(MKINSTALLDIRS)
|
||||
|
||||
l = @INTL_LIBTOOL_SUFFIX_PREFIX@
|
||||
|
||||
AR = ar
|
||||
CC = @CC@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
RANLIB = @RANLIB@
|
||||
YACC = @INTLBISON@ -y -d
|
||||
YFLAGS = --name-prefix=__gettext
|
||||
|
||||
DEFS = -DLOCALEDIR=\"$(localedir)\" -DLOCALE_ALIAS_PATH=\"$(aliaspath)\" \
|
||||
-DLIBDIR=\"$(prefix)/libdata\" -DIN_LIBINTL \
|
||||
-DENABLE_RELOCATABLE=1 -DIN_LIBRARY -DINSTALLDIR=\"$(libdir)\" -DNO_XMALLOC \
|
||||
-Dset_relocation_prefix=libintl_set_relocation_prefix \
|
||||
-Drelocate=libintl_relocate \
|
||||
-DDEPENDS_ON_LIBICONV=1 @DEFS@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CFLAGS = @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
|
||||
COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
|
||||
|
||||
HEADERS = \
|
||||
gmo.h \
|
||||
gettextP.h \
|
||||
hash-string.h \
|
||||
loadinfo.h \
|
||||
plural-exp.h \
|
||||
eval-plural.h \
|
||||
localcharset.h \
|
||||
relocatable.h \
|
||||
os2compat.h \
|
||||
libgnuintl.h.in
|
||||
SOURCES = \
|
||||
bindtextdom.c \
|
||||
dcgettext.c \
|
||||
dgettext.c \
|
||||
gettext.c \
|
||||
finddomain.c \
|
||||
loadmsgcat.c \
|
||||
localealias.c \
|
||||
textdomain.c \
|
||||
l10nflist.c \
|
||||
explodename.c \
|
||||
dcigettext.c \
|
||||
dcngettext.c \
|
||||
dngettext.c \
|
||||
ngettext.c \
|
||||
plural.y \
|
||||
plural-exp.c \
|
||||
localcharset.c \
|
||||
relocatable.c \
|
||||
localename.c \
|
||||
log.c \
|
||||
osdep.c \
|
||||
os2compat.c \
|
||||
intl-compat.c
|
||||
OBJECTS = \
|
||||
bindtextdom.$lo \
|
||||
dcgettext.$lo \
|
||||
dgettext.$lo \
|
||||
gettext.$lo \
|
||||
finddomain.$lo \
|
||||
loadmsgcat.$lo \
|
||||
localealias.$lo \
|
||||
textdomain.$lo \
|
||||
l10nflist.$lo \
|
||||
explodename.$lo \
|
||||
dcigettext.$lo \
|
||||
dcngettext.$lo \
|
||||
dngettext.$lo \
|
||||
ngettext.$lo \
|
||||
plural.$lo \
|
||||
plural-exp.$lo \
|
||||
localcharset.$lo \
|
||||
relocatable.$lo \
|
||||
localename.$lo \
|
||||
log.$lo \
|
||||
osdep.$lo \
|
||||
intl-compat.$lo
|
||||
DISTFILES.common = Makefile.in \
|
||||
config.charset locale.alias ref-add.sin ref-del.sin $(HEADERS) $(SOURCES)
|
||||
DISTFILES.generated = plural.c
|
||||
DISTFILES.normal = VERSION
|
||||
DISTFILES.gettext = COPYING.LIB-2.0 COPYING.LIB-2.1 libintl.glibc \
|
||||
Makefile.vms libgnuintl.h.msvc-shared README.woe32 Makefile.msvc
|
||||
DISTFILES.obsolete = xopen-msg.sed linux-msg.sed po2tbl.sed.in cat-compat.c \
|
||||
COPYING.LIB-2 gettext.h libgettext.h plural-eval.c libgnuintl.h
|
||||
|
||||
all: all-@USE_INCLUDED_LIBINTL@
|
||||
all-yes: libintl.$la libintl.h charset.alias ref-add.sed ref-del.sed
|
||||
all-no: all-no-@BUILD_INCLUDED_LIBINTL@
|
||||
all-no-yes: libgnuintl.$la
|
||||
all-no-no:
|
||||
|
||||
libintl.a libgnuintl.a: $(OBJECTS)
|
||||
rm -f $@
|
||||
$(AR) cru $@ $(OBJECTS)
|
||||
$(RANLIB) $@
|
||||
|
||||
libintl.la libgnuintl.la: $(OBJECTS)
|
||||
$(LIBTOOL) --mode=link \
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) $(LDFLAGS) -o $@ \
|
||||
$(OBJECTS) @LTLIBICONV@ $(LIBS) \
|
||||
-version-info $(LTV_CURRENT):$(LTV_REVISION):$(LTV_AGE) \
|
||||
-rpath $(libdir) \
|
||||
-no-undefined
|
||||
|
||||
# Libtool's library version information for libintl.
|
||||
# Before making a gettext release, the gettext maintainer must change this
|
||||
# according to the libtool documentation, section "Library interface versions".
|
||||
# Maintainers of other packages that include the intl directory must *not*
|
||||
# change these values.
|
||||
LTV_CURRENT=5
|
||||
LTV_REVISION=0
|
||||
LTV_AGE=3
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .y .o .lo .sin .sed
|
||||
|
||||
.c.o:
|
||||
$(COMPILE) $<
|
||||
|
||||
.y.c:
|
||||
$(YACC) $(YFLAGS) --output $@ $<
|
||||
rm -f $*.h
|
||||
|
||||
bindtextdom.lo: $(srcdir)/bindtextdom.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/bindtextdom.c
|
||||
dcgettext.lo: $(srcdir)/dcgettext.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dcgettext.c
|
||||
dgettext.lo: $(srcdir)/dgettext.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dgettext.c
|
||||
gettext.lo: $(srcdir)/gettext.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/gettext.c
|
||||
finddomain.lo: $(srcdir)/finddomain.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/finddomain.c
|
||||
loadmsgcat.lo: $(srcdir)/loadmsgcat.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/loadmsgcat.c
|
||||
localealias.lo: $(srcdir)/localealias.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/localealias.c
|
||||
textdomain.lo: $(srcdir)/textdomain.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/textdomain.c
|
||||
l10nflist.lo: $(srcdir)/l10nflist.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/l10nflist.c
|
||||
explodename.lo: $(srcdir)/explodename.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/explodename.c
|
||||
dcigettext.lo: $(srcdir)/dcigettext.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dcigettext.c
|
||||
dcngettext.lo: $(srcdir)/dcngettext.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dcngettext.c
|
||||
dngettext.lo: $(srcdir)/dngettext.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dngettext.c
|
||||
ngettext.lo: $(srcdir)/ngettext.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/ngettext.c
|
||||
plural.lo: $(srcdir)/plural.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/plural.c
|
||||
plural-exp.lo: $(srcdir)/plural-exp.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/plural-exp.c
|
||||
localcharset.lo: $(srcdir)/localcharset.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/localcharset.c
|
||||
relocatable.lo: $(srcdir)/relocatable.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/relocatable.c
|
||||
localename.lo: $(srcdir)/localename.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/localename.c
|
||||
log.lo: $(srcdir)/log.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/log.c
|
||||
osdep.lo: $(srcdir)/osdep.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/osdep.c
|
||||
intl-compat.lo: $(srcdir)/intl-compat.c
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/intl-compat.c
|
||||
|
||||
ref-add.sed: $(srcdir)/ref-add.sin
|
||||
sed -e '/^#/d' -e 's/@''PACKAGE''@/@PACKAGE@/g' $(srcdir)/ref-add.sin > t-ref-add.sed
|
||||
mv t-ref-add.sed ref-add.sed
|
||||
ref-del.sed: $(srcdir)/ref-del.sin
|
||||
sed -e '/^#/d' -e 's/@''PACKAGE''@/@PACKAGE@/g' $(srcdir)/ref-del.sin > t-ref-del.sed
|
||||
mv t-ref-del.sed ref-del.sed
|
||||
|
||||
INCLUDES = -I. -I$(srcdir) -I${top_builddir} -I${top_srcdir}
|
||||
|
||||
libgnuintl.h: $(srcdir)/libgnuintl.h.in
|
||||
cp $(srcdir)/libgnuintl.h.in libgnuintl.h
|
||||
|
||||
libintl.h: libgnuintl.h
|
||||
cp libgnuintl.h libintl.h
|
||||
|
||||
charset.alias: $(srcdir)/config.charset
|
||||
$(SHELL) $(srcdir)/config.charset '@host@' > t-$@
|
||||
mv t-$@ $@
|
||||
|
||||
check: all
|
||||
|
||||
# We must not install the libintl.h/libintl.a files if we are on a
|
||||
# system which has the GNU gettext() function in its C library or in a
|
||||
# separate library.
|
||||
# If you want to use the one which comes with this version of the
|
||||
# package, you have to use `configure --with-included-gettext'.
|
||||
install: install-exec install-data
|
||||
install-exec: all
|
||||
if { test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; } \
|
||||
&& test '@USE_INCLUDED_LIBINTL@' = yes; then \
|
||||
$(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir); \
|
||||
$(INSTALL_DATA) libintl.h $(DESTDIR)$(includedir)/libintl.h; \
|
||||
$(LIBTOOL) --mode=install \
|
||||
$(INSTALL_DATA) libintl.$la $(DESTDIR)$(libdir)/libintl.$la; \
|
||||
if test "@RELOCATABLE@" = yes; then \
|
||||
dependencies=`sed -n -e 's,^dependency_libs=\(.*\),\1,p' < $(DESTDIR)$(libdir)/libintl.la | sed -e "s,^',," -e "s,'\$$,,"`; \
|
||||
if test -n "$dependencies"; then \
|
||||
rm -f $(DESTDIR)$(libdir)/libintl.la; \
|
||||
fi; \
|
||||
fi; \
|
||||
else \
|
||||
: ; \
|
||||
fi
|
||||
if test "$(PACKAGE)" = "gettext-tools" \
|
||||
&& test '@USE_INCLUDED_LIBINTL@' = no; then \
|
||||
$(mkinstalldirs) $(DESTDIR)$(libdir); \
|
||||
$(LIBTOOL) --mode=install \
|
||||
$(INSTALL_DATA) libgnuintl.$la $(DESTDIR)$(libdir)/libgnuintl.$la; \
|
||||
rm -f $(DESTDIR)$(libdir)/preloadable_libintl.so; \
|
||||
$(INSTALL_DATA) $(DESTDIR)$(libdir)/libgnuintl.so $(DESTDIR)$(libdir)/preloadable_libintl.so; \
|
||||
$(LIBTOOL) --mode=uninstall \
|
||||
rm -f $(DESTDIR)$(libdir)/libgnuintl.$la; \
|
||||
else \
|
||||
: ; \
|
||||
fi
|
||||
if test '@USE_INCLUDED_LIBINTL@' = yes; then \
|
||||
$(mkinstalldirs) $(DESTDIR)$(localedir); \
|
||||
test -f $(DESTDIR)$(localedir)/locale.alias \
|
||||
&& orig=$(DESTDIR)$(localedir)/locale.alias \
|
||||
|| orig=$(srcdir)/locale.alias; \
|
||||
temp=$(DESTDIR)$(localedir)/t-locale.alias; \
|
||||
dest=$(DESTDIR)$(localedir)/locale.alias; \
|
||||
sed -f ref-add.sed $$orig > $$temp; \
|
||||
$(INSTALL_DATA) $$temp $$dest; \
|
||||
rm -f $$temp; \
|
||||
else \
|
||||
: ; \
|
||||
fi
|
||||
install-data: all
|
||||
if test "$(PACKAGE)" = "gettext-tools"; then \
|
||||
$(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \
|
||||
$(INSTALL_DATA) VERSION $(DESTDIR)$(gettextsrcdir)/VERSION; \
|
||||
$(INSTALL_DATA) ChangeLog.inst $(DESTDIR)$(gettextsrcdir)/ChangeLog; \
|
||||
dists="COPYING.LIB-2.0 COPYING.LIB-2.1 $(DISTFILES.common)"; \
|
||||
for file in $$dists; do \
|
||||
$(INSTALL_DATA) $(srcdir)/$$file \
|
||||
$(DESTDIR)$(gettextsrcdir)/$$file; \
|
||||
done; \
|
||||
chmod a+x $(DESTDIR)$(gettextsrcdir)/config.charset; \
|
||||
dists="$(DISTFILES.generated)"; \
|
||||
for file in $$dists; do \
|
||||
if test -f $$file; then dir=.; else dir=$(srcdir); fi; \
|
||||
$(INSTALL_DATA) $$dir/$$file \
|
||||
$(DESTDIR)$(gettextsrcdir)/$$file; \
|
||||
done; \
|
||||
dists="$(DISTFILES.obsolete)"; \
|
||||
for file in $$dists; do \
|
||||
rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
|
||||
done; \
|
||||
else \
|
||||
: ; \
|
||||
fi
|
||||
|
||||
install-strip: install
|
||||
|
||||
installdirs:
|
||||
if { test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; } \
|
||||
&& test '@USE_INCLUDED_LIBINTL@' = yes; then \
|
||||
$(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir); \
|
||||
else \
|
||||
: ; \
|
||||
fi
|
||||
if test "$(PACKAGE)" = "gettext-tools" \
|
||||
&& test '@USE_INCLUDED_LIBINTL@' = no; then \
|
||||
$(mkinstalldirs) $(DESTDIR)$(libdir); \
|
||||
else \
|
||||
: ; \
|
||||
fi
|
||||
if test '@USE_INCLUDED_LIBINTL@' = yes; then \
|
||||
test @GLIBC21@ != no || $(mkinstalldirs) $(DESTDIR)$(libdir); \
|
||||
$(mkinstalldirs) $(DESTDIR)$(localedir); \
|
||||
else \
|
||||
: ; \
|
||||
fi
|
||||
if test "$(PACKAGE)" = "gettext-tools"; then \
|
||||
$(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \
|
||||
else \
|
||||
: ; \
|
||||
fi
|
||||
|
||||
# Define this as empty until I found a useful application.
|
||||
installcheck:
|
||||
|
||||
uninstall:
|
||||
if { test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; } \
|
||||
&& test '@USE_INCLUDED_LIBINTL@' = yes; then \
|
||||
rm -f $(DESTDIR)$(includedir)/libintl.h; \
|
||||
$(LIBTOOL) --mode=uninstall \
|
||||
rm -f $(DESTDIR)$(libdir)/libintl.$la; \
|
||||
else \
|
||||
: ; \
|
||||
fi
|
||||
if test "$(PACKAGE)" = "gettext-tools" \
|
||||
&& test '@USE_INCLUDED_LIBINTL@' = no; then \
|
||||
rm -f $(DESTDIR)$(libdir)/preloadable_libintl.so; \
|
||||
else \
|
||||
: ; \
|
||||
fi
|
||||
if test '@USE_INCLUDED_LIBINTL@' = yes; then \
|
||||
if test -f $(DESTDIR)$(prefix)/libdata/charset.alias; then \
|
||||
temp=$(DESTDIR)$(prefix)/libdata/t-charset.alias; \
|
||||
dest=$(DESTDIR)$(prefix)/libdata/charset.alias; \
|
||||
sed -f ref-del.sed $$dest > $$temp; \
|
||||
if grep '^# Packages using this file: $$' $$temp > /dev/null; then \
|
||||
rm -f $$dest; \
|
||||
else \
|
||||
$(INSTALL_DATA) $$temp $$dest; \
|
||||
fi; \
|
||||
rm -f $$temp; \
|
||||
fi; \
|
||||
if test -f $(DESTDIR)$(localedir)/locale.alias; then \
|
||||
temp=$(DESTDIR)$(localedir)/t-locale.alias; \
|
||||
dest=$(DESTDIR)$(localedir)/locale.alias; \
|
||||
sed -f ref-del.sed $$dest > $$temp; \
|
||||
if grep '^# Packages using this file: $$' $$temp > /dev/null; then \
|
||||
rm -f $$dest; \
|
||||
else \
|
||||
$(INSTALL_DATA) $$temp $$dest; \
|
||||
fi; \
|
||||
rm -f $$temp; \
|
||||
fi; \
|
||||
else \
|
||||
: ; \
|
||||
fi
|
||||
if test "$(PACKAGE)" = "gettext-tools"; then \
|
||||
for file in VERSION ChangeLog COPYING.LIB-2.0 COPYING.LIB-2.1 $(DISTFILES.common) $(DISTFILES.generated); do \
|
||||
rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
|
||||
done; \
|
||||
else \
|
||||
: ; \
|
||||
fi
|
||||
|
||||
info dvi ps pdf html:
|
||||
|
||||
$(OBJECTS): ${top_builddir}/config.h libgnuintl.h
|
||||
bindtextdom.$lo dcgettext.$lo dcigettext.$lo dcngettext.$lo dgettext.$lo dngettext.$lo finddomain.$lo gettext.$lo intl-compat.$lo loadmsgcat.$lo localealias.$lo ngettext.$lo textdomain.$lo: $(srcdir)/gettextP.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h
|
||||
dcigettext.$lo loadmsgcat.$lo: $(srcdir)/hash-string.h
|
||||
explodename.$lo l10nflist.$lo: $(srcdir)/loadinfo.h
|
||||
dcigettext.$lo loadmsgcat.$lo plural.$lo plural-exp.$lo: $(srcdir)/plural-exp.h
|
||||
dcigettext.$lo: $(srcdir)/eval-plural.h
|
||||
localcharset.$lo: $(srcdir)/localcharset.h
|
||||
localealias.$lo localcharset.$lo relocatable.$lo: $(srcdir)/relocatable.h
|
||||
|
||||
tags: TAGS
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES)
|
||||
here=`pwd`; cd $(srcdir) && etags -o $$here/TAGS $(HEADERS) $(SOURCES)
|
||||
|
||||
ctags: CTAGS
|
||||
|
||||
CTAGS: $(HEADERS) $(SOURCES)
|
||||
here=`pwd`; cd $(srcdir) && ctags -o $$here/CTAGS $(HEADERS) $(SOURCES)
|
||||
|
||||
id: ID
|
||||
|
||||
ID: $(HEADERS) $(SOURCES)
|
||||
here=`pwd`; cd $(srcdir) && mkid -f$$here/ID $(HEADERS) $(SOURCES)
|
||||
|
||||
|
||||
mostlyclean:
|
||||
rm -f *.a *.la *.o *.obj *.lo core core.*
|
||||
rm -f libgnuintl.h libintl.h charset.alias ref-add.sed ref-del.sed
|
||||
rm -f -r .libs _libs
|
||||
|
||||
clean: mostlyclean
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile ID TAGS
|
||||
if test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; then \
|
||||
rm -f ChangeLog.inst $(DISTFILES.normal); \
|
||||
else \
|
||||
: ; \
|
||||
fi
|
||||
|
||||
maintainer-clean: distclean
|
||||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
|
||||
|
||||
# GNU gettext needs not contain the file `VERSION' but contains some
|
||||
# other files which should not be distributed in other packages.
|
||||
distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
|
||||
dist distdir: Makefile
|
||||
if test "$(PACKAGE)" = "gettext-tools"; then \
|
||||
: ; \
|
||||
else \
|
||||
if test "$(PACKAGE)" = "gettext-runtime"; then \
|
||||
additional="$(DISTFILES.gettext)"; \
|
||||
else \
|
||||
additional="$(DISTFILES.normal)"; \
|
||||
fi; \
|
||||
$(MAKE) $(DISTFILES.common) $(DISTFILES.generated) $$additional; \
|
||||
for file in ChangeLog $(DISTFILES.common) $(DISTFILES.generated) $$additional; do \
|
||||
if test -f $$file; then dir=.; else dir=$(srcdir); fi; \
|
||||
cp -p $$dir/$$file $(distdir); \
|
||||
done; \
|
||||
fi
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) && $(SHELL) ./config.status
|
||||
# This would be more efficient, but doesn't work any more with autoconf-2.57,
|
||||
# when AC_CONFIG_FILES([intl/Makefile:somedir/Makefile.in]) is used.
|
||||
# cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make not to export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
1
lib/intl/VERSION
Normal file
1
lib/intl/VERSION
Normal file
|
@ -0,0 +1 @@
|
|||
GNU gettext library from gettext-0.12.1
|
374
lib/intl/bindtextdom.c
Normal file
374
lib/intl/bindtextdom.c
Normal file
|
@ -0,0 +1,374 @@
|
|||
/* Implementation of the bindtextdomain(3) function
|
||||
Copyright (C) 1995-1998, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _LIBC
|
||||
# include <libintl.h>
|
||||
#else
|
||||
# include "libgnuintl.h"
|
||||
#endif
|
||||
#include "gettextP.h"
|
||||
|
||||
#ifdef _LIBC
|
||||
/* We have to handle multi-threaded applications. */
|
||||
# include <bits/libc-lock.h>
|
||||
#else
|
||||
/* Provide dummy implementation if this is outside glibc. */
|
||||
# define __libc_rwlock_define(CLASS, NAME)
|
||||
# define __libc_rwlock_wrlock(NAME)
|
||||
# define __libc_rwlock_unlock(NAME)
|
||||
#endif
|
||||
|
||||
/* The internal variables in the standalone libintl.a must have different
|
||||
names than the internal variables in GNU libc, otherwise programs
|
||||
using libintl.a cannot be linked statically. */
|
||||
#if !defined _LIBC
|
||||
# define _nl_default_dirname libintl_nl_default_dirname
|
||||
# define _nl_domain_bindings libintl_nl_domain_bindings
|
||||
#endif
|
||||
|
||||
/* Some compilers, like SunOS4 cc, don't have offsetof in <stddef.h>. */
|
||||
#ifndef offsetof
|
||||
# define offsetof(type,ident) ((size_t)&(((type*)0)->ident))
|
||||
#endif
|
||||
|
||||
/* @@ end of prolog @@ */
|
||||
|
||||
/* Contains the default location of the message catalogs. */
|
||||
extern const char _nl_default_dirname[];
|
||||
#ifdef _LIBC
|
||||
extern const char _nl_default_dirname_internal[] attribute_hidden;
|
||||
#else
|
||||
# define INTUSE(name) name
|
||||
#endif
|
||||
|
||||
/* List with bindings of specific domains. */
|
||||
extern struct binding *_nl_domain_bindings;
|
||||
|
||||
/* Lock variable to protect the global data in the gettext implementation. */
|
||||
__libc_rwlock_define (extern, _nl_state_lock attribute_hidden)
|
||||
|
||||
|
||||
/* Names for the libintl functions are a problem. They must not clash
|
||||
with existing names and they should follow ANSI C. But this source
|
||||
code is also used in GNU C Library where the names have a __
|
||||
prefix. So we have to make a difference here. */
|
||||
#ifdef _LIBC
|
||||
# define BINDTEXTDOMAIN __bindtextdomain
|
||||
# define BIND_TEXTDOMAIN_CODESET __bind_textdomain_codeset
|
||||
# ifndef strdup
|
||||
# define strdup(str) __strdup (str)
|
||||
# endif
|
||||
#else
|
||||
# define BINDTEXTDOMAIN libintl_bindtextdomain
|
||||
# define BIND_TEXTDOMAIN_CODESET libintl_bind_textdomain_codeset
|
||||
#endif
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
static void set_binding_values PARAMS ((const char *domainname,
|
||||
const char **dirnamep,
|
||||
const char **codesetp));
|
||||
|
||||
/* Specifies the directory name *DIRNAMEP and the output codeset *CODESETP
|
||||
to be used for the DOMAINNAME message catalog.
|
||||
If *DIRNAMEP or *CODESETP is NULL, the corresponding attribute is not
|
||||
modified, only the current value is returned.
|
||||
If DIRNAMEP or CODESETP is NULL, the corresponding attribute is neither
|
||||
modified nor returned. */
|
||||
static void
|
||||
set_binding_values (domainname, dirnamep, codesetp)
|
||||
const char *domainname;
|
||||
const char **dirnamep;
|
||||
const char **codesetp;
|
||||
{
|
||||
struct binding *binding;
|
||||
int modified;
|
||||
|
||||
/* Some sanity checks. */
|
||||
if (domainname == NULL || domainname[0] == '\0')
|
||||
{
|
||||
if (dirnamep)
|
||||
*dirnamep = NULL;
|
||||
if (codesetp)
|
||||
*codesetp = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
__libc_rwlock_wrlock (_nl_state_lock);
|
||||
|
||||
modified = 0;
|
||||
|
||||
for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
|
||||
{
|
||||
int compare = strcmp (domainname, binding->domainname);
|
||||
if (compare == 0)
|
||||
/* We found it! */
|
||||
break;
|
||||
if (compare < 0)
|
||||
{
|
||||
/* It is not in the list. */
|
||||
binding = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (binding != NULL)
|
||||
{
|
||||
if (dirnamep)
|
||||
{
|
||||
const char *dirname = *dirnamep;
|
||||
|
||||
if (dirname == NULL)
|
||||
/* The current binding has be to returned. */
|
||||
*dirnamep = binding->dirname;
|
||||
else
|
||||
{
|
||||
/* The domain is already bound. If the new value and the old
|
||||
one are equal we simply do nothing. Otherwise replace the
|
||||
old binding. */
|
||||
char *result = binding->dirname;
|
||||
if (strcmp (dirname, result) != 0)
|
||||
{
|
||||
if (strcmp (dirname, INTUSE(_nl_default_dirname)) == 0)
|
||||
result = (char *) INTUSE(_nl_default_dirname);
|
||||
else
|
||||
{
|
||||
#if defined _LIBC || defined HAVE_STRDUP
|
||||
result = strdup (dirname);
|
||||
#else
|
||||
size_t len = strlen (dirname) + 1;
|
||||
result = (char *) malloc (len);
|
||||
if (__builtin_expect (result != NULL, 1))
|
||||
memcpy (result, dirname, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (__builtin_expect (result != NULL, 1))
|
||||
{
|
||||
if (binding->dirname != INTUSE(_nl_default_dirname))
|
||||
free (binding->dirname);
|
||||
|
||||
binding->dirname = result;
|
||||
modified = 1;
|
||||
}
|
||||
}
|
||||
*dirnamep = result;
|
||||
}
|
||||
}
|
||||
|
||||
if (codesetp)
|
||||
{
|
||||
const char *codeset = *codesetp;
|
||||
|
||||
if (codeset == NULL)
|
||||
/* The current binding has be to returned. */
|
||||
*codesetp = binding->codeset;
|
||||
else
|
||||
{
|
||||
/* The domain is already bound. If the new value and the old
|
||||
one are equal we simply do nothing. Otherwise replace the
|
||||
old binding. */
|
||||
char *result = binding->codeset;
|
||||
if (result == NULL || strcmp (codeset, result) != 0)
|
||||
{
|
||||
#if defined _LIBC || defined HAVE_STRDUP
|
||||
result = strdup (codeset);
|
||||
#else
|
||||
size_t len = strlen (codeset) + 1;
|
||||
result = (char *) malloc (len);
|
||||
if (__builtin_expect (result != NULL, 1))
|
||||
memcpy (result, codeset, len);
|
||||
#endif
|
||||
|
||||
if (__builtin_expect (result != NULL, 1))
|
||||
{
|
||||
if (binding->codeset != NULL)
|
||||
free (binding->codeset);
|
||||
|
||||
binding->codeset = result;
|
||||
binding->codeset_cntr++;
|
||||
modified = 1;
|
||||
}
|
||||
}
|
||||
*codesetp = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((dirnamep == NULL || *dirnamep == NULL)
|
||||
&& (codesetp == NULL || *codesetp == NULL))
|
||||
{
|
||||
/* Simply return the default values. */
|
||||
if (dirnamep)
|
||||
*dirnamep = INTUSE(_nl_default_dirname);
|
||||
if (codesetp)
|
||||
*codesetp = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We have to create a new binding. */
|
||||
size_t len = strlen (domainname) + 1;
|
||||
struct binding *new_binding =
|
||||
(struct binding *) malloc (offsetof (struct binding, domainname) + len);
|
||||
|
||||
if (__builtin_expect (new_binding == NULL, 0))
|
||||
goto failed;
|
||||
|
||||
memcpy (new_binding->domainname, domainname, len);
|
||||
|
||||
if (dirnamep)
|
||||
{
|
||||
const char *dirname = *dirnamep;
|
||||
|
||||
if (dirname == NULL)
|
||||
/* The default value. */
|
||||
dirname = INTUSE(_nl_default_dirname);
|
||||
else
|
||||
{
|
||||
if (strcmp (dirname, INTUSE(_nl_default_dirname)) == 0)
|
||||
dirname = INTUSE(_nl_default_dirname);
|
||||
else
|
||||
{
|
||||
char *result;
|
||||
#if defined _LIBC || defined HAVE_STRDUP
|
||||
result = strdup (dirname);
|
||||
if (__builtin_expect (result == NULL, 0))
|
||||
goto failed_dirname;
|
||||
#else
|
||||
size_t len = strlen (dirname) + 1;
|
||||
result = (char *) malloc (len);
|
||||
if (__builtin_expect (result == NULL, 0))
|
||||
goto failed_dirname;
|
||||
memcpy (result, dirname, len);
|
||||
#endif
|
||||
dirname = result;
|
||||
}
|
||||
}
|
||||
*dirnamep = dirname;
|
||||
new_binding->dirname = (char *) dirname;
|
||||
}
|
||||
else
|
||||
/* The default value. */
|
||||
new_binding->dirname = (char *) INTUSE(_nl_default_dirname);
|
||||
|
||||
new_binding->codeset_cntr = 0;
|
||||
|
||||
if (codesetp)
|
||||
{
|
||||
const char *codeset = *codesetp;
|
||||
|
||||
if (codeset != NULL)
|
||||
{
|
||||
char *result;
|
||||
|
||||
#if defined _LIBC || defined HAVE_STRDUP
|
||||
result = strdup (codeset);
|
||||
if (__builtin_expect (result == NULL, 0))
|
||||
goto failed_codeset;
|
||||
#else
|
||||
size_t len = strlen (codeset) + 1;
|
||||
result = (char *) malloc (len);
|
||||
if (__builtin_expect (result == NULL, 0))
|
||||
goto failed_codeset;
|
||||
memcpy (result, codeset, len);
|
||||
#endif
|
||||
codeset = result;
|
||||
new_binding->codeset_cntr++;
|
||||
}
|
||||
*codesetp = codeset;
|
||||
new_binding->codeset = (char *) codeset;
|
||||
}
|
||||
else
|
||||
new_binding->codeset = NULL;
|
||||
|
||||
/* Now enqueue it. */
|
||||
if (_nl_domain_bindings == NULL
|
||||
|| strcmp (domainname, _nl_domain_bindings->domainname) < 0)
|
||||
{
|
||||
new_binding->next = _nl_domain_bindings;
|
||||
_nl_domain_bindings = new_binding;
|
||||
}
|
||||
else
|
||||
{
|
||||
binding = _nl_domain_bindings;
|
||||
while (binding->next != NULL
|
||||
&& strcmp (domainname, binding->next->domainname) > 0)
|
||||
binding = binding->next;
|
||||
|
||||
new_binding->next = binding->next;
|
||||
binding->next = new_binding;
|
||||
}
|
||||
|
||||
modified = 1;
|
||||
|
||||
/* Here we deal with memory allocation failures. */
|
||||
if (0)
|
||||
{
|
||||
failed_codeset:
|
||||
if (new_binding->dirname != INTUSE(_nl_default_dirname))
|
||||
free (new_binding->dirname);
|
||||
failed_dirname:
|
||||
free (new_binding);
|
||||
failed:
|
||||
if (dirnamep)
|
||||
*dirnamep = NULL;
|
||||
if (codesetp)
|
||||
*codesetp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we modified any binding, we flush the caches. */
|
||||
if (modified)
|
||||
++_nl_msg_cat_cntr;
|
||||
|
||||
__libc_rwlock_unlock (_nl_state_lock);
|
||||
}
|
||||
|
||||
/* Specify that the DOMAINNAME message catalog will be found
|
||||
in DIRNAME rather than in the system locale data base. */
|
||||
char *
|
||||
BINDTEXTDOMAIN (domainname, dirname)
|
||||
const char *domainname;
|
||||
const char *dirname;
|
||||
{
|
||||
set_binding_values (domainname, &dirname, NULL);
|
||||
return (char *) dirname;
|
||||
}
|
||||
|
||||
/* Specify the character encoding in which the messages from the
|
||||
DOMAINNAME message catalog will be returned. */
|
||||
char *
|
||||
BIND_TEXTDOMAIN_CODESET (domainname, codeset)
|
||||
const char *domainname;
|
||||
const char *codeset;
|
||||
{
|
||||
set_binding_values (domainname, NULL, &codeset);
|
||||
return (char *) codeset;
|
||||
}
|
||||
|
||||
#ifdef _LIBC
|
||||
/* Aliases for function names in GNU C Library. */
|
||||
weak_alias (__bindtextdomain, bindtextdomain);
|
||||
weak_alias (__bind_textdomain_codeset, bind_textdomain_codeset);
|
||||
#endif
|
467
lib/intl/config.charset
Executable file
467
lib/intl/config.charset
Executable file
|
@ -0,0 +1,467 @@
|
|||
#! /bin/sh
|
||||
# Output a system dependent table of character encoding aliases.
|
||||
#
|
||||
# Copyright (C) 2000-2003 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Library 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
|
||||
# Library General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library 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.
|
||||
#
|
||||
# The table consists of lines of the form
|
||||
# ALIAS CANONICAL
|
||||
#
|
||||
# ALIAS is the (system dependent) result of "nl_langinfo (CODESET)".
|
||||
# ALIAS is compared in a case sensitive way.
|
||||
#
|
||||
# CANONICAL is the GNU canonical name for this character encoding.
|
||||
# It must be an encoding supported by libiconv. Support by GNU libc is
|
||||
# also desirable. CANONICAL is case insensitive. Usually an upper case
|
||||
# MIME charset name is preferred.
|
||||
# The current list of GNU canonical charset names is as follows.
|
||||
#
|
||||
# name used by which systems a MIME name?
|
||||
# ASCII, ANSI_X3.4-1968 glibc solaris freebsd
|
||||
# ISO-8859-1 glibc aix hpux irix osf solaris freebsd yes
|
||||
# ISO-8859-2 glibc aix hpux irix osf solaris freebsd yes
|
||||
# ISO-8859-3 glibc solaris yes
|
||||
# ISO-8859-4 osf solaris freebsd yes
|
||||
# ISO-8859-5 glibc aix hpux irix osf solaris freebsd yes
|
||||
# ISO-8859-6 glibc aix hpux solaris yes
|
||||
# ISO-8859-7 glibc aix hpux irix osf solaris yes
|
||||
# ISO-8859-8 glibc aix hpux osf solaris yes
|
||||
# ISO-8859-9 glibc aix hpux irix osf solaris yes
|
||||
# ISO-8859-13 glibc
|
||||
# ISO-8859-14 glibc
|
||||
# ISO-8859-15 glibc aix osf solaris freebsd
|
||||
# KOI8-R glibc solaris freebsd yes
|
||||
# KOI8-U glibc freebsd yes
|
||||
# KOI8-T glibc
|
||||
# CP437 dos
|
||||
# CP775 dos
|
||||
# CP850 aix osf dos
|
||||
# CP852 dos
|
||||
# CP855 dos
|
||||
# CP856 aix
|
||||
# CP857 dos
|
||||
# CP861 dos
|
||||
# CP862 dos
|
||||
# CP864 dos
|
||||
# CP865 dos
|
||||
# CP866 freebsd dos
|
||||
# CP869 dos
|
||||
# CP874 woe32 dos
|
||||
# CP922 aix
|
||||
# CP932 aix woe32 dos
|
||||
# CP943 aix
|
||||
# CP949 osf woe32 dos
|
||||
# CP950 woe32 dos
|
||||
# CP1046 aix
|
||||
# CP1124 aix
|
||||
# CP1125 dos
|
||||
# CP1129 aix
|
||||
# CP1250 woe32
|
||||
# CP1251 glibc solaris woe32
|
||||
# CP1252 aix woe32
|
||||
# CP1253 woe32
|
||||
# CP1254 woe32
|
||||
# CP1255 glibc woe32
|
||||
# CP1256 woe32
|
||||
# CP1257 woe32
|
||||
# GB2312 glibc aix hpux irix solaris freebsd yes
|
||||
# EUC-JP glibc aix hpux irix osf solaris freebsd yes
|
||||
# EUC-KR glibc aix hpux irix osf solaris freebsd yes
|
||||
# EUC-TW glibc aix hpux irix osf solaris
|
||||
# BIG5 glibc aix hpux osf solaris freebsd yes
|
||||
# BIG5-HKSCS glibc solaris
|
||||
# GBK glibc aix osf solaris woe32 dos
|
||||
# GB18030 glibc solaris
|
||||
# SHIFT_JIS hpux osf solaris freebsd yes
|
||||
# JOHAB glibc solaris woe32
|
||||
# TIS-620 glibc aix hpux osf solaris
|
||||
# VISCII glibc yes
|
||||
# TCVN5712-1 glibc
|
||||
# GEORGIAN-PS glibc
|
||||
# HP-ROMAN8 hpux
|
||||
# HP-ARABIC8 hpux
|
||||
# HP-GREEK8 hpux
|
||||
# HP-HEBREW8 hpux
|
||||
# HP-TURKISH8 hpux
|
||||
# HP-KANA8 hpux
|
||||
# DEC-KANJI osf
|
||||
# DEC-HANYU osf
|
||||
# UTF-8 glibc aix hpux osf solaris yes
|
||||
#
|
||||
# Note: Names which are not marked as being a MIME name should not be used in
|
||||
# Internet protocols for information interchange (mail, news, etc.).
|
||||
#
|
||||
# Note: ASCII and ANSI_X3.4-1968 are synonymous canonical names. Applications
|
||||
# must understand both names and treat them as equivalent.
|
||||
#
|
||||
# The first argument passed to this file is the canonical host specification,
|
||||
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
|
||||
# or
|
||||
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
|
||||
|
||||
host="$1"
|
||||
os=`echo "$host" | sed -e 's/^[^-]*-[^-]*-\(.*\)$/\1/'`
|
||||
echo "# This file contains a table of character encoding aliases,"
|
||||
echo "# suitable for operating system '${os}'."
|
||||
echo "# It was automatically generated from config.charset."
|
||||
# List of references, updated during installation:
|
||||
echo "# Packages using this file: "
|
||||
case "$os" in
|
||||
linux* | *-gnu*)
|
||||
# With glibc-2.1 or newer, we don't need any canonicalization,
|
||||
# because glibc has iconv and both glibc and libiconv support all
|
||||
# GNU canonical names directly. Therefore, the Makefile does not
|
||||
# need to install the alias file at all.
|
||||
# The following applies only to glibc-2.0.x and older libcs.
|
||||
echo "ISO_646.IRV:1983 ASCII"
|
||||
;;
|
||||
aix*)
|
||||
echo "ISO8859-1 ISO-8859-1"
|
||||
echo "ISO8859-2 ISO-8859-2"
|
||||
echo "ISO8859-5 ISO-8859-5"
|
||||
echo "ISO8859-6 ISO-8859-6"
|
||||
echo "ISO8859-7 ISO-8859-7"
|
||||
echo "ISO8859-8 ISO-8859-8"
|
||||
echo "ISO8859-9 ISO-8859-9"
|
||||
echo "ISO8859-15 ISO-8859-15"
|
||||
echo "IBM-850 CP850"
|
||||
echo "IBM-856 CP856"
|
||||
echo "IBM-921 ISO-8859-13"
|
||||
echo "IBM-922 CP922"
|
||||
echo "IBM-932 CP932"
|
||||
echo "IBM-943 CP943"
|
||||
echo "IBM-1046 CP1046"
|
||||
echo "IBM-1124 CP1124"
|
||||
echo "IBM-1129 CP1129"
|
||||
echo "IBM-1252 CP1252"
|
||||
echo "IBM-eucCN GB2312"
|
||||
echo "IBM-eucJP EUC-JP"
|
||||
echo "IBM-eucKR EUC-KR"
|
||||
echo "IBM-eucTW EUC-TW"
|
||||
echo "big5 BIG5"
|
||||
echo "GBK GBK"
|
||||
echo "TIS-620 TIS-620"
|
||||
echo "UTF-8 UTF-8"
|
||||
;;
|
||||
hpux*)
|
||||
echo "iso88591 ISO-8859-1"
|
||||
echo "iso88592 ISO-8859-2"
|
||||
echo "iso88595 ISO-8859-5"
|
||||
echo "iso88596 ISO-8859-6"
|
||||
echo "iso88597 ISO-8859-7"
|
||||
echo "iso88598 ISO-8859-8"
|
||||
echo "iso88599 ISO-8859-9"
|
||||
echo "iso885915 ISO-8859-15"
|
||||
echo "roman8 HP-ROMAN8"
|
||||
echo "arabic8 HP-ARABIC8"
|
||||
echo "greek8 HP-GREEK8"
|
||||
echo "hebrew8 HP-HEBREW8"
|
||||
echo "turkish8 HP-TURKISH8"
|
||||
echo "kana8 HP-KANA8"
|
||||
echo "tis620 TIS-620"
|
||||
echo "big5 BIG5"
|
||||
echo "eucJP EUC-JP"
|
||||
echo "eucKR EUC-KR"
|
||||
echo "eucTW EUC-TW"
|
||||
echo "hp15CN GB2312"
|
||||
#echo "ccdc ?" # what is this?
|
||||
echo "SJIS SHIFT_JIS"
|
||||
echo "utf8 UTF-8"
|
||||
;;
|
||||
irix*)
|
||||
echo "ISO8859-1 ISO-8859-1"
|
||||
echo "ISO8859-2 ISO-8859-2"
|
||||
echo "ISO8859-5 ISO-8859-5"
|
||||
echo "ISO8859-7 ISO-8859-7"
|
||||
echo "ISO8859-9 ISO-8859-9"
|
||||
echo "eucCN GB2312"
|
||||
echo "eucJP EUC-JP"
|
||||
echo "eucKR EUC-KR"
|
||||
echo "eucTW EUC-TW"
|
||||
;;
|
||||
osf*)
|
||||
echo "ISO8859-1 ISO-8859-1"
|
||||
echo "ISO8859-2 ISO-8859-2"
|
||||
echo "ISO8859-4 ISO-8859-4"
|
||||
echo "ISO8859-5 ISO-8859-5"
|
||||
echo "ISO8859-7 ISO-8859-7"
|
||||
echo "ISO8859-8 ISO-8859-8"
|
||||
echo "ISO8859-9 ISO-8859-9"
|
||||
echo "ISO8859-15 ISO-8859-15"
|
||||
echo "cp850 CP850"
|
||||
echo "big5 BIG5"
|
||||
echo "dechanyu DEC-HANYU"
|
||||
echo "dechanzi GB2312"
|
||||
echo "deckanji DEC-KANJI"
|
||||
echo "deckorean EUC-KR"
|
||||
echo "eucJP EUC-JP"
|
||||
echo "eucKR EUC-KR"
|
||||
echo "eucTW EUC-TW"
|
||||
echo "GBK GBK"
|
||||
echo "KSC5601 CP949"
|
||||
echo "sdeckanji EUC-JP"
|
||||
echo "SJIS SHIFT_JIS"
|
||||
echo "TACTIS TIS-620"
|
||||
echo "UTF-8 UTF-8"
|
||||
;;
|
||||
solaris*)
|
||||
echo "646 ASCII"
|
||||
echo "ISO8859-1 ISO-8859-1"
|
||||
echo "ISO8859-2 ISO-8859-2"
|
||||
echo "ISO8859-3 ISO-8859-3"
|
||||
echo "ISO8859-4 ISO-8859-4"
|
||||
echo "ISO8859-5 ISO-8859-5"
|
||||
echo "ISO8859-6 ISO-8859-6"
|
||||
echo "ISO8859-7 ISO-8859-7"
|
||||
echo "ISO8859-8 ISO-8859-8"
|
||||
echo "ISO8859-9 ISO-8859-9"
|
||||
echo "ISO8859-15 ISO-8859-15"
|
||||
echo "koi8-r KOI8-R"
|
||||
echo "ansi-1251 CP1251"
|
||||
echo "BIG5 BIG5"
|
||||
echo "Big5-HKSCS BIG5-HKSCS"
|
||||
echo "gb2312 GB2312"
|
||||
echo "GBK GBK"
|
||||
echo "GB18030 GB18030"
|
||||
echo "cns11643 EUC-TW"
|
||||
echo "5601 EUC-KR"
|
||||
echo "ko_KR.johap92 JOHAB"
|
||||
echo "eucJP EUC-JP"
|
||||
echo "PCK SHIFT_JIS"
|
||||
echo "TIS620.2533 TIS-620"
|
||||
#echo "sun_eu_greek ?" # what is this?
|
||||
echo "UTF-8 UTF-8"
|
||||
;;
|
||||
freebsd* | os2*)
|
||||
# FreeBSD 4.2 doesn't have nl_langinfo(CODESET); therefore
|
||||
# localcharset.c falls back to using the full locale name
|
||||
# from the environment variables.
|
||||
# Likewise for OS/2. OS/2 has XFree86 just like FreeBSD. Just
|
||||
# reuse FreeBSD's locale data for OS/2.
|
||||
echo "C ASCII"
|
||||
echo "US-ASCII ASCII"
|
||||
for l in la_LN lt_LN; do
|
||||
echo "$l.ASCII ASCII"
|
||||
done
|
||||
for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \
|
||||
fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT la_LN \
|
||||
lt_LN nl_BE nl_NL no_NO pt_PT sv_SE; do
|
||||
echo "$l.ISO_8859-1 ISO-8859-1"
|
||||
echo "$l.DIS_8859-15 ISO-8859-15"
|
||||
done
|
||||
for l in cs_CZ hr_HR hu_HU la_LN lt_LN pl_PL sl_SI; do
|
||||
echo "$l.ISO_8859-2 ISO-8859-2"
|
||||
done
|
||||
for l in la_LN lt_LT; do
|
||||
echo "$l.ISO_8859-4 ISO-8859-4"
|
||||
done
|
||||
for l in ru_RU ru_SU; do
|
||||
echo "$l.KOI8-R KOI8-R"
|
||||
echo "$l.ISO_8859-5 ISO-8859-5"
|
||||
echo "$l.CP866 CP866"
|
||||
done
|
||||
echo "uk_UA.KOI8-U KOI8-U"
|
||||
echo "zh_TW.BIG5 BIG5"
|
||||
echo "zh_TW.Big5 BIG5"
|
||||
echo "zh_CN.EUC GB2312"
|
||||
echo "ja_JP.EUC EUC-JP"
|
||||
echo "ja_JP.SJIS SHIFT_JIS"
|
||||
echo "ja_JP.Shift_JIS SHIFT_JIS"
|
||||
echo "ko_KR.EUC EUC-KR"
|
||||
;;
|
||||
netbsd*)
|
||||
echo "646 ASCII"
|
||||
echo "ISO8859-1 ISO-8859-1"
|
||||
echo "ISO8859-2 ISO-8859-2"
|
||||
echo "ISO8859-4 ISO-8859-4"
|
||||
echo "ISO8859-5 ISO-8859-5"
|
||||
echo "ISO8859-15 ISO-8859-15"
|
||||
echo "eucCN GB2312"
|
||||
echo "eucJP EUC-JP"
|
||||
echo "eucKR EUC-KR"
|
||||
echo "eucTW EUC-TW"
|
||||
echo "BIG5 BIG5"
|
||||
echo "SJIS SHIFT_JIS"
|
||||
;;
|
||||
beos*)
|
||||
# BeOS has a single locale, and it has UTF-8 encoding.
|
||||
echo "* UTF-8"
|
||||
;;
|
||||
msdosdjgpp*)
|
||||
# DJGPP 2.03 doesn't have nl_langinfo(CODESET); therefore
|
||||
# localcharset.c falls back to using the full locale name
|
||||
# from the environment variables.
|
||||
echo "#"
|
||||
echo "# The encodings given here may not all be correct."
|
||||
echo "# If you find that the encoding given for your language and"
|
||||
echo "# country is not the one your DOS machine actually uses, just"
|
||||
echo "# correct it in this file, and send a mail to"
|
||||
echo "# Juan Manuel Guerrero <st001906@hrz1.hrz.tu-darmstadt.de>"
|
||||
echo "# and Bruno Haible <bruno@clisp.org>."
|
||||
echo "#"
|
||||
echo "C ASCII"
|
||||
# ISO-8859-1 languages
|
||||
echo "ca CP850"
|
||||
echo "ca_ES CP850"
|
||||
echo "da CP865" # not CP850 ??
|
||||
echo "da_DK CP865" # not CP850 ??
|
||||
echo "de CP850"
|
||||
echo "de_AT CP850"
|
||||
echo "de_CH CP850"
|
||||
echo "de_DE CP850"
|
||||
echo "en CP850"
|
||||
echo "en_AU CP850" # not CP437 ??
|
||||
echo "en_CA CP850"
|
||||
echo "en_GB CP850"
|
||||
echo "en_NZ CP437"
|
||||
echo "en_US CP437"
|
||||
echo "en_ZA CP850" # not CP437 ??
|
||||
echo "es CP850"
|
||||
echo "es_AR CP850"
|
||||
echo "es_BO CP850"
|
||||
echo "es_CL CP850"
|
||||
echo "es_CO CP850"
|
||||
echo "es_CR CP850"
|
||||
echo "es_CU CP850"
|
||||
echo "es_DO CP850"
|
||||
echo "es_EC CP850"
|
||||
echo "es_ES CP850"
|
||||
echo "es_GT CP850"
|
||||
echo "es_HN CP850"
|
||||
echo "es_MX CP850"
|
||||
echo "es_NI CP850"
|
||||
echo "es_PA CP850"
|
||||
echo "es_PY CP850"
|
||||
echo "es_PE CP850"
|
||||
echo "es_SV CP850"
|
||||
echo "es_UY CP850"
|
||||
echo "es_VE CP850"
|
||||
echo "et CP850"
|
||||
echo "et_EE CP850"
|
||||
echo "eu CP850"
|
||||
echo "eu_ES CP850"
|
||||
echo "fi CP850"
|
||||
echo "fi_FI CP850"
|
||||
echo "fr CP850"
|
||||
echo "fr_BE CP850"
|
||||
echo "fr_CA CP850"
|
||||
echo "fr_CH CP850"
|
||||
echo "fr_FR CP850"
|
||||
echo "ga CP850"
|
||||
echo "ga_IE CP850"
|
||||
echo "gd CP850"
|
||||
echo "gd_GB CP850"
|
||||
echo "gl CP850"
|
||||
echo "gl_ES CP850"
|
||||
echo "id CP850" # not CP437 ??
|
||||
echo "id_ID CP850" # not CP437 ??
|
||||
echo "is CP861" # not CP850 ??
|
||||
echo "is_IS CP861" # not CP850 ??
|
||||
echo "it CP850"
|
||||
echo "it_CH CP850"
|
||||
echo "it_IT CP850"
|
||||
echo "lt CP775"
|
||||
echo "lt_LT CP775"
|
||||
echo "lv CP775"
|
||||
echo "lv_LV CP775"
|
||||
echo "nb CP865" # not CP850 ??
|
||||
echo "nb_NO CP865" # not CP850 ??
|
||||
echo "nl CP850"
|
||||
echo "nl_BE CP850"
|
||||
echo "nl_NL CP850"
|
||||
echo "nn CP865" # not CP850 ??
|
||||
echo "nn_NO CP865" # not CP850 ??
|
||||
echo "no CP865" # not CP850 ??
|
||||
echo "no_NO CP865" # not CP850 ??
|
||||
echo "pt CP850"
|
||||
echo "pt_BR CP850"
|
||||
echo "pt_PT CP850"
|
||||
echo "sv CP850"
|
||||
echo "sv_SE CP850"
|
||||
# ISO-8859-2 languages
|
||||
echo "cs CP852"
|
||||
echo "cs_CZ CP852"
|
||||
echo "hr CP852"
|
||||
echo "hr_HR CP852"
|
||||
echo "hu CP852"
|
||||
echo "hu_HU CP852"
|
||||
echo "pl CP852"
|
||||
echo "pl_PL CP852"
|
||||
echo "ro CP852"
|
||||
echo "ro_RO CP852"
|
||||
echo "sk CP852"
|
||||
echo "sk_SK CP852"
|
||||
echo "sl CP852"
|
||||
echo "sl_SI CP852"
|
||||
echo "sq CP852"
|
||||
echo "sq_AL CP852"
|
||||
echo "sr CP852" # CP852 or CP866 or CP855 ??
|
||||
echo "sr_YU CP852" # CP852 or CP866 or CP855 ??
|
||||
# ISO-8859-3 languages
|
||||
echo "mt CP850"
|
||||
echo "mt_MT CP850"
|
||||
# ISO-8859-5 languages
|
||||
echo "be CP866"
|
||||
echo "be_BE CP866"
|
||||
echo "bg CP866" # not CP855 ??
|
||||
echo "bg_BG CP866" # not CP855 ??
|
||||
echo "mk CP866" # not CP855 ??
|
||||
echo "mk_MK CP866" # not CP855 ??
|
||||
echo "ru CP866"
|
||||
echo "ru_RU CP866"
|
||||
echo "uk CP1125"
|
||||
echo "uk_UA CP1125"
|
||||
# ISO-8859-6 languages
|
||||
echo "ar CP864"
|
||||
echo "ar_AE CP864"
|
||||
echo "ar_DZ CP864"
|
||||
echo "ar_EG CP864"
|
||||
echo "ar_IQ CP864"
|
||||
echo "ar_IR CP864"
|
||||
echo "ar_JO CP864"
|
||||
echo "ar_KW CP864"
|
||||
echo "ar_MA CP864"
|
||||
echo "ar_OM CP864"
|
||||
echo "ar_QA CP864"
|
||||
echo "ar_SA CP864"
|
||||
echo "ar_SY CP864"
|
||||
# ISO-8859-7 languages
|
||||
echo "el CP869"
|
||||
echo "el_GR CP869"
|
||||
# ISO-8859-8 languages
|
||||
echo "he CP862"
|
||||
echo "he_IL CP862"
|
||||
# ISO-8859-9 languages
|
||||
echo "tr CP857"
|
||||
echo "tr_TR CP857"
|
||||
# Japanese
|
||||
echo "ja CP932"
|
||||
echo "ja_JP CP932"
|
||||
# Chinese
|
||||
echo "zh_CN GBK"
|
||||
echo "zh_TW CP950" # not CP938 ??
|
||||
# Korean
|
||||
echo "kr CP949" # not CP934 ??
|
||||
echo "kr_KR CP949" # not CP934 ??
|
||||
# Thai
|
||||
echo "th CP874"
|
||||
echo "th_TH CP874"
|
||||
# Other
|
||||
echo "eo CP850"
|
||||
echo "eo_EO CP850"
|
||||
;;
|
||||
esac
|
59
lib/intl/dcgettext.c
Normal file
59
lib/intl/dcgettext.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* Implementation of the dcgettext(3) function.
|
||||
Copyright (C) 1995-1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "gettextP.h"
|
||||
#ifdef _LIBC
|
||||
# include <libintl.h>
|
||||
#else
|
||||
# include "libgnuintl.h"
|
||||
#endif
|
||||
|
||||
/* @@ end of prolog @@ */
|
||||
|
||||
/* Names for the libintl functions are a problem. They must not clash
|
||||
with existing names and they should follow ANSI C. But this source
|
||||
code is also used in GNU C Library where the names have a __
|
||||
prefix. So we have to make a difference here. */
|
||||
#ifdef _LIBC
|
||||
# define DCGETTEXT __dcgettext
|
||||
# define DCIGETTEXT __dcigettext
|
||||
#else
|
||||
# define DCGETTEXT libintl_dcgettext
|
||||
# define DCIGETTEXT libintl_dcigettext
|
||||
#endif
|
||||
|
||||
/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
|
||||
locale. */
|
||||
char *
|
||||
DCGETTEXT (domainname, msgid, category)
|
||||
const char *domainname;
|
||||
const char *msgid;
|
||||
int category;
|
||||
{
|
||||
return DCIGETTEXT (domainname, msgid, NULL, 0, 0, category);
|
||||
}
|
||||
|
||||
#ifdef _LIBC
|
||||
/* Alias for function name in GNU C Library. */
|
||||
INTDEF(__dcgettext)
|
||||
weak_alias (__dcgettext, dcgettext);
|
||||
#endif
|
1238
lib/intl/dcigettext.c
Normal file
1238
lib/intl/dcigettext.c
Normal file
File diff suppressed because it is too large
Load diff
60
lib/intl/dcngettext.c
Normal file
60
lib/intl/dcngettext.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* Implementation of the dcngettext(3) function.
|
||||
Copyright (C) 1995-1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "gettextP.h"
|
||||
#ifdef _LIBC
|
||||
# include <libintl.h>
|
||||
#else
|
||||
# include "libgnuintl.h"
|
||||
#endif
|
||||
|
||||
/* @@ end of prolog @@ */
|
||||
|
||||
/* Names for the libintl functions are a problem. They must not clash
|
||||
with existing names and they should follow ANSI C. But this source
|
||||
code is also used in GNU C Library where the names have a __
|
||||
prefix. So we have to make a difference here. */
|
||||
#ifdef _LIBC
|
||||
# define DCNGETTEXT __dcngettext
|
||||
# define DCIGETTEXT __dcigettext
|
||||
#else
|
||||
# define DCNGETTEXT libintl_dcngettext
|
||||
# define DCIGETTEXT libintl_dcigettext
|
||||
#endif
|
||||
|
||||
/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
|
||||
locale. */
|
||||
char *
|
||||
DCNGETTEXT (domainname, msgid1, msgid2, n, category)
|
||||
const char *domainname;
|
||||
const char *msgid1;
|
||||
const char *msgid2;
|
||||
unsigned long int n;
|
||||
int category;
|
||||
{
|
||||
return DCIGETTEXT (domainname, msgid1, msgid2, 1, n, category);
|
||||
}
|
||||
|
||||
#ifdef _LIBC
|
||||
/* Alias for function name in GNU C Library. */
|
||||
weak_alias (__dcngettext, dcngettext);
|
||||
#endif
|
59
lib/intl/dgettext.c
Normal file
59
lib/intl/dgettext.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* Implementation of the dgettext(3) function.
|
||||
Copyright (C) 1995-1997, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
#include "gettextP.h"
|
||||
#ifdef _LIBC
|
||||
# include <libintl.h>
|
||||
#else
|
||||
# include "libgnuintl.h"
|
||||
#endif
|
||||
|
||||
/* @@ end of prolog @@ */
|
||||
|
||||
/* Names for the libintl functions are a problem. They must not clash
|
||||
with existing names and they should follow ANSI C. But this source
|
||||
code is also used in GNU C Library where the names have a __
|
||||
prefix. So we have to make a difference here. */
|
||||
#ifdef _LIBC
|
||||
# define DGETTEXT __dgettext
|
||||
# define DCGETTEXT INTUSE(__dcgettext)
|
||||
#else
|
||||
# define DGETTEXT libintl_dgettext
|
||||
# define DCGETTEXT libintl_dcgettext
|
||||
#endif
|
||||
|
||||
/* Look up MSGID in the DOMAINNAME message catalog of the current
|
||||
LC_MESSAGES locale. */
|
||||
char *
|
||||
DGETTEXT (domainname, msgid)
|
||||
const char *domainname;
|
||||
const char *msgid;
|
||||
{
|
||||
return DCGETTEXT (domainname, msgid, LC_MESSAGES);
|
||||
}
|
||||
|
||||
#ifdef _LIBC
|
||||
/* Alias for function name in GNU C Library. */
|
||||
weak_alias (__dgettext, dgettext);
|
||||
#endif
|
61
lib/intl/dngettext.c
Normal file
61
lib/intl/dngettext.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
/* Implementation of the dngettext(3) function.
|
||||
Copyright (C) 1995-1997, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
#include "gettextP.h"
|
||||
#ifdef _LIBC
|
||||
# include <libintl.h>
|
||||
#else
|
||||
# include "libgnuintl.h"
|
||||
#endif
|
||||
|
||||
/* @@ end of prolog @@ */
|
||||
|
||||
/* Names for the libintl functions are a problem. They must not clash
|
||||
with existing names and they should follow ANSI C. But this source
|
||||
code is also used in GNU C Library where the names have a __
|
||||
prefix. So we have to make a difference here. */
|
||||
#ifdef _LIBC
|
||||
# define DNGETTEXT __dngettext
|
||||
# define DCNGETTEXT __dcngettext
|
||||
#else
|
||||
# define DNGETTEXT libintl_dngettext
|
||||
# define DCNGETTEXT libintl_dcngettext
|
||||
#endif
|
||||
|
||||
/* Look up MSGID in the DOMAINNAME message catalog of the current
|
||||
LC_MESSAGES locale and skip message according to the plural form. */
|
||||
char *
|
||||
DNGETTEXT (domainname, msgid1, msgid2, n)
|
||||
const char *domainname;
|
||||
const char *msgid1;
|
||||
const char *msgid2;
|
||||
unsigned long int n;
|
||||
{
|
||||
return DCNGETTEXT (domainname, msgid1, msgid2, n, LC_MESSAGES);
|
||||
}
|
||||
|
||||
#ifdef _LIBC
|
||||
/* Alias for function name in GNU C Library. */
|
||||
weak_alias (__dngettext, dngettext);
|
||||
#endif
|
114
lib/intl/eval-plural.h
Normal file
114
lib/intl/eval-plural.h
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* Plural expression evaluation.
|
||||
Copyright (C) 2000-2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifndef STATIC
|
||||
#define STATIC static
|
||||
#endif
|
||||
|
||||
/* Evaluate the plural expression and return an index value. */
|
||||
STATIC unsigned long int plural_eval PARAMS ((struct expression *pexp,
|
||||
unsigned long int n))
|
||||
internal_function;
|
||||
|
||||
STATIC
|
||||
unsigned long int
|
||||
internal_function
|
||||
plural_eval (pexp, n)
|
||||
struct expression *pexp;
|
||||
unsigned long int n;
|
||||
{
|
||||
switch (pexp->nargs)
|
||||
{
|
||||
case 0:
|
||||
switch (pexp->operation)
|
||||
{
|
||||
case var:
|
||||
return n;
|
||||
case num:
|
||||
return pexp->val.num;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
/* pexp->operation must be lnot. */
|
||||
unsigned long int arg = plural_eval (pexp->val.args[0], n);
|
||||
return ! arg;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
unsigned long int leftarg = plural_eval (pexp->val.args[0], n);
|
||||
if (pexp->operation == lor)
|
||||
return leftarg || plural_eval (pexp->val.args[1], n);
|
||||
else if (pexp->operation == land)
|
||||
return leftarg && plural_eval (pexp->val.args[1], n);
|
||||
else
|
||||
{
|
||||
unsigned long int rightarg = plural_eval (pexp->val.args[1], n);
|
||||
|
||||
switch (pexp->operation)
|
||||
{
|
||||
case mult:
|
||||
return leftarg * rightarg;
|
||||
case divide:
|
||||
#if !INTDIV0_RAISES_SIGFPE
|
||||
if (rightarg == 0)
|
||||
raise (SIGFPE);
|
||||
#endif
|
||||
return leftarg / rightarg;
|
||||
case module:
|
||||
#if !INTDIV0_RAISES_SIGFPE
|
||||
if (rightarg == 0)
|
||||
raise (SIGFPE);
|
||||
#endif
|
||||
return leftarg % rightarg;
|
||||
case plus:
|
||||
return leftarg + rightarg;
|
||||
case minus:
|
||||
return leftarg - rightarg;
|
||||
case less_than:
|
||||
return leftarg < rightarg;
|
||||
case greater_than:
|
||||
return leftarg > rightarg;
|
||||
case less_or_equal:
|
||||
return leftarg <= rightarg;
|
||||
case greater_or_equal:
|
||||
return leftarg >= rightarg;
|
||||
case equal:
|
||||
return leftarg == rightarg;
|
||||
case not_equal:
|
||||
return leftarg != rightarg;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* NOTREACHED */
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
/* pexp->operation must be qmop. */
|
||||
unsigned long int boolarg = plural_eval (pexp->val.args[0], n);
|
||||
return plural_eval (pexp->val.args[boolarg ? 1 : 2], n);
|
||||
}
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
192
lib/intl/explodename.c
Normal file
192
lib/intl/explodename.c
Normal file
|
@ -0,0 +1,192 @@
|
|||
/* Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc.
|
||||
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "loadinfo.h"
|
||||
|
||||
/* On some strange systems still no definition of NULL is found. Sigh! */
|
||||
#ifndef NULL
|
||||
# if defined __STDC__ && __STDC__
|
||||
# define NULL ((void *) 0)
|
||||
# else
|
||||
# define NULL 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* @@ end of prolog @@ */
|
||||
|
||||
char *
|
||||
_nl_find_language (name)
|
||||
const char *name;
|
||||
{
|
||||
while (name[0] != '\0' && name[0] != '_' && name[0] != '@'
|
||||
&& name[0] != '+' && name[0] != ',')
|
||||
++name;
|
||||
|
||||
return (char *) name;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_nl_explode_name (name, language, modifier, territory, codeset,
|
||||
normalized_codeset, special, sponsor, revision)
|
||||
char *name;
|
||||
const char **language;
|
||||
const char **modifier;
|
||||
const char **territory;
|
||||
const char **codeset;
|
||||
const char **normalized_codeset;
|
||||
const char **special;
|
||||
const char **sponsor;
|
||||
const char **revision;
|
||||
{
|
||||
enum { undecided, xpg, cen } syntax;
|
||||
char *cp;
|
||||
int mask;
|
||||
|
||||
*modifier = NULL;
|
||||
*territory = NULL;
|
||||
*codeset = NULL;
|
||||
*normalized_codeset = NULL;
|
||||
*special = NULL;
|
||||
*sponsor = NULL;
|
||||
*revision = NULL;
|
||||
|
||||
/* Now we determine the single parts of the locale name. First
|
||||
look for the language. Termination symbols are `_' and `@' if
|
||||
we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */
|
||||
mask = 0;
|
||||
syntax = undecided;
|
||||
*language = cp = name;
|
||||
cp = _nl_find_language (*language);
|
||||
|
||||
if (*language == cp)
|
||||
/* This does not make sense: language has to be specified. Use
|
||||
this entry as it is without exploding. Perhaps it is an alias. */
|
||||
cp = strchr (*language, '\0');
|
||||
else if (cp[0] == '_')
|
||||
{
|
||||
/* Next is the territory. */
|
||||
cp[0] = '\0';
|
||||
*territory = ++cp;
|
||||
|
||||
while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@'
|
||||
&& cp[0] != '+' && cp[0] != ',' && cp[0] != '_')
|
||||
++cp;
|
||||
|
||||
mask |= TERRITORY;
|
||||
|
||||
if (cp[0] == '.')
|
||||
{
|
||||
/* Next is the codeset. */
|
||||
syntax = xpg;
|
||||
cp[0] = '\0';
|
||||
*codeset = ++cp;
|
||||
|
||||
while (cp[0] != '\0' && cp[0] != '@')
|
||||
++cp;
|
||||
|
||||
mask |= XPG_CODESET;
|
||||
|
||||
if (*codeset != cp && (*codeset)[0] != '\0')
|
||||
{
|
||||
*normalized_codeset = _nl_normalize_codeset (*codeset,
|
||||
cp - *codeset);
|
||||
if (strcmp (*codeset, *normalized_codeset) == 0)
|
||||
free ((char *) *normalized_codeset);
|
||||
else
|
||||
mask |= XPG_NORM_CODESET;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cp[0] == '@' || (syntax != xpg && cp[0] == '+'))
|
||||
{
|
||||
/* Next is the modifier. */
|
||||
syntax = cp[0] == '@' ? xpg : cen;
|
||||
cp[0] = '\0';
|
||||
*modifier = ++cp;
|
||||
|
||||
while (syntax == cen && cp[0] != '\0' && cp[0] != '+'
|
||||
&& cp[0] != ',' && cp[0] != '_')
|
||||
++cp;
|
||||
|
||||
mask |= XPG_MODIFIER | CEN_AUDIENCE;
|
||||
}
|
||||
|
||||
if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_'))
|
||||
{
|
||||
syntax = cen;
|
||||
|
||||
if (cp[0] == '+')
|
||||
{
|
||||
/* Next is special application (CEN syntax). */
|
||||
cp[0] = '\0';
|
||||
*special = ++cp;
|
||||
|
||||
while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_')
|
||||
++cp;
|
||||
|
||||
mask |= CEN_SPECIAL;
|
||||
}
|
||||
|
||||
if (cp[0] == ',')
|
||||
{
|
||||
/* Next is sponsor (CEN syntax). */
|
||||
cp[0] = '\0';
|
||||
*sponsor = ++cp;
|
||||
|
||||
while (cp[0] != '\0' && cp[0] != '_')
|
||||
++cp;
|
||||
|
||||
mask |= CEN_SPONSOR;
|
||||
}
|
||||
|
||||
if (cp[0] == '_')
|
||||
{
|
||||
/* Next is revision (CEN syntax). */
|
||||
cp[0] = '\0';
|
||||
*revision = ++cp;
|
||||
|
||||
mask |= CEN_REVISION;
|
||||
}
|
||||
}
|
||||
|
||||
/* For CEN syntax values it might be important to have the
|
||||
separator character in the file name, not for XPG syntax. */
|
||||
if (syntax == xpg)
|
||||
{
|
||||
if (*territory != NULL && (*territory)[0] == '\0')
|
||||
mask &= ~TERRITORY;
|
||||
|
||||
if (*codeset != NULL && (*codeset)[0] == '\0')
|
||||
mask &= ~XPG_CODESET;
|
||||
|
||||
if (*modifier != NULL && (*modifier)[0] == '\0')
|
||||
mask &= ~XPG_MODIFIER;
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
195
lib/intl/finddomain.c
Normal file
195
lib/intl/finddomain.c
Normal file
|
@ -0,0 +1,195 @@
|
|||
/* Handle list of needed message catalogs
|
||||
Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
Written by Ulrich Drepper <drepper@gnu.org>, 1995.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined HAVE_UNISTD_H || defined _LIBC
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "gettextP.h"
|
||||
#ifdef _LIBC
|
||||
# include <libintl.h>
|
||||
#else
|
||||
# include "libgnuintl.h"
|
||||
#endif
|
||||
|
||||
/* @@ end of prolog @@ */
|
||||
/* List of already loaded domains. */
|
||||
static struct loaded_l10nfile *_nl_loaded_domains;
|
||||
|
||||
|
||||
/* Return a data structure describing the message catalog described by
|
||||
the DOMAINNAME and CATEGORY parameters with respect to the currently
|
||||
established bindings. */
|
||||
struct loaded_l10nfile *
|
||||
internal_function
|
||||
_nl_find_domain (dirname, locale, domainname, domainbinding)
|
||||
const char *dirname;
|
||||
char *locale;
|
||||
const char *domainname;
|
||||
struct binding *domainbinding;
|
||||
{
|
||||
struct loaded_l10nfile *retval;
|
||||
const char *language;
|
||||
const char *modifier;
|
||||
const char *territory;
|
||||
const char *codeset;
|
||||
const char *normalized_codeset;
|
||||
const char *special;
|
||||
const char *sponsor;
|
||||
const char *revision;
|
||||
const char *alias_value;
|
||||
int mask;
|
||||
|
||||
/* LOCALE can consist of up to four recognized parts for the XPG syntax:
|
||||
|
||||
language[_territory[.codeset]][@modifier]
|
||||
|
||||
and six parts for the CEN syntax:
|
||||
|
||||
language[_territory][+audience][+special][,[sponsor][_revision]]
|
||||
|
||||
Beside the first part all of them are allowed to be missing. If
|
||||
the full specified locale is not found, the less specific one are
|
||||
looked for. The various parts will be stripped off according to
|
||||
the following order:
|
||||
(1) revision
|
||||
(2) sponsor
|
||||
(3) special
|
||||
(4) codeset
|
||||
(5) normalized codeset
|
||||
(6) territory
|
||||
(7) audience/modifier
|
||||
*/
|
||||
|
||||
/* If we have already tested for this locale entry there has to
|
||||
be one data set in the list of loaded domains. */
|
||||
retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
|
||||
strlen (dirname) + 1, 0, locale, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, domainname, 0);
|
||||
if (retval != NULL)
|
||||
{
|
||||
/* We know something about this locale. */
|
||||
int cnt;
|
||||
|
||||
if (retval->decided == 0)
|
||||
_nl_load_domain (retval, domainbinding);
|
||||
|
||||
if (retval->data != NULL)
|
||||
return retval;
|
||||
|
||||
for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
|
||||
{
|
||||
if (retval->successor[cnt]->decided == 0)
|
||||
_nl_load_domain (retval->successor[cnt], domainbinding);
|
||||
|
||||
if (retval->successor[cnt]->data != NULL)
|
||||
break;
|
||||
}
|
||||
return cnt >= 0 ? retval : NULL;
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* See whether the locale value is an alias. If yes its value
|
||||
*overwrites* the alias name. No test for the original value is
|
||||
done. */
|
||||
alias_value = _nl_expand_alias (locale);
|
||||
if (alias_value != NULL)
|
||||
{
|
||||
#if defined _LIBC || defined HAVE_STRDUP
|
||||
locale = strdup (alias_value);
|
||||
if (locale == NULL)
|
||||
return NULL;
|
||||
#else
|
||||
size_t len = strlen (alias_value) + 1;
|
||||
locale = (char *) malloc (len);
|
||||
if (locale == NULL)
|
||||
return NULL;
|
||||
|
||||
memcpy (locale, alias_value, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Now we determine the single parts of the locale name. First
|
||||
look for the language. Termination symbols are `_' and `@' if
|
||||
we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */
|
||||
mask = _nl_explode_name (locale, &language, &modifier, &territory,
|
||||
&codeset, &normalized_codeset, &special,
|
||||
&sponsor, &revision);
|
||||
|
||||
/* Create all possible locale entries which might be interested in
|
||||
generalization. */
|
||||
retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
|
||||
strlen (dirname) + 1, mask, language, territory,
|
||||
codeset, normalized_codeset, modifier, special,
|
||||
sponsor, revision, domainname, 1);
|
||||
if (retval == NULL)
|
||||
/* This means we are out of core. */
|
||||
return NULL;
|
||||
|
||||
if (retval->decided == 0)
|
||||
_nl_load_domain (retval, domainbinding);
|
||||
if (retval->data == NULL)
|
||||
{
|
||||
int cnt;
|
||||
for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
|
||||
{
|
||||
if (retval->successor[cnt]->decided == 0)
|
||||
_nl_load_domain (retval->successor[cnt], domainbinding);
|
||||
if (retval->successor[cnt]->data != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* The room for an alias was dynamically allocated. Free it now. */
|
||||
if (alias_value != NULL)
|
||||
free (locale);
|
||||
|
||||
/* The space for normalized_codeset is dynamically allocated. Free it. */
|
||||
if (mask & XPG_NORM_CODESET)
|
||||
free ((void *) normalized_codeset);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _LIBC
|
||||
libc_freeres_fn (free_mem)
|
||||
{
|
||||
struct loaded_l10nfile *runp = _nl_loaded_domains;
|
||||
|
||||
while (runp != NULL)
|
||||
{
|
||||
struct loaded_l10nfile *here = runp;
|
||||
if (runp->data != NULL)
|
||||
_nl_unload_domain ((struct loaded_domain *) runp->data);
|
||||
runp = runp->next;
|
||||
free ((char *) here->filename);
|
||||
free (here);
|
||||
}
|
||||
}
|
||||
#endif
|
64
lib/intl/gettext.c
Normal file
64
lib/intl/gettext.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* Implementation of gettext(3) function.
|
||||
Copyright (C) 1995, 1997, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef _LIBC
|
||||
# define __need_NULL
|
||||
# include <stddef.h>
|
||||
#else
|
||||
# include <stdlib.h> /* Just for NULL. */
|
||||
#endif
|
||||
|
||||
#include "gettextP.h"
|
||||
#ifdef _LIBC
|
||||
# include <libintl.h>
|
||||
#else
|
||||
# include "libgnuintl.h"
|
||||
#endif
|
||||
|
||||
/* @@ end of prolog @@ */
|
||||
|
||||
/* Names for the libintl functions are a problem. They must not clash
|
||||
with existing names and they should follow ANSI C. But this source
|
||||
code is also used in GNU C Library where the names have a __
|
||||
prefix. So we have to make a difference here. */
|
||||
#ifdef _LIBC
|
||||
# define GETTEXT __gettext
|
||||
# define DCGETTEXT INTUSE(__dcgettext)
|
||||
#else
|
||||
# define GETTEXT libintl_gettext
|
||||
# define DCGETTEXT libintl_dcgettext
|
||||
#endif
|
||||
|
||||
/* Look up MSGID in the current default message catalog for the current
|
||||
LC_MESSAGES locale. If not found, returns MSGID itself (the default
|
||||
text). */
|
||||
char *
|
||||
GETTEXT (msgid)
|
||||
const char *msgid;
|
||||
{
|
||||
return DCGETTEXT (NULL, msgid, LC_MESSAGES);
|
||||
}
|
||||
|
||||
#ifdef _LIBC
|
||||
/* Alias for function name in GNU C Library. */
|
||||
weak_alias (__gettext, gettext);
|
||||
#endif
|
224
lib/intl/gettextP.h
Normal file
224
lib/intl/gettextP.h
Normal file
|
@ -0,0 +1,224 @@
|
|||
/* Header describing internals of libintl library.
|
||||
Copyright (C) 1995-1999, 2000-2003 Free Software Foundation, Inc.
|
||||
Written by Ulrich Drepper <drepper@cygnus.com>, 1995.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifndef _GETTEXTP_H
|
||||
#define _GETTEXTP_H
|
||||
|
||||
#include <stddef.h> /* Get size_t. */
|
||||
|
||||
#ifdef _LIBC
|
||||
# include "../iconv/gconv_int.h"
|
||||
#else
|
||||
# if HAVE_ICONV
|
||||
# include <iconv.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "loadinfo.h"
|
||||
|
||||
#include "gmo.h" /* Get nls_uint32. */
|
||||
|
||||
/* @@ end of prolog @@ */
|
||||
|
||||
#ifndef PARAMS
|
||||
# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES
|
||||
# define PARAMS(args) args
|
||||
# else
|
||||
# define PARAMS(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef internal_function
|
||||
# define internal_function
|
||||
#endif
|
||||
|
||||
#ifndef attribute_hidden
|
||||
# define attribute_hidden
|
||||
#endif
|
||||
|
||||
/* Tell the compiler when a conditional or integer expression is
|
||||
almost always true or almost always false. */
|
||||
#ifndef HAVE_BUILTIN_EXPECT
|
||||
# define __builtin_expect(expr, val) (expr)
|
||||
#endif
|
||||
|
||||
#ifndef W
|
||||
# define W(flag, data) ((flag) ? SWAP (data) : (data))
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _LIBC
|
||||
# include <byteswap.h>
|
||||
# define SWAP(i) bswap_32 (i)
|
||||
#else
|
||||
static inline nls_uint32
|
||||
SWAP (i)
|
||||
nls_uint32 i;
|
||||
{
|
||||
return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* In-memory representation of system dependent string. */
|
||||
struct sysdep_string_desc
|
||||
{
|
||||
/* Length of addressed string, including the trailing NUL. */
|
||||
size_t length;
|
||||
/* Pointer to addressed string. */
|
||||
const char *pointer;
|
||||
};
|
||||
|
||||
/* The representation of an opened message catalog. */
|
||||
struct loaded_domain
|
||||
{
|
||||
/* Pointer to memory containing the .mo file. */
|
||||
const char *data;
|
||||
/* 1 if the memory is mmap()ed, 0 if the memory is malloc()ed. */
|
||||
int use_mmap;
|
||||
/* Size of mmap()ed memory. */
|
||||
size_t mmap_size;
|
||||
/* 1 if the .mo file uses a different endianness than this machine. */
|
||||
int must_swap;
|
||||
/* Pointer to additional malloc()ed memory. */
|
||||
void *malloced;
|
||||
|
||||
/* Number of static strings pairs. */
|
||||
nls_uint32 nstrings;
|
||||
/* Pointer to descriptors of original strings in the file. */
|
||||
const struct string_desc *orig_tab;
|
||||
/* Pointer to descriptors of translated strings in the file. */
|
||||
const struct string_desc *trans_tab;
|
||||
|
||||
/* Number of system dependent strings pairs. */
|
||||
nls_uint32 n_sysdep_strings;
|
||||
/* Pointer to descriptors of original sysdep strings. */
|
||||
const struct sysdep_string_desc *orig_sysdep_tab;
|
||||
/* Pointer to descriptors of translated sysdep strings. */
|
||||
const struct sysdep_string_desc *trans_sysdep_tab;
|
||||
|
||||
/* Size of hash table. */
|
||||
nls_uint32 hash_size;
|
||||
/* Pointer to hash table. */
|
||||
const nls_uint32 *hash_tab;
|
||||
/* 1 if the hash table uses a different endianness than this machine. */
|
||||
int must_swap_hash_tab;
|
||||
|
||||
int codeset_cntr;
|
||||
#ifdef _LIBC
|
||||
__gconv_t conv;
|
||||
#else
|
||||
# if HAVE_ICONV
|
||||
iconv_t conv;
|
||||
# endif
|
||||
#endif
|
||||
char **conv_tab;
|
||||
|
||||
struct expression *plural;
|
||||
unsigned long int nplurals;
|
||||
};
|
||||
|
||||
/* We want to allocate a string at the end of the struct. But ISO C
|
||||
doesn't allow zero sized arrays. */
|
||||
#ifdef __GNUC__
|
||||
# define ZERO 0
|
||||
#else
|
||||
# define ZERO 1
|
||||
#endif
|
||||
|
||||
/* A set of settings bound to a message domain. Used to store settings
|
||||
from bindtextdomain() and bind_textdomain_codeset(). */
|
||||
struct binding
|
||||
{
|
||||
struct binding *next;
|
||||
char *dirname;
|
||||
int codeset_cntr; /* Incremented each time codeset changes. */
|
||||
char *codeset;
|
||||
char domainname[ZERO];
|
||||
};
|
||||
|
||||
/* A counter which is incremented each time some previous translations
|
||||
become invalid.
|
||||
This variable is part of the external ABI of the GNU libintl. */
|
||||
extern int _nl_msg_cat_cntr;
|
||||
|
||||
#ifndef _LIBC
|
||||
const char *_nl_locale_name PARAMS ((int category, const char *categoryname));
|
||||
#endif
|
||||
|
||||
struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname,
|
||||
char *__locale,
|
||||
const char *__domainname,
|
||||
struct binding *__domainbinding))
|
||||
internal_function;
|
||||
void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain,
|
||||
struct binding *__domainbinding))
|
||||
internal_function;
|
||||
void _nl_unload_domain PARAMS ((struct loaded_domain *__domain))
|
||||
internal_function;
|
||||
const char *_nl_init_domain_conv PARAMS ((struct loaded_l10nfile *__domain_file,
|
||||
struct loaded_domain *__domain,
|
||||
struct binding *__domainbinding))
|
||||
internal_function;
|
||||
void _nl_free_domain_conv PARAMS ((struct loaded_domain *__domain))
|
||||
internal_function;
|
||||
|
||||
char *_nl_find_msg PARAMS ((struct loaded_l10nfile *domain_file,
|
||||
struct binding *domainbinding,
|
||||
const char *msgid, size_t *lengthp))
|
||||
internal_function;
|
||||
|
||||
#ifdef _LIBC
|
||||
extern char *__gettext PARAMS ((const char *__msgid));
|
||||
extern char *__dgettext PARAMS ((const char *__domainname,
|
||||
const char *__msgid));
|
||||
extern char *__dcgettext PARAMS ((const char *__domainname,
|
||||
const char *__msgid, int __category));
|
||||
extern char *__ngettext PARAMS ((const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n));
|
||||
extern char *__dngettext PARAMS ((const char *__domainname,
|
||||
const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int n));
|
||||
extern char *__dcngettext PARAMS ((const char *__domainname,
|
||||
const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n, int __category));
|
||||
extern char *__dcigettext PARAMS ((const char *__domainname,
|
||||
const char *__msgid1, const char *__msgid2,
|
||||
int __plural, unsigned long int __n,
|
||||
int __category));
|
||||
extern char *__textdomain PARAMS ((const char *__domainname));
|
||||
extern char *__bindtextdomain PARAMS ((const char *__domainname,
|
||||
const char *__dirname));
|
||||
extern char *__bind_textdomain_codeset PARAMS ((const char *__domainname,
|
||||
const char *__codeset));
|
||||
#else
|
||||
/* Declare the exported libintl_* functions, in a way that allows us to
|
||||
call them under their real name. */
|
||||
# define _INTL_REDIRECT_MACROS
|
||||
# include "libgnuintl.h"
|
||||
extern char *libintl_dcigettext PARAMS ((const char *__domainname,
|
||||
const char *__msgid1,
|
||||
const char *__msgid2,
|
||||
int __plural, unsigned long int __n,
|
||||
int __category));
|
||||
#endif
|
||||
|
||||
/* @@ begin of epilog @@ */
|
||||
|
||||
#endif /* gettextP.h */
|
148
lib/intl/gmo.h
Normal file
148
lib/intl/gmo.h
Normal file
|
@ -0,0 +1,148 @@
|
|||
/* Description of GNU message catalog format: general file layout.
|
||||
Copyright (C) 1995, 1997, 2000-2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifndef _GETTEXT_H
|
||||
#define _GETTEXT_H 1
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
/* @@ end of prolog @@ */
|
||||
|
||||
/* The magic number of the GNU message catalog format. */
|
||||
#define _MAGIC 0x950412de
|
||||
#define _MAGIC_SWAPPED 0xde120495
|
||||
|
||||
/* Revision number of the currently used .mo (binary) file format. */
|
||||
#define MO_REVISION_NUMBER 0
|
||||
|
||||
/* The following contortions are an attempt to use the C preprocessor
|
||||
to determine an unsigned integral type that is 32 bits wide. An
|
||||
alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
|
||||
as of version autoconf-2.13, the AC_CHECK_SIZEOF macro doesn't work
|
||||
when cross-compiling. */
|
||||
|
||||
#if __STDC__
|
||||
# define UINT_MAX_32_BITS 4294967295U
|
||||
#else
|
||||
# define UINT_MAX_32_BITS 0xFFFFFFFF
|
||||
#endif
|
||||
|
||||
/* If UINT_MAX isn't defined, assume it's a 32-bit type.
|
||||
This should be valid for all systems GNU cares about because
|
||||
that doesn't include 16-bit systems, and only modern systems
|
||||
(that certainly have <limits.h>) have 64+-bit integral types. */
|
||||
|
||||
#ifndef UINT_MAX
|
||||
# define UINT_MAX UINT_MAX_32_BITS
|
||||
#endif
|
||||
|
||||
#if UINT_MAX == UINT_MAX_32_BITS
|
||||
typedef unsigned nls_uint32;
|
||||
#else
|
||||
# if USHRT_MAX == UINT_MAX_32_BITS
|
||||
typedef unsigned short nls_uint32;
|
||||
# else
|
||||
# if ULONG_MAX == UINT_MAX_32_BITS
|
||||
typedef unsigned long nls_uint32;
|
||||
# else
|
||||
/* The following line is intended to throw an error. Using #error is
|
||||
not portable enough. */
|
||||
"Cannot determine unsigned 32-bit data type."
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Header for binary .mo file format. */
|
||||
struct mo_file_header
|
||||
{
|
||||
/* The magic number. */
|
||||
nls_uint32 magic;
|
||||
/* The revision number of the file format. */
|
||||
nls_uint32 revision;
|
||||
|
||||
/* The following are only used in .mo files with major revision 0. */
|
||||
|
||||
/* The number of strings pairs. */
|
||||
nls_uint32 nstrings;
|
||||
/* Offset of table with start offsets of original strings. */
|
||||
nls_uint32 orig_tab_offset;
|
||||
/* Offset of table with start offsets of translated strings. */
|
||||
nls_uint32 trans_tab_offset;
|
||||
/* Size of hash table. */
|
||||
nls_uint32 hash_tab_size;
|
||||
/* Offset of first hash table entry. */
|
||||
nls_uint32 hash_tab_offset;
|
||||
|
||||
/* The following are only used in .mo files with minor revision >= 1. */
|
||||
|
||||
/* The number of system dependent segments. */
|
||||
nls_uint32 n_sysdep_segments;
|
||||
/* Offset of table describing system dependent segments. */
|
||||
nls_uint32 sysdep_segments_offset;
|
||||
/* The number of system dependent strings pairs. */
|
||||
nls_uint32 n_sysdep_strings;
|
||||
/* Offset of table with start offsets of original sysdep strings. */
|
||||
nls_uint32 orig_sysdep_tab_offset;
|
||||
/* Offset of table with start offsets of translated sysdep strings. */
|
||||
nls_uint32 trans_sysdep_tab_offset;
|
||||
};
|
||||
|
||||
/* Descriptor for static string contained in the binary .mo file. */
|
||||
struct string_desc
|
||||
{
|
||||
/* Length of addressed string, not including the trailing NUL. */
|
||||
nls_uint32 length;
|
||||
/* Offset of string in file. */
|
||||
nls_uint32 offset;
|
||||
};
|
||||
|
||||
/* The following are only used in .mo files with minor revision >= 1. */
|
||||
|
||||
/* Descriptor for system dependent string segment. */
|
||||
struct sysdep_segment
|
||||
{
|
||||
/* Length of addressed string, including the trailing NUL. */
|
||||
nls_uint32 length;
|
||||
/* Offset of string in file. */
|
||||
nls_uint32 offset;
|
||||
};
|
||||
|
||||
/* Descriptor for system dependent string. */
|
||||
struct sysdep_string
|
||||
{
|
||||
/* Offset of static string segments in file. */
|
||||
nls_uint32 offset;
|
||||
/* Alternating sequence of static and system dependent segments.
|
||||
The last segment is a static segment, including the trailing NUL. */
|
||||
struct segment_pair
|
||||
{
|
||||
/* Size of static segment. */
|
||||
nls_uint32 segsize;
|
||||
/* Reference to system dependent string segment, or ~0 at the end. */
|
||||
nls_uint32 sysdepref;
|
||||
} segments[1];
|
||||
};
|
||||
|
||||
/* Marker for the end of the segments[] array. This has the value 0xFFFFFFFF,
|
||||
regardless whether 'int' is 16 bit, 32 bit, or 64 bit. */
|
||||
#define SEGMENTS_END ((nls_uint32) ~0)
|
||||
|
||||
/* @@ begin of epilog @@ */
|
||||
|
||||
#endif /* gettext.h */
|
59
lib/intl/hash-string.h
Normal file
59
lib/intl/hash-string.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* Description of GNU message catalog format: string hashing function.
|
||||
Copyright (C) 1995, 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
/* @@ end of prolog @@ */
|
||||
|
||||
#ifndef PARAMS
|
||||
# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES
|
||||
# define PARAMS(Args) Args
|
||||
# else
|
||||
# define PARAMS(Args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* We assume to have `unsigned long int' value with at least 32 bits. */
|
||||
#define HASHWORDBITS 32
|
||||
|
||||
|
||||
/* Defines the so called `hashpjw' function by P.J. Weinberger
|
||||
[see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
|
||||
1986, 1987 Bell Telephone Laboratories, Inc.] */
|
||||
static unsigned long int hash_string PARAMS ((const char *__str_param));
|
||||
|
||||
static inline unsigned long int
|
||||
hash_string (str_param)
|
||||
const char *str_param;
|
||||
{
|
||||
unsigned long int hval, g;
|
||||
const char *str = str_param;
|
||||
|
||||
/* Compute the hash value for the given string. */
|
||||
hval = 0;
|
||||
while (*str != '\0')
|
||||
{
|
||||
hval <<= 4;
|
||||
hval += (unsigned long int) *str++;
|
||||
g = hval & ((unsigned long int) 0xf << (HASHWORDBITS - 4));
|
||||
if (g != 0)
|
||||
{
|
||||
hval ^= g >> (HASHWORDBITS - 8);
|
||||
hval ^= g;
|
||||
}
|
||||
}
|
||||
return hval;
|
||||
}
|
151
lib/intl/intl-compat.c
Normal file
151
lib/intl/intl-compat.c
Normal file
|
@ -0,0 +1,151 @@
|
|||
/* intl-compat.c - Stub functions to call gettext functions from GNU gettext
|
||||
Library.
|
||||
Copyright (C) 1995, 2000-2003 Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "gettextP.h"
|
||||
|
||||
/* @@ end of prolog @@ */
|
||||
|
||||
/* This file redirects the gettext functions (without prefix) to those
|
||||
defined in the included GNU libintl library (with "libintl_" prefix).
|
||||
It is compiled into libintl in order to make the AM_GNU_GETTEXT test
|
||||
of gettext <= 0.11.2 work with the libintl library >= 0.11.3 which
|
||||
has the redirections primarily in the <libintl.h> include file.
|
||||
It is also compiled into libgnuintl so that libgnuintl.so can be used
|
||||
as LD_PRELOADable library on glibc systems, to provide the extra
|
||||
features that the functions in the libc don't have (namely, logging). */
|
||||
|
||||
|
||||
#undef gettext
|
||||
#undef dgettext
|
||||
#undef dcgettext
|
||||
#undef ngettext
|
||||
#undef dngettext
|
||||
#undef dcngettext
|
||||
#undef textdomain
|
||||
#undef bindtextdomain
|
||||
#undef bind_textdomain_codeset
|
||||
|
||||
|
||||
/* When building a DLL, we must export some functions. Note that because
|
||||
the functions are only defined for binary backward compatibility, we
|
||||
don't need to use __declspec(dllimport) in any case. */
|
||||
#if defined _MSC_VER && BUILDING_DLL
|
||||
# define DLL_EXPORTED __declspec(dllexport)
|
||||
#else
|
||||
# define DLL_EXPORTED
|
||||
#endif
|
||||
|
||||
|
||||
DLL_EXPORTED
|
||||
char *
|
||||
gettext (msgid)
|
||||
const char *msgid;
|
||||
{
|
||||
return libintl_gettext (msgid);
|
||||
}
|
||||
|
||||
|
||||
DLL_EXPORTED
|
||||
char *
|
||||
dgettext (domainname, msgid)
|
||||
const char *domainname;
|
||||
const char *msgid;
|
||||
{
|
||||
return libintl_dgettext (domainname, msgid);
|
||||
}
|
||||
|
||||
|
||||
DLL_EXPORTED
|
||||
char *
|
||||
dcgettext (domainname, msgid, category)
|
||||
const char *domainname;
|
||||
const char *msgid;
|
||||
int category;
|
||||
{
|
||||
return libintl_dcgettext (domainname, msgid, category);
|
||||
}
|
||||
|
||||
|
||||
DLL_EXPORTED
|
||||
char *
|
||||
ngettext (msgid1, msgid2, n)
|
||||
const char *msgid1;
|
||||
const char *msgid2;
|
||||
unsigned long int n;
|
||||
{
|
||||
return libintl_ngettext (msgid1, msgid2, n);
|
||||
}
|
||||
|
||||
|
||||
DLL_EXPORTED
|
||||
char *
|
||||
dngettext (domainname, msgid1, msgid2, n)
|
||||
const char *domainname;
|
||||
const char *msgid1;
|
||||
const char *msgid2;
|
||||
unsigned long int n;
|
||||
{
|
||||
return libintl_dngettext (domainname, msgid1, msgid2, n);
|
||||
}
|
||||
|
||||
|
||||
DLL_EXPORTED
|
||||
char *
|
||||
dcngettext (domainname, msgid1, msgid2, n, category)
|
||||
const char *domainname;
|
||||
const char *msgid1;
|
||||
const char *msgid2;
|
||||
unsigned long int n;
|
||||
int category;
|
||||
{
|
||||
return libintl_dcngettext (domainname, msgid1, msgid2, n, category);
|
||||
}
|
||||
|
||||
|
||||
DLL_EXPORTED
|
||||
char *
|
||||
textdomain (domainname)
|
||||
const char *domainname;
|
||||
{
|
||||
return libintl_textdomain (domainname);
|
||||
}
|
||||
|
||||
|
||||
DLL_EXPORTED
|
||||
char *
|
||||
bindtextdomain (domainname, dirname)
|
||||
const char *domainname;
|
||||
const char *dirname;
|
||||
{
|
||||
return libintl_bindtextdomain (domainname, dirname);
|
||||
}
|
||||
|
||||
|
||||
DLL_EXPORTED
|
||||
char *
|
||||
bind_textdomain_codeset (domainname, codeset)
|
||||
const char *domainname;
|
||||
const char *codeset;
|
||||
{
|
||||
return libintl_bind_textdomain_codeset (domainname, codeset);
|
||||
}
|
453
lib/intl/l10nflist.c
Normal file
453
lib/intl/l10nflist.c
Normal file
|
@ -0,0 +1,453 @@
|
|||
/* Copyright (C) 1995-1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
/* Tell glibc's <string.h> to provide a prototype for stpcpy().
|
||||
This must come before <config.h> because <config.h> may include
|
||||
<features.h>, and once <features.h> has been included, it's too late. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined _LIBC || defined HAVE_ARGZ_H
|
||||
# include <argz.h>
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "loadinfo.h"
|
||||
|
||||
/* On some strange systems still no definition of NULL is found. Sigh! */
|
||||
#ifndef NULL
|
||||
# if defined __STDC__ && __STDC__
|
||||
# define NULL ((void *) 0)
|
||||
# else
|
||||
# define NULL 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* @@ end of prolog @@ */
|
||||
|
||||
#ifdef _LIBC
|
||||
/* Rename the non ANSI C functions. This is required by the standard
|
||||
because some ANSI C functions will require linking with this object
|
||||
file and the name space must not be polluted. */
|
||||
# ifndef stpcpy
|
||||
# define stpcpy(dest, src) __stpcpy(dest, src)
|
||||
# endif
|
||||
#else
|
||||
# ifndef HAVE_STPCPY
|
||||
static char *stpcpy PARAMS ((char *dest, const char *src));
|
||||
# endif
|
||||
#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.
|
||||
*/
|
||||
#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))
|
||||
#else
|
||||
/* Unix */
|
||||
# define ISSLASH(C) ((C) == '/')
|
||||
# define IS_ABSOLUTE_PATH(P) ISSLASH ((P)[0])
|
||||
#endif
|
||||
|
||||
/* Define function which are usually not available. */
|
||||
|
||||
#if !defined _LIBC && !defined HAVE___ARGZ_COUNT
|
||||
/* Returns the number of strings in ARGZ. */
|
||||
static size_t argz_count__ PARAMS ((const char *argz, size_t len));
|
||||
|
||||
static size_t
|
||||
argz_count__ (argz, len)
|
||||
const char *argz;
|
||||
size_t len;
|
||||
{
|
||||
size_t count = 0;
|
||||
while (len > 0)
|
||||
{
|
||||
size_t part_len = strlen (argz);
|
||||
argz += part_len + 1;
|
||||
len -= part_len + 1;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
# undef __argz_count
|
||||
# define __argz_count(argz, len) argz_count__ (argz, len)
|
||||
#else
|
||||
# ifdef _LIBC
|
||||
# define __argz_count(argz, len) INTUSE(__argz_count) (argz, len)
|
||||
# endif
|
||||
#endif /* !_LIBC && !HAVE___ARGZ_COUNT */
|
||||
|
||||
#if !defined _LIBC && !defined HAVE___ARGZ_STRINGIFY
|
||||
/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's
|
||||
except the last into the character SEP. */
|
||||
static void argz_stringify__ PARAMS ((char *argz, size_t len, int sep));
|
||||
|
||||
static void
|
||||
argz_stringify__ (argz, len, sep)
|
||||
char *argz;
|
||||
size_t len;
|
||||
int sep;
|
||||
{
|
||||
while (len > 0)
|
||||
{
|
||||
size_t part_len = strlen (argz);
|
||||
argz += part_len;
|
||||
len -= part_len + 1;
|
||||
if (len > 0)
|
||||
*argz++ = sep;
|
||||
}
|
||||
}
|
||||
# undef __argz_stringify
|
||||
# define __argz_stringify(argz, len, sep) argz_stringify__ (argz, len, sep)
|
||||
#else
|
||||
# ifdef _LIBC
|
||||
# define __argz_stringify(argz, len, sep) \
|
||||
INTUSE(__argz_stringify) (argz, len, sep)
|
||||
# endif
|
||||
#endif /* !_LIBC && !HAVE___ARGZ_STRINGIFY */
|
||||
|
||||
#if !defined _LIBC && !defined HAVE___ARGZ_NEXT
|
||||
static char *argz_next__ PARAMS ((char *argz, size_t argz_len,
|
||||
const char *entry));
|
||||
|
||||
static char *
|
||||
argz_next__ (argz, argz_len, entry)
|
||||
char *argz;
|
||||
size_t argz_len;
|
||||
const char *entry;
|
||||
{
|
||||
if (entry)
|
||||
{
|
||||
if (entry < argz + argz_len)
|
||||
entry = strchr (entry, '\0') + 1;
|
||||
|
||||
return entry >= argz + argz_len ? NULL : (char *) entry;
|
||||
}
|
||||
else
|
||||
if (argz_len > 0)
|
||||
return argz;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
# undef __argz_next
|
||||
# define __argz_next(argz, len, entry) argz_next__ (argz, len, entry)
|
||||
#endif /* !_LIBC && !HAVE___ARGZ_NEXT */
|
||||
|
||||
|
||||
/* Return number of bits set in X. */
|
||||
static int pop PARAMS ((int x));
|
||||
|
||||
static inline int
|
||||
pop (x)
|
||||
int x;
|
||||
{
|
||||
/* We assume that no more than 16 bits are used. */
|
||||
x = ((x & ~0x5555) >> 1) + (x & 0x5555);
|
||||
x = ((x & ~0x3333) >> 2) + (x & 0x3333);
|
||||
x = ((x >> 4) + x) & 0x0f0f;
|
||||
x = ((x >> 8) + x) & 0xff;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
struct loaded_l10nfile *
|
||||
_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language,
|
||||
territory, codeset, normalized_codeset, modifier, special,
|
||||
sponsor, revision, filename, do_allocate)
|
||||
struct loaded_l10nfile **l10nfile_list;
|
||||
const char *dirlist;
|
||||
size_t dirlist_len;
|
||||
int mask;
|
||||
const char *language;
|
||||
const char *territory;
|
||||
const char *codeset;
|
||||
const char *normalized_codeset;
|
||||
const char *modifier;
|
||||
const char *special;
|
||||
const char *sponsor;
|
||||
const char *revision;
|
||||
const char *filename;
|
||||
int do_allocate;
|
||||
{
|
||||
char *abs_filename;
|
||||
struct loaded_l10nfile **lastp;
|
||||
struct loaded_l10nfile *retval;
|
||||
char *cp;
|
||||
size_t dirlist_count;
|
||||
size_t entries;
|
||||
int cnt;
|
||||
|
||||
/* If LANGUAGE contains an absolute directory specification, we ignore
|
||||
DIRLIST. */
|
||||
if (IS_ABSOLUTE_PATH (language))
|
||||
dirlist_len = 0;
|
||||
|
||||
/* Allocate room for the full file name. */
|
||||
abs_filename = (char *) malloc (dirlist_len
|
||||
+ strlen (language)
|
||||
+ ((mask & TERRITORY) != 0
|
||||
? strlen (territory) + 1 : 0)
|
||||
+ ((mask & XPG_CODESET) != 0
|
||||
? strlen (codeset) + 1 : 0)
|
||||
+ ((mask & XPG_NORM_CODESET) != 0
|
||||
? strlen (normalized_codeset) + 1 : 0)
|
||||
+ (((mask & XPG_MODIFIER) != 0
|
||||
|| (mask & CEN_AUDIENCE) != 0)
|
||||
? strlen (modifier) + 1 : 0)
|
||||
+ ((mask & CEN_SPECIAL) != 0
|
||||
? strlen (special) + 1 : 0)
|
||||
+ (((mask & CEN_SPONSOR) != 0
|
||||
|| (mask & CEN_REVISION) != 0)
|
||||
? (1 + ((mask & CEN_SPONSOR) != 0
|
||||
? strlen (sponsor) : 0)
|
||||
+ ((mask & CEN_REVISION) != 0
|
||||
? strlen (revision) + 1 : 0)) : 0)
|
||||
+ 1 + strlen (filename) + 1);
|
||||
|
||||
if (abs_filename == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Construct file name. */
|
||||
cp = abs_filename;
|
||||
if (dirlist_len > 0)
|
||||
{
|
||||
memcpy (cp, dirlist, dirlist_len);
|
||||
__argz_stringify (cp, dirlist_len, PATH_SEPARATOR);
|
||||
cp += dirlist_len;
|
||||
cp[-1] = '/';
|
||||
}
|
||||
|
||||
cp = stpcpy (cp, language);
|
||||
|
||||
if ((mask & TERRITORY) != 0)
|
||||
{
|
||||
*cp++ = '_';
|
||||
cp = stpcpy (cp, territory);
|
||||
}
|
||||
if ((mask & XPG_CODESET) != 0)
|
||||
{
|
||||
*cp++ = '.';
|
||||
cp = stpcpy (cp, codeset);
|
||||
}
|
||||
if ((mask & XPG_NORM_CODESET) != 0)
|
||||
{
|
||||
*cp++ = '.';
|
||||
cp = stpcpy (cp, normalized_codeset);
|
||||
}
|
||||
if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0)
|
||||
{
|
||||
/* This component can be part of both syntaces but has different
|
||||
leading characters. For CEN we use `+', else `@'. */
|
||||
*cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@';
|
||||
cp = stpcpy (cp, modifier);
|
||||
}
|
||||
if ((mask & CEN_SPECIAL) != 0)
|
||||
{
|
||||
*cp++ = '+';
|
||||
cp = stpcpy (cp, special);
|
||||
}
|
||||
if ((mask & (CEN_SPONSOR | CEN_REVISION)) != 0)
|
||||
{
|
||||
*cp++ = ',';
|
||||
if ((mask & CEN_SPONSOR) != 0)
|
||||
cp = stpcpy (cp, sponsor);
|
||||
if ((mask & CEN_REVISION) != 0)
|
||||
{
|
||||
*cp++ = '_';
|
||||
cp = stpcpy (cp, revision);
|
||||
}
|
||||
}
|
||||
|
||||
*cp++ = '/';
|
||||
stpcpy (cp, filename);
|
||||
|
||||
/* Look in list of already loaded domains whether it is already
|
||||
available. */
|
||||
lastp = l10nfile_list;
|
||||
for (retval = *l10nfile_list; retval != NULL; retval = retval->next)
|
||||
if (retval->filename != NULL)
|
||||
{
|
||||
int compare = strcmp (retval->filename, abs_filename);
|
||||
if (compare == 0)
|
||||
/* We found it! */
|
||||
break;
|
||||
if (compare < 0)
|
||||
{
|
||||
/* It's not in the list. */
|
||||
retval = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
lastp = &retval->next;
|
||||
}
|
||||
|
||||
if (retval != NULL || do_allocate == 0)
|
||||
{
|
||||
free (abs_filename);
|
||||
return retval;
|
||||
}
|
||||
|
||||
dirlist_count = (dirlist_len > 0 ? __argz_count (dirlist, dirlist_len) : 1);
|
||||
|
||||
/* Allocate a new loaded_l10nfile. */
|
||||
retval =
|
||||
(struct loaded_l10nfile *)
|
||||
malloc (sizeof (*retval)
|
||||
+ (((dirlist_count << pop (mask)) + (dirlist_count > 1 ? 1 : 0))
|
||||
* sizeof (struct loaded_l10nfile *)));
|
||||
if (retval == NULL)
|
||||
return NULL;
|
||||
|
||||
retval->filename = abs_filename;
|
||||
|
||||
/* We set retval->data to NULL here; it is filled in later.
|
||||
Setting retval->decided to 1 here means that retval does not
|
||||
correspond to a real file (dirlist_count > 1) or is not worth
|
||||
looking up (if an unnormalized codeset was specified). */
|
||||
retval->decided = (dirlist_count > 1
|
||||
|| ((mask & XPG_CODESET) != 0
|
||||
&& (mask & XPG_NORM_CODESET) != 0));
|
||||
retval->data = NULL;
|
||||
|
||||
retval->next = *lastp;
|
||||
*lastp = retval;
|
||||
|
||||
entries = 0;
|
||||
/* Recurse to fill the inheritance list of RETVAL.
|
||||
If the DIRLIST is a real list (i.e. DIRLIST_COUNT > 1), the RETVAL
|
||||
entry does not correspond to a real file; retval->filename contains
|
||||
colons. In this case we loop across all elements of DIRLIST and
|
||||
across all bit patterns dominated by MASK.
|
||||
If the DIRLIST is a single directory or entirely redundant (i.e.
|
||||
DIRLIST_COUNT == 1), we loop across all bit patterns dominated by
|
||||
MASK, excluding MASK itself.
|
||||
In either case, we loop down from MASK to 0. This has the effect
|
||||
that the extra bits in the locale name are dropped in this order:
|
||||
first the modifier, then the territory, then the codeset, then the
|
||||
normalized_codeset. */
|
||||
for (cnt = dirlist_count > 1 ? mask : mask - 1; cnt >= 0; --cnt)
|
||||
if ((cnt & ~mask) == 0
|
||||
&& ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0)
|
||||
&& ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0))
|
||||
{
|
||||
if (dirlist_count > 1)
|
||||
{
|
||||
/* Iterate over all elements of the DIRLIST. */
|
||||
char *dir = NULL;
|
||||
|
||||
while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir))
|
||||
!= NULL)
|
||||
retval->successor[entries++]
|
||||
= _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1,
|
||||
cnt, language, territory, codeset,
|
||||
normalized_codeset, modifier, special,
|
||||
sponsor, revision, filename, 1);
|
||||
}
|
||||
else
|
||||
retval->successor[entries++]
|
||||
= _nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len,
|
||||
cnt, language, territory, codeset,
|
||||
normalized_codeset, modifier, special,
|
||||
sponsor, revision, filename, 1);
|
||||
}
|
||||
retval->successor[entries] = NULL;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Normalize codeset name. There is no standard for the codeset
|
||||
names. Normalization allows the user to use any of the common
|
||||
names. The return value is dynamically allocated and has to be
|
||||
freed by the caller. */
|
||||
const char *
|
||||
_nl_normalize_codeset (codeset, name_len)
|
||||
const char *codeset;
|
||||
size_t name_len;
|
||||
{
|
||||
int len = 0;
|
||||
int only_digit = 1;
|
||||
char *retval;
|
||||
char *wp;
|
||||
size_t cnt;
|
||||
|
||||
for (cnt = 0; cnt < name_len; ++cnt)
|
||||
if (isalnum ((unsigned char) codeset[cnt]))
|
||||
{
|
||||
++len;
|
||||
|
||||
if (isalpha ((unsigned char) codeset[cnt]))
|
||||
only_digit = 0;
|
||||
}
|
||||
|
||||
retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1);
|
||||
|
||||
if (retval != NULL)
|
||||
{
|
||||
if (only_digit)
|
||||
wp = stpcpy (retval, "iso");
|
||||
else
|
||||
wp = retval;
|
||||
|
||||
for (cnt = 0; cnt < name_len; ++cnt)
|
||||
if (isalpha ((unsigned char) codeset[cnt]))
|
||||
*wp++ = tolower ((unsigned char) codeset[cnt]);
|
||||
else if (isdigit ((unsigned char) codeset[cnt]))
|
||||
*wp++ = codeset[cnt];
|
||||
|
||||
*wp = '\0';
|
||||
}
|
||||
|
||||
return (const char *) retval;
|
||||
}
|
||||
|
||||
|
||||
/* @@ begin of epilog @@ */
|
||||
|
||||
/* We don't want libintl.a to depend on any other library. So we
|
||||
avoid the non-standard function stpcpy. In GNU C Library this
|
||||
function is available, though. Also allow the symbol HAVE_STPCPY
|
||||
to be defined. */
|
||||
#if !_LIBC && !HAVE_STPCPY
|
||||
static char *
|
||||
stpcpy (dest, src)
|
||||
char *dest;
|
||||
const char *src;
|
||||
{
|
||||
while ((*dest++ = *src++) != '\0')
|
||||
/* Do nothing. */ ;
|
||||
return dest - 1;
|
||||
}
|
||||
#endif
|
309
lib/intl/libgnuintl.h.in
Normal file
309
lib/intl/libgnuintl.h.in
Normal file
|
@ -0,0 +1,309 @@
|
|||
/* Message catalogs for internationalization.
|
||||
Copyright (C) 1995-1997, 2000-2003 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifndef _LIBINTL_H
|
||||
#define _LIBINTL_H 1
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
/* The LC_MESSAGES locale category is the category used by the functions
|
||||
gettext() and dgettext(). It is specified in POSIX, but not in ANSI C.
|
||||
On systems that don't define it, use an arbitrary value instead.
|
||||
On Solaris, <locale.h> defines __LOCALE_H (or _LOCALE_H in Solaris 2.5)
|
||||
then includes <libintl.h> (i.e. this file!) and then only defines
|
||||
LC_MESSAGES. To avoid a redefinition warning, don't define LC_MESSAGES
|
||||
in this case. */
|
||||
#if !defined LC_MESSAGES && !(defined __LOCALE_H || (defined _LOCALE_H && defined __sun))
|
||||
# define LC_MESSAGES 1729
|
||||
#endif
|
||||
|
||||
/* We define an additional symbol to signal that we use the GNU
|
||||
implementation of gettext. */
|
||||
#define __USE_GNU_GETTEXT 1
|
||||
|
||||
/* Provide information about the supported file formats. Returns the
|
||||
maximum minor revision number supported for a given major revision. */
|
||||
#define __GNU_GETTEXT_SUPPORTED_REVISION(major) \
|
||||
((major) == 0 ? 1 : -1)
|
||||
|
||||
/* Resolve a platform specific conflict on DJGPP. GNU gettext takes
|
||||
precedence over _conio_gettext. */
|
||||
#ifdef __DJGPP__
|
||||
# undef gettext
|
||||
#endif
|
||||
|
||||
/* Use _INTL_PARAMS, not PARAMS, in order to avoid clashes with identifiers
|
||||
used by programs. Similarly, test __PROTOTYPES, not PROTOTYPES. */
|
||||
#ifndef _INTL_PARAMS
|
||||
# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES
|
||||
# define _INTL_PARAMS(args) args
|
||||
# else
|
||||
# define _INTL_PARAMS(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* We redirect the functions to those prefixed with "libintl_". This is
|
||||
necessary, because some systems define gettext/textdomain/... in the C
|
||||
library (namely, Solaris 2.4 and newer, and GNU libc 2.0 and newer).
|
||||
If we used the unprefixed names, there would be cases where the
|
||||
definition in the C library would override the one in the libintl.so
|
||||
shared library. Recall that on ELF systems, the symbols are looked
|
||||
up in the following order:
|
||||
1. in the executable,
|
||||
2. in the shared libraries specified on the link command line, in order,
|
||||
3. in the dependencies of the shared libraries specified on the link
|
||||
command line,
|
||||
4. in the dlopen()ed shared libraries, in the order in which they were
|
||||
dlopen()ed.
|
||||
The definition in the C library would override the one in libintl.so if
|
||||
either
|
||||
* -lc is given on the link command line and -lintl isn't, or
|
||||
* -lc is given on the link command line before -lintl, or
|
||||
* libintl.so is a dependency of a dlopen()ed shared library but not
|
||||
linked to the executable at link time.
|
||||
Since Solaris gettext() behaves differently than GNU gettext(), this
|
||||
would be unacceptable.
|
||||
|
||||
The redirection happens by default through macros in C, so that &gettext
|
||||
is independent of the compilation unit, but through inline functions in
|
||||
C++, in order not to interfere with the name mangling of class fields or
|
||||
class methods called 'gettext'. */
|
||||
|
||||
/* The user can define _INTL_REDIRECT_INLINE or _INTL_REDIRECT_MACROS.
|
||||
If he doesn't, we choose the method. A third possible method is
|
||||
_INTL_REDIRECT_ASM, supported only by GCC. */
|
||||
#if !(defined _INTL_REDIRECT_INLINE || defined _INTL_REDIRECT_MACROS)
|
||||
# if __GNUC__ >= 2 && !defined __APPLE_CC__ && (defined __STDC__ || defined __cplusplus)
|
||||
# define _INTL_REDIRECT_ASM
|
||||
# else
|
||||
# ifdef __cplusplus
|
||||
# define _INTL_REDIRECT_INLINE
|
||||
# else
|
||||
# define _INTL_REDIRECT_MACROS
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
/* Auxiliary macros. */
|
||||
#ifdef _INTL_REDIRECT_ASM
|
||||
# define _INTL_ASM(cname) __asm__ (_INTL_ASMNAME (__USER_LABEL_PREFIX__, #cname))
|
||||
# define _INTL_ASMNAME(prefix,cnamestring) _INTL_STRINGIFY (prefix) cnamestring
|
||||
# define _INTL_STRINGIFY(prefix) #prefix
|
||||
#else
|
||||
# define _INTL_ASM(cname)
|
||||
#endif
|
||||
|
||||
/* Look up MSGID in the current default message catalog for the current
|
||||
LC_MESSAGES locale. If not found, returns MSGID itself (the default
|
||||
text). */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_gettext (const char *__msgid);
|
||||
static inline char *gettext (const char *__msgid)
|
||||
{
|
||||
return libintl_gettext (__msgid);
|
||||
}
|
||||
#else
|
||||
#ifdef _INTL_REDIRECT_MACROS
|
||||
# define gettext libintl_gettext
|
||||
#endif
|
||||
extern char *gettext _INTL_PARAMS ((const char *__msgid))
|
||||
_INTL_ASM (libintl_gettext);
|
||||
#endif
|
||||
|
||||
/* Look up MSGID in the DOMAINNAME message catalog for the current
|
||||
LC_MESSAGES locale. */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_dgettext (const char *__domainname, const char *__msgid);
|
||||
static inline char *dgettext (const char *__domainname, const char *__msgid)
|
||||
{
|
||||
return libintl_dgettext (__domainname, __msgid);
|
||||
}
|
||||
#else
|
||||
#ifdef _INTL_REDIRECT_MACROS
|
||||
# define dgettext libintl_dgettext
|
||||
#endif
|
||||
extern char *dgettext _INTL_PARAMS ((const char *__domainname,
|
||||
const char *__msgid))
|
||||
_INTL_ASM (libintl_dgettext);
|
||||
#endif
|
||||
|
||||
/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
|
||||
locale. */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_dcgettext (const char *__domainname, const char *__msgid,
|
||||
int __category);
|
||||
static inline char *dcgettext (const char *__domainname, const char *__msgid,
|
||||
int __category)
|
||||
{
|
||||
return libintl_dcgettext (__domainname, __msgid, __category);
|
||||
}
|
||||
#else
|
||||
#ifdef _INTL_REDIRECT_MACROS
|
||||
# define dcgettext libintl_dcgettext
|
||||
#endif
|
||||
extern char *dcgettext _INTL_PARAMS ((const char *__domainname,
|
||||
const char *__msgid,
|
||||
int __category))
|
||||
_INTL_ASM (libintl_dcgettext);
|
||||
#endif
|
||||
|
||||
|
||||
/* Similar to `gettext' but select the plural form corresponding to the
|
||||
number N. */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_ngettext (const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n);
|
||||
static inline char *ngettext (const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n)
|
||||
{
|
||||
return libintl_ngettext (__msgid1, __msgid2, __n);
|
||||
}
|
||||
#else
|
||||
#ifdef _INTL_REDIRECT_MACROS
|
||||
# define ngettext libintl_ngettext
|
||||
#endif
|
||||
extern char *ngettext _INTL_PARAMS ((const char *__msgid1,
|
||||
const char *__msgid2,
|
||||
unsigned long int __n))
|
||||
_INTL_ASM (libintl_ngettext);
|
||||
#endif
|
||||
|
||||
/* Similar to `dgettext' but select the plural form corresponding to the
|
||||
number N. */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_dngettext (const char *__domainname, const char *__msgid1,
|
||||
const char *__msgid2, unsigned long int __n);
|
||||
static inline char *dngettext (const char *__domainname, const char *__msgid1,
|
||||
const char *__msgid2, unsigned long int __n)
|
||||
{
|
||||
return libintl_dngettext (__domainname, __msgid1, __msgid2, __n);
|
||||
}
|
||||
#else
|
||||
#ifdef _INTL_REDIRECT_MACROS
|
||||
# define dngettext libintl_dngettext
|
||||
#endif
|
||||
extern char *dngettext _INTL_PARAMS ((const char *__domainname,
|
||||
const char *__msgid1,
|
||||
const char *__msgid2,
|
||||
unsigned long int __n))
|
||||
_INTL_ASM (libintl_dngettext);
|
||||
#endif
|
||||
|
||||
/* Similar to `dcgettext' but select the plural form corresponding to the
|
||||
number N. */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_dcngettext (const char *__domainname,
|
||||
const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n, int __category);
|
||||
static inline char *dcngettext (const char *__domainname,
|
||||
const char *__msgid1, const char *__msgid2,
|
||||
unsigned long int __n, int __category)
|
||||
{
|
||||
return libintl_dcngettext (__domainname, __msgid1, __msgid2, __n, __category);
|
||||
}
|
||||
#else
|
||||
#ifdef _INTL_REDIRECT_MACROS
|
||||
# define dcngettext libintl_dcngettext
|
||||
#endif
|
||||
extern char *dcngettext _INTL_PARAMS ((const char *__domainname,
|
||||
const char *__msgid1,
|
||||
const char *__msgid2,
|
||||
unsigned long int __n,
|
||||
int __category))
|
||||
_INTL_ASM (libintl_dcngettext);
|
||||
#endif
|
||||
|
||||
|
||||
/* Set the current default message catalog to DOMAINNAME.
|
||||
If DOMAINNAME is null, return the current default.
|
||||
If DOMAINNAME is "", reset to the default of "messages". */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_textdomain (const char *__domainname);
|
||||
static inline char *textdomain (const char *__domainname)
|
||||
{
|
||||
return libintl_textdomain (__domainname);
|
||||
}
|
||||
#else
|
||||
#ifdef _INTL_REDIRECT_MACROS
|
||||
# define textdomain libintl_textdomain
|
||||
#endif
|
||||
extern char *textdomain _INTL_PARAMS ((const char *__domainname))
|
||||
_INTL_ASM (libintl_textdomain);
|
||||
#endif
|
||||
|
||||
/* Specify that the DOMAINNAME message catalog will be found
|
||||
in DIRNAME rather than in the system locale data base. */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_bindtextdomain (const char *__domainname,
|
||||
const char *__dirname);
|
||||
static inline char *bindtextdomain (const char *__domainname,
|
||||
const char *__dirname)
|
||||
{
|
||||
return libintl_bindtextdomain (__domainname, __dirname);
|
||||
}
|
||||
#else
|
||||
#ifdef _INTL_REDIRECT_MACROS
|
||||
# define bindtextdomain libintl_bindtextdomain
|
||||
#endif
|
||||
extern char *bindtextdomain _INTL_PARAMS ((const char *__domainname,
|
||||
const char *__dirname))
|
||||
_INTL_ASM (libintl_bindtextdomain);
|
||||
#endif
|
||||
|
||||
/* Specify the character encoding in which the messages from the
|
||||
DOMAINNAME message catalog will be returned. */
|
||||
#ifdef _INTL_REDIRECT_INLINE
|
||||
extern char *libintl_bind_textdomain_codeset (const char *__domainname,
|
||||
const char *__codeset);
|
||||
static inline char *bind_textdomain_codeset (const char *__domainname,
|
||||
const char *__codeset)
|
||||
{
|
||||
return libintl_bind_textdomain_codeset (__domainname, __codeset);
|
||||
}
|
||||
#else
|
||||
#ifdef _INTL_REDIRECT_MACROS
|
||||
# define bind_textdomain_codeset libintl_bind_textdomain_codeset
|
||||
#endif
|
||||
extern char *bind_textdomain_codeset _INTL_PARAMS ((const char *__domainname,
|
||||
const char *__codeset))
|
||||
_INTL_ASM (libintl_bind_textdomain_codeset);
|
||||
#endif
|
||||
|
||||
|
||||
/* Support for relocatable packages. */
|
||||
|
||||
/* Sets the original and the current installation prefix of the package.
|
||||
Relocation simply replaces a pathname starting with the original prefix
|
||||
by the corresponding pathname with the current prefix instead. Both
|
||||
prefixes should be directory names without trailing slash (i.e. use ""
|
||||
instead of "/"). */
|
||||
#define libintl_set_relocation_prefix libintl_set_relocation_prefix
|
||||
extern void
|
||||
libintl_set_relocation_prefix _INTL_PARAMS ((const char *orig_prefix,
|
||||
const char *curr_prefix));
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* libintl.h */
|
156
lib/intl/loadinfo.h
Normal file
156
lib/intl/loadinfo.h
Normal file
|
@ -0,0 +1,156 @@
|
|||
/* Copyright (C) 1996-1999, 2000-2002 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifndef _LOADINFO_H
|
||||
#define _LOADINFO_H 1
|
||||
|
||||
/* Declarations of locale dependent catalog lookup functions.
|
||||
Implemented in
|
||||
|
||||
localealias.c Possibly replace a locale name by another.
|
||||
explodename.c Split a locale name into its various fields.
|
||||
l10nflist.c Generate a list of filenames of possible message catalogs.
|
||||
finddomain.c Find and open the relevant message catalogs.
|
||||
|
||||
The main function _nl_find_domain() in finddomain.c is declared
|
||||
in gettextP.h.
|
||||
*/
|
||||
|
||||
#ifndef PARAMS
|
||||
# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES
|
||||
# define PARAMS(args) args
|
||||
# else
|
||||
# define PARAMS(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef internal_function
|
||||
# define internal_function
|
||||
#endif
|
||||
|
||||
/* Tell the compiler when a conditional or integer expression is
|
||||
almost always true or almost always false. */
|
||||
#ifndef HAVE_BUILTIN_EXPECT
|
||||
# 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
|
||||
#define CEN_SPECIAL 4
|
||||
#define XPG_NORM_CODESET 8
|
||||
#define XPG_CODESET 16
|
||||
#define TERRITORY 32
|
||||
#define CEN_AUDIENCE 64
|
||||
#define XPG_MODIFIER 128
|
||||
|
||||
#define CEN_SPECIFIC (CEN_REVISION|CEN_SPONSOR|CEN_SPECIAL|CEN_AUDIENCE)
|
||||
#define XPG_SPECIFIC (XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER)
|
||||
|
||||
|
||||
struct loaded_l10nfile
|
||||
{
|
||||
const char *filename;
|
||||
int decided;
|
||||
|
||||
const void *data;
|
||||
|
||||
struct loaded_l10nfile *next;
|
||||
struct loaded_l10nfile *successor[1];
|
||||
};
|
||||
|
||||
|
||||
/* Normalize codeset name. There is no standard for the codeset
|
||||
names. Normalization allows the user to use any of the common
|
||||
names. The return value is dynamically allocated and has to be
|
||||
freed by the caller. */
|
||||
extern const char *_nl_normalize_codeset PARAMS ((const char *codeset,
|
||||
size_t name_len));
|
||||
|
||||
/* Lookup a locale dependent file.
|
||||
*L10NFILE_LIST denotes a pool of lookup results of locale dependent
|
||||
files of the same kind, sorted in decreasing order of ->filename.
|
||||
DIRLIST and DIRLIST_LEN are an argz list of directories in which to
|
||||
look, containing at least one directory (i.e. DIRLIST_LEN > 0).
|
||||
MASK, LANGUAGE, TERRITORY, CODESET, NORMALIZED_CODESET, MODIFIER,
|
||||
SPECIAL, SPONSOR, REVISION are the pieces of the locale name, as
|
||||
produced by _nl_explode_name(). FILENAME is the filename suffix.
|
||||
The return value is the lookup result, either found in *L10NFILE_LIST,
|
||||
or - if DO_ALLOCATE is nonzero - freshly allocated, or possibly NULL.
|
||||
If the return value is non-NULL, it is added to *L10NFILE_LIST, and
|
||||
its ->next field denotes the chaining inside *L10NFILE_LIST, and
|
||||
furthermore its ->successor[] field contains a list of other lookup
|
||||
results from which this lookup result inherits. */
|
||||
extern struct loaded_l10nfile *
|
||||
_nl_make_l10nflist PARAMS ((struct loaded_l10nfile **l10nfile_list,
|
||||
const char *dirlist, size_t dirlist_len, int mask,
|
||||
const char *language, const char *territory,
|
||||
const char *codeset,
|
||||
const char *normalized_codeset,
|
||||
const char *modifier, const char *special,
|
||||
const char *sponsor, const char *revision,
|
||||
const char *filename, int do_allocate));
|
||||
|
||||
/* Lookup the real locale name for a locale alias NAME, or NULL if
|
||||
NAME is not a locale alias (but possibly a real locale name).
|
||||
The return value is statically allocated and must not be freed. */
|
||||
extern const char *_nl_expand_alias PARAMS ((const char *name));
|
||||
|
||||
/* Split a locale name NAME into its pieces: language, modifier,
|
||||
territory, codeset, special, sponsor, revision.
|
||||
NAME gets destructively modified: NUL bytes are inserted here and
|
||||
there. *LANGUAGE gets assigned NAME. Each of *MODIFIER, *TERRITORY,
|
||||
*CODESET, *SPECIAL, *SPONSOR, *REVISION gets assigned either a
|
||||
pointer into the old NAME string, or NULL. *NORMALIZED_CODESET
|
||||
gets assigned the expanded *CODESET, if it is different from *CODESET;
|
||||
this one is dynamically allocated and has to be freed by the caller.
|
||||
The return value is a bitmask, where each bit corresponds to one
|
||||
filled-in value:
|
||||
XPG_MODIFIER, CEN_AUDIENCE for *MODIFIER,
|
||||
TERRITORY for *TERRITORY,
|
||||
XPG_CODESET for *CODESET,
|
||||
XPG_NORM_CODESET for *NORMALIZED_CODESET,
|
||||
CEN_SPECIAL for *SPECIAL,
|
||||
CEN_SPONSOR for *SPONSOR,
|
||||
CEN_REVISION for *REVISION.
|
||||
*/
|
||||
extern int _nl_explode_name PARAMS ((char *name, const char **language,
|
||||
const char **modifier,
|
||||
const char **territory,
|
||||
const char **codeset,
|
||||
const char **normalized_codeset,
|
||||
const char **special,
|
||||
const char **sponsor,
|
||||
const char **revision));
|
||||
|
||||
/* Split a locale name NAME into a leading language part and all the
|
||||
rest. Return a pointer to the first character after the language,
|
||||
i.e. to the first byte of the rest. */
|
||||
extern char *_nl_find_language PARAMS ((const char *name));
|
||||
|
||||
#endif /* loadinfo.h */
|
1322
lib/intl/loadmsgcat.c
Normal file
1322
lib/intl/loadmsgcat.c
Normal file
File diff suppressed because it is too large
Load diff
398
lib/intl/localcharset.c
Normal file
398
lib/intl/localcharset.c
Normal file
|
@ -0,0 +1,398 @@
|
|||
/* Determine a canonical name for the current locale's character encoding.
|
||||
|
||||
Copyright (C) 2000-2003 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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 <bruno@clisp.org>. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
/* Specification. */
|
||||
#include "localcharset.h"
|
||||
|
||||
#if HAVE_STDDEF_H
|
||||
# include <stddef.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#if HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <strings.h>
|
||||
#endif
|
||||
#if HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if defined _WIN32 || defined __WIN32__
|
||||
# undef WIN32 /* avoid warning on mingw32 */
|
||||
# define WIN32
|
||||
#endif
|
||||
|
||||
#if defined __EMX__
|
||||
/* Assume EMX program runs on OS/2, even if compiled under DOS. */
|
||||
# define OS2
|
||||
#endif
|
||||
|
||||
#if !defined WIN32
|
||||
# if HAVE_LANGINFO_CODESET
|
||||
# include <langinfo.h>
|
||||
# else
|
||||
# if HAVE_SETLOCALE
|
||||
# include <locale.h>
|
||||
# endif
|
||||
# endif
|
||||
#elif defined WIN32
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
#endif
|
||||
#if defined OS2
|
||||
# define INCL_DOS
|
||||
# include <os2.h>
|
||||
#endif
|
||||
|
||||
#if ENABLE_RELOCATABLE
|
||||
# include "relocatable.h"
|
||||
#else
|
||||
# define relocate(pathname) (pathname)
|
||||
#endif
|
||||
|
||||
#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__
|
||||
/* Win32, OS/2, DOS */
|
||||
# define ISSLASH(C) ((C) == '/' || (C) == '\\')
|
||||
#endif
|
||||
|
||||
#ifndef DIRECTORY_SEPARATOR
|
||||
# define DIRECTORY_SEPARATOR '/'
|
||||
#endif
|
||||
|
||||
#ifndef ISSLASH
|
||||
# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETC_UNLOCKED
|
||||
# undef getc
|
||||
# define getc getc_unlocked
|
||||
#endif
|
||||
|
||||
/* The following static variable is declared 'volatile' to avoid a
|
||||
possible multithread problem in the function get_charset_aliases. If we
|
||||
are running in a threaded environment, and if two threads initialize
|
||||
'charset_aliases' simultaneously, both will produce the same value,
|
||||
and everything will be ok if the two assignments to 'charset_aliases'
|
||||
are atomic. But I don't know what will happen if the two assignments mix. */
|
||||
#if __STDC__ != 1
|
||||
# define volatile /* empty */
|
||||
#endif
|
||||
/* Pointer to the contents of the charset.alias file, if it has already been
|
||||
read, else NULL. Its format is:
|
||||
ALIAS_1 '\0' CANONICAL_1 '\0' ... ALIAS_n '\0' CANONICAL_n '\0' '\0' */
|
||||
static const char * volatile charset_aliases;
|
||||
|
||||
/* Return a pointer to the contents of the charset.alias file. */
|
||||
static const char *
|
||||
get_charset_aliases ()
|
||||
{
|
||||
const char *cp;
|
||||
|
||||
cp = charset_aliases;
|
||||
if (cp == NULL)
|
||||
{
|
||||
#if !(defined VMS || defined WIN32)
|
||||
FILE *fp;
|
||||
const char *dir = relocate (LIBDIR);
|
||||
const char *base = "charset.alias";
|
||||
char *file_name;
|
||||
|
||||
/* Concatenate dir and base into freshly allocated file_name. */
|
||||
{
|
||||
size_t dir_len = strlen (dir);
|
||||
size_t base_len = strlen (base);
|
||||
int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1]));
|
||||
file_name = (char *) malloc (dir_len + add_slash + base_len + 1);
|
||||
if (file_name != NULL)
|
||||
{
|
||||
memcpy (file_name, dir, dir_len);
|
||||
if (add_slash)
|
||||
file_name[dir_len] = DIRECTORY_SEPARATOR;
|
||||
memcpy (file_name + dir_len + add_slash, base, base_len + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (file_name == NULL || (fp = fopen (file_name, "r")) == NULL)
|
||||
/* Out of memory or file not found, treat it as empty. */
|
||||
cp = "";
|
||||
else
|
||||
{
|
||||
/* Parse the file's contents. */
|
||||
int c;
|
||||
char buf1[50+1];
|
||||
char buf2[50+1];
|
||||
char *res_ptr = NULL;
|
||||
size_t res_size = 0;
|
||||
size_t l1, l2;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
c = getc (fp);
|
||||
if (c == EOF)
|
||||
break;
|
||||
if (c == '\n' || c == ' ' || c == '\t')
|
||||
continue;
|
||||
if (c == '#')
|
||||
{
|
||||
/* Skip comment, to end of line. */
|
||||
do
|
||||
c = getc (fp);
|
||||
while (!(c == EOF || c == '\n'));
|
||||
if (c == EOF)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
ungetc (c, fp);
|
||||
if (fscanf (fp, "%50s %50s", buf1, buf2) < 2)
|
||||
break;
|
||||
l1 = strlen (buf1);
|
||||
l2 = strlen (buf2);
|
||||
if (res_size == 0)
|
||||
{
|
||||
res_size = l1 + 1 + l2 + 1;
|
||||
res_ptr = (char *) malloc (res_size + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
res_size += l1 + 1 + l2 + 1;
|
||||
res_ptr = (char *) realloc (res_ptr, res_size + 1);
|
||||
}
|
||||
if (res_ptr == NULL)
|
||||
{
|
||||
/* Out of memory. */
|
||||
res_size = 0;
|
||||
break;
|
||||
}
|
||||
strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1);
|
||||
strcpy (res_ptr + res_size - (l2 + 1), buf2);
|
||||
}
|
||||
fclose (fp);
|
||||
if (res_size == 0)
|
||||
cp = "";
|
||||
else
|
||||
{
|
||||
*(res_ptr + res_size) = '\0';
|
||||
cp = res_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (file_name != NULL)
|
||||
free (file_name);
|
||||
|
||||
#else
|
||||
|
||||
# if defined VMS
|
||||
/* To avoid the troubles of an extra file charset.alias_vms in the
|
||||
sources of many GNU packages, simply inline the aliases here. */
|
||||
/* The list of encodings is taken from the OpenVMS 7.3-1 documentation
|
||||
"Compaq C Run-Time Library Reference Manual for OpenVMS systems"
|
||||
section 10.7 "Handling Different Character Sets". */
|
||||
cp = "ISO8859-1" "\0" "ISO-8859-1" "\0"
|
||||
"ISO8859-2" "\0" "ISO-8859-2" "\0"
|
||||
"ISO8859-5" "\0" "ISO-8859-5" "\0"
|
||||
"ISO8859-7" "\0" "ISO-8859-7" "\0"
|
||||
"ISO8859-8" "\0" "ISO-8859-8" "\0"
|
||||
"ISO8859-9" "\0" "ISO-8859-9" "\0"
|
||||
/* Japanese */
|
||||
"eucJP" "\0" "EUC-JP" "\0"
|
||||
"SJIS" "\0" "SHIFT_JIS" "\0"
|
||||
"DECKANJI" "\0" "DEC-KANJI" "\0"
|
||||
"SDECKANJI" "\0" "EUC-JP" "\0"
|
||||
/* Chinese */
|
||||
"eucTW" "\0" "EUC-TW" "\0"
|
||||
"DECHANYU" "\0" "DEC-HANYU" "\0"
|
||||
"DECHANZI" "\0" "GB2312" "\0"
|
||||
/* Korean */
|
||||
"DECKOREAN" "\0" "EUC-KR" "\0";
|
||||
# endif
|
||||
|
||||
# if defined WIN32
|
||||
/* To avoid the troubles of installing a separate file in the same
|
||||
directory as the DLL and of retrieving the DLL's directory at
|
||||
runtime, simply inline the aliases here. */
|
||||
|
||||
cp = "CP936" "\0" "GBK" "\0"
|
||||
"CP1361" "\0" "JOHAB" "\0"
|
||||
"CP20127" "\0" "ASCII" "\0"
|
||||
"CP20866" "\0" "KOI8-R" "\0"
|
||||
"CP21866" "\0" "KOI8-RU" "\0"
|
||||
"CP28591" "\0" "ISO-8859-1" "\0"
|
||||
"CP28592" "\0" "ISO-8859-2" "\0"
|
||||
"CP28593" "\0" "ISO-8859-3" "\0"
|
||||
"CP28594" "\0" "ISO-8859-4" "\0"
|
||||
"CP28595" "\0" "ISO-8859-5" "\0"
|
||||
"CP28596" "\0" "ISO-8859-6" "\0"
|
||||
"CP28597" "\0" "ISO-8859-7" "\0"
|
||||
"CP28598" "\0" "ISO-8859-8" "\0"
|
||||
"CP28599" "\0" "ISO-8859-9" "\0"
|
||||
"CP28605" "\0" "ISO-8859-15" "\0";
|
||||
# endif
|
||||
#endif
|
||||
|
||||
charset_aliases = cp;
|
||||
}
|
||||
|
||||
return cp;
|
||||
}
|
||||
|
||||
/* Determine the current locale's character encoding, and canonicalize it
|
||||
into one of the canonical names listed in config.charset.
|
||||
The result must not be freed; it is statically allocated.
|
||||
If the canonical name cannot be determined, the result is a non-canonical
|
||||
name. */
|
||||
|
||||
#ifdef STATIC
|
||||
STATIC
|
||||
#endif
|
||||
const char *
|
||||
locale_charset ()
|
||||
{
|
||||
const char *codeset;
|
||||
const char *aliases;
|
||||
|
||||
#if !(defined WIN32 || defined OS2)
|
||||
|
||||
# if HAVE_LANGINFO_CODESET
|
||||
|
||||
/* Most systems support nl_langinfo (CODESET) nowadays. */
|
||||
codeset = nl_langinfo (CODESET);
|
||||
|
||||
# else
|
||||
|
||||
/* On old systems which lack it, use setlocale or getenv. */
|
||||
const char *locale = NULL;
|
||||
|
||||
/* But most old systems don't have a complete set of locales. Some
|
||||
(like SunOS 4 or DJGPP) have only the C locale. Therefore we don't
|
||||
use setlocale here; it would return "C" when it doesn't support the
|
||||
locale name the user has set. */
|
||||
# if HAVE_SETLOCALE && 0
|
||||
locale = setlocale (LC_CTYPE, NULL);
|
||||
# endif
|
||||
if (locale == NULL || locale[0] == '\0')
|
||||
{
|
||||
locale = getenv ("LC_ALL");
|
||||
if (locale == NULL || locale[0] == '\0')
|
||||
{
|
||||
locale = getenv ("LC_CTYPE");
|
||||
if (locale == NULL || locale[0] == '\0')
|
||||
locale = getenv ("LANG");
|
||||
}
|
||||
}
|
||||
|
||||
/* On some old systems, one used to set locale = "iso8859_1". On others,
|
||||
you set it to "language_COUNTRY.charset". In any case, we resolve it
|
||||
through the charset.alias file. */
|
||||
codeset = locale;
|
||||
|
||||
# endif
|
||||
|
||||
#elif defined WIN32
|
||||
|
||||
static char buf[2 + 10 + 1];
|
||||
|
||||
/* Woe32 has a function returning the locale's codepage as a number. */
|
||||
sprintf (buf, "CP%u", GetACP ());
|
||||
codeset = buf;
|
||||
|
||||
#elif defined OS2
|
||||
|
||||
const char *locale;
|
||||
static char buf[2 + 10 + 1];
|
||||
ULONG cp[3];
|
||||
ULONG cplen;
|
||||
|
||||
/* Allow user to override the codeset, as set in the operating system,
|
||||
with standard language environment variables. */
|
||||
locale = getenv ("LC_ALL");
|
||||
if (locale == NULL || locale[0] == '\0')
|
||||
{
|
||||
locale = getenv ("LC_CTYPE");
|
||||
if (locale == NULL || locale[0] == '\0')
|
||||
locale = getenv ("LANG");
|
||||
}
|
||||
if (locale != NULL && locale[0] != '\0')
|
||||
{
|
||||
/* If the locale name contains an encoding after the dot, return it. */
|
||||
const char *dot = strchr (locale, '.');
|
||||
|
||||
if (dot != NULL)
|
||||
{
|
||||
const char *modifier;
|
||||
|
||||
dot++;
|
||||
/* Look for the possible @... trailer and remove it, if any. */
|
||||
modifier = strchr (dot, '@');
|
||||
if (modifier == NULL)
|
||||
return dot;
|
||||
if (modifier - dot < sizeof (buf))
|
||||
{
|
||||
memcpy (buf, dot, modifier - dot);
|
||||
buf [modifier - dot] = '\0';
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
/* Resolve through the charset.alias file. */
|
||||
codeset = locale;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* OS/2 has a function returning the locale's codepage as a number. */
|
||||
if (DosQueryCp (sizeof (cp), cp, &cplen))
|
||||
codeset = "";
|
||||
else
|
||||
{
|
||||
sprintf (buf, "CP%u", cp[0]);
|
||||
codeset = buf;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (codeset == NULL)
|
||||
/* The canonical name cannot be determined. */
|
||||
codeset = "";
|
||||
|
||||
/* Resolve alias. */
|
||||
for (aliases = get_charset_aliases ();
|
||||
*aliases != '\0';
|
||||
aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
|
||||
if (strcmp (codeset, aliases) == 0
|
||||
|| (aliases[0] == '*' && aliases[1] == '\0'))
|
||||
{
|
||||
codeset = aliases + strlen (aliases) + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Don't return an empty string. GNU libc and GNU libiconv interpret
|
||||
the empty string as denoting "the locale's character encoding",
|
||||
thus GNU libiconv would call this function a second time. */
|
||||
if (codeset[0] == '\0')
|
||||
codeset = "ASCII";
|
||||
|
||||
return codeset;
|
||||
}
|
42
lib/intl/localcharset.h
Normal file
42
lib/intl/localcharset.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/* Determine a canonical name for the current locale's character encoding.
|
||||
Copyright (C) 2000-2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU CHARSET Library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifndef _LOCALCHARSET_H
|
||||
#define _LOCALCHARSET_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Determine the current locale's character encoding, and canonicalize it
|
||||
into one of the canonical names listed in config.charset.
|
||||
The result must not be freed; it is statically allocated.
|
||||
If the canonical name cannot be determined, the result is a non-canonical
|
||||
name. */
|
||||
extern const char * locale_charset (void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _LOCALCHARSET_H */
|
78
lib/intl/locale.alias
Normal file
78
lib/intl/locale.alias
Normal file
|
@ -0,0 +1,78 @@
|
|||
# Locale name alias data base.
|
||||
# Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Library 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
|
||||
# Library General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library 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.
|
||||
|
||||
# The format of this file is the same as for the corresponding file of
|
||||
# the X Window System, which normally can be found in
|
||||
# /usr/lib/X11/locale/locale.alias
|
||||
# A single line contains two fields: an alias and a substitution value.
|
||||
# All entries are case independent.
|
||||
|
||||
# Note: This file is far from being complete. If you have a value for
|
||||
# your own site which you think might be useful for others too, share
|
||||
# it with the rest of us. Send it using the `glibcbug' script to
|
||||
# bugs@gnu.org.
|
||||
|
||||
# Packages using this file:
|
||||
|
||||
bokmal no_NO.ISO-8859-1
|
||||
bokmål no_NO.ISO-8859-1
|
||||
catalan ca_ES.ISO-8859-1
|
||||
croatian hr_HR.ISO-8859-2
|
||||
czech cs_CZ.ISO-8859-2
|
||||
danish da_DK.ISO-8859-1
|
||||
dansk da_DK.ISO-8859-1
|
||||
deutsch de_DE.ISO-8859-1
|
||||
dutch nl_NL.ISO-8859-1
|
||||
eesti et_EE.ISO-8859-1
|
||||
estonian et_EE.ISO-8859-1
|
||||
finnish fi_FI.ISO-8859-1
|
||||
français fr_FR.ISO-8859-1
|
||||
french fr_FR.ISO-8859-1
|
||||
galego gl_ES.ISO-8859-1
|
||||
galician gl_ES.ISO-8859-1
|
||||
german de_DE.ISO-8859-1
|
||||
greek el_GR.ISO-8859-7
|
||||
hebrew he_IL.ISO-8859-8
|
||||
hrvatski hr_HR.ISO-8859-2
|
||||
hungarian hu_HU.ISO-8859-2
|
||||
icelandic is_IS.ISO-8859-1
|
||||
italian it_IT.ISO-8859-1
|
||||
japanese ja_JP.eucJP
|
||||
japanese.euc ja_JP.eucJP
|
||||
ja_JP ja_JP.eucJP
|
||||
ja_JP.ujis ja_JP.eucJP
|
||||
japanese.sjis ja_JP.SJIS
|
||||
korean ko_KR.eucKR
|
||||
korean.euc ko_KR.eucKR
|
||||
ko_KR ko_KR.eucKR
|
||||
lithuanian lt_LT.ISO-8859-13
|
||||
nb_NO no_NO.ISO-8859-1
|
||||
nb_NO.ISO-8859-1 no_NO.ISO-8859-1
|
||||
norwegian no_NO.ISO-8859-1
|
||||
nynorsk nn_NO.ISO-8859-1
|
||||
polish pl_PL.ISO-8859-2
|
||||
portuguese pt_PT.ISO-8859-1
|
||||
romanian ro_RO.ISO-8859-2
|
||||
russian ru_RU.ISO-8859-5
|
||||
slovak sk_SK.ISO-8859-2
|
||||
slovene sl_SI.ISO-8859-2
|
||||
slovenian sl_SI.ISO-8859-2
|
||||
spanish es_ES.ISO-8859-1
|
||||
swedish sv_SE.ISO-8859-1
|
||||
thai th_TH.TIS-620
|
||||
turkish tr_TR.ISO-8859-9
|
419
lib/intl/localealias.c
Normal file
419
lib/intl/localealias.c
Normal file
|
@ -0,0 +1,419 @@
|
|||
/* Handle aliases for locale names.
|
||||
Copyright (C) 1995-1999, 2000-2001, 2003 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
/* Tell glibc's <string.h> to provide a prototype for mempcpy().
|
||||
This must come before <config.h> because <config.h> may include
|
||||
<features.h>, and once <features.h> has been included, it's too late. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#if defined _LIBC || defined HAVE___FSETLOCKING
|
||||
# include <stdio_ext.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
# undef alloca
|
||||
# define alloca __builtin_alloca
|
||||
# define HAVE_ALLOCA 1
|
||||
#else
|
||||
# ifdef _MSC_VER
|
||||
# include <malloc.h>
|
||||
# define alloca _alloca
|
||||
# else
|
||||
# if defined HAVE_ALLOCA_H || defined _LIBC
|
||||
# include <alloca.h>
|
||||
# else
|
||||
# ifdef _AIX
|
||||
#pragma alloca
|
||||
# else
|
||||
# ifndef alloca
|
||||
char *alloca ();
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gettextP.h"
|
||||
|
||||
#if ENABLE_RELOCATABLE
|
||||
# include "relocatable.h"
|
||||
#else
|
||||
# define relocate(pathname) (pathname)
|
||||
#endif
|
||||
|
||||
/* @@ end of prolog @@ */
|
||||
|
||||
#ifdef _LIBC
|
||||
/* Rename the non ANSI C functions. This is required by the standard
|
||||
because some ANSI C functions will require linking with this object
|
||||
file and the name space must not be polluted. */
|
||||
# define strcasecmp __strcasecmp
|
||||
|
||||
# ifndef mempcpy
|
||||
# define mempcpy __mempcpy
|
||||
# endif
|
||||
# define HAVE_MEMPCPY 1
|
||||
# define HAVE___FSETLOCKING 1
|
||||
|
||||
/* We need locking here since we can be called from different places. */
|
||||
# include <bits/libc-lock.h>
|
||||
|
||||
__libc_lock_define_initialized (static, lock);
|
||||
#endif
|
||||
|
||||
#ifndef internal_function
|
||||
# define internal_function
|
||||
#endif
|
||||
|
||||
/* Some optimizations for glibc. */
|
||||
#ifdef _LIBC
|
||||
# define FEOF(fp) feof_unlocked (fp)
|
||||
# define FGETS(buf, n, fp) fgets_unlocked (buf, n, fp)
|
||||
#else
|
||||
# define FEOF(fp) feof (fp)
|
||||
# define FGETS(buf, n, fp) fgets (buf, n, fp)
|
||||
#endif
|
||||
|
||||
/* For those losing systems which don't have `alloca' we have to add
|
||||
some additional code emulating it. */
|
||||
#ifdef HAVE_ALLOCA
|
||||
# define freea(p) /* nothing */
|
||||
#else
|
||||
# define alloca(n) malloc (n)
|
||||
# define freea(p) free (p)
|
||||
#endif
|
||||
|
||||
#if defined _LIBC_REENTRANT || defined HAVE_FGETS_UNLOCKED
|
||||
# undef fgets
|
||||
# define fgets(buf, len, s) fgets_unlocked (buf, len, s)
|
||||
#endif
|
||||
#if defined _LIBC_REENTRANT || defined HAVE_FEOF_UNLOCKED
|
||||
# undef feof
|
||||
# define feof(s) feof_unlocked (s)
|
||||
#endif
|
||||
|
||||
|
||||
struct alias_map
|
||||
{
|
||||
const char *alias;
|
||||
const char *value;
|
||||
};
|
||||
|
||||
|
||||
#ifndef _LIBC
|
||||
# define libc_freeres_ptr(decl) decl
|
||||
#endif
|
||||
|
||||
libc_freeres_ptr (static char *string_space);
|
||||
static size_t string_space_act;
|
||||
static size_t string_space_max;
|
||||
libc_freeres_ptr (static struct alias_map *map);
|
||||
static size_t nmap;
|
||||
static size_t maxmap;
|
||||
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
static size_t read_alias_file PARAMS ((const char *fname, int fname_len))
|
||||
internal_function;
|
||||
static int extend_alias_table PARAMS ((void));
|
||||
static int alias_compare PARAMS ((const struct alias_map *map1,
|
||||
const struct alias_map *map2));
|
||||
|
||||
|
||||
const char *
|
||||
_nl_expand_alias (name)
|
||||
const char *name;
|
||||
{
|
||||
static const char *locale_alias_path;
|
||||
struct alias_map *retval;
|
||||
const char *result = NULL;
|
||||
size_t added;
|
||||
|
||||
#ifdef _LIBC
|
||||
__libc_lock_lock (lock);
|
||||
#endif
|
||||
|
||||
if (locale_alias_path == NULL)
|
||||
locale_alias_path = LOCALE_ALIAS_PATH;
|
||||
|
||||
do
|
||||
{
|
||||
struct alias_map item;
|
||||
|
||||
item.alias = name;
|
||||
|
||||
if (nmap > 0)
|
||||
retval = (struct alias_map *) bsearch (&item, map, nmap,
|
||||
sizeof (struct alias_map),
|
||||
(int (*) PARAMS ((const void *,
|
||||
const void *))
|
||||
) alias_compare);
|
||||
else
|
||||
retval = NULL;
|
||||
|
||||
/* We really found an alias. Return the value. */
|
||||
if (retval != NULL)
|
||||
{
|
||||
result = retval->value;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Perhaps we can find another alias file. */
|
||||
added = 0;
|
||||
while (added == 0 && locale_alias_path[0] != '\0')
|
||||
{
|
||||
const char *start;
|
||||
|
||||
while (locale_alias_path[0] == PATH_SEPARATOR)
|
||||
++locale_alias_path;
|
||||
start = locale_alias_path;
|
||||
|
||||
while (locale_alias_path[0] != '\0'
|
||||
&& locale_alias_path[0] != PATH_SEPARATOR)
|
||||
++locale_alias_path;
|
||||
|
||||
if (start < locale_alias_path)
|
||||
added = read_alias_file (start, locale_alias_path - start);
|
||||
}
|
||||
}
|
||||
while (added != 0);
|
||||
|
||||
#ifdef _LIBC
|
||||
__libc_lock_unlock (lock);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static size_t
|
||||
internal_function
|
||||
read_alias_file (fname, fname_len)
|
||||
const char *fname;
|
||||
int fname_len;
|
||||
{
|
||||
FILE *fp;
|
||||
char *full_fname;
|
||||
size_t added;
|
||||
static const char aliasfile[] = "/locale.alias";
|
||||
|
||||
full_fname = (char *) alloca (fname_len + sizeof aliasfile);
|
||||
#ifdef HAVE_MEMPCPY
|
||||
mempcpy (mempcpy (full_fname, fname, fname_len),
|
||||
aliasfile, sizeof aliasfile);
|
||||
#else
|
||||
memcpy (full_fname, fname, fname_len);
|
||||
memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile);
|
||||
#endif
|
||||
|
||||
fp = fopen (relocate (full_fname), "r");
|
||||
freea (full_fname);
|
||||
if (fp == NULL)
|
||||
return 0;
|
||||
|
||||
#ifdef HAVE___FSETLOCKING
|
||||
/* No threads present. */
|
||||
__fsetlocking (fp, FSETLOCKING_BYCALLER);
|
||||
#endif
|
||||
|
||||
added = 0;
|
||||
while (!FEOF (fp))
|
||||
{
|
||||
/* It is a reasonable approach to use a fix buffer here because
|
||||
a) we are only interested in the first two fields
|
||||
b) these fields must be usable as file names and so must not
|
||||
be that long
|
||||
We avoid a multi-kilobyte buffer here since this would use up
|
||||
stack space which we might not have if the program ran out of
|
||||
memory. */
|
||||
char buf[400];
|
||||
char *alias;
|
||||
char *value;
|
||||
char *cp;
|
||||
|
||||
if (FGETS (buf, sizeof buf, fp) == NULL)
|
||||
/* EOF reached. */
|
||||
break;
|
||||
|
||||
cp = buf;
|
||||
/* Ignore leading white space. */
|
||||
while (isspace ((unsigned char) cp[0]))
|
||||
++cp;
|
||||
|
||||
/* A leading '#' signals a comment line. */
|
||||
if (cp[0] != '\0' && cp[0] != '#')
|
||||
{
|
||||
alias = cp++;
|
||||
while (cp[0] != '\0' && !isspace ((unsigned char) cp[0]))
|
||||
++cp;
|
||||
/* Terminate alias name. */
|
||||
if (cp[0] != '\0')
|
||||
*cp++ = '\0';
|
||||
|
||||
/* Now look for the beginning of the value. */
|
||||
while (isspace ((unsigned char) cp[0]))
|
||||
++cp;
|
||||
|
||||
if (cp[0] != '\0')
|
||||
{
|
||||
size_t alias_len;
|
||||
size_t value_len;
|
||||
|
||||
value = cp++;
|
||||
while (cp[0] != '\0' && !isspace ((unsigned char) cp[0]))
|
||||
++cp;
|
||||
/* Terminate value. */
|
||||
if (cp[0] == '\n')
|
||||
{
|
||||
/* This has to be done to make the following test
|
||||
for the end of line possible. We are looking for
|
||||
the terminating '\n' which do not overwrite here. */
|
||||
*cp++ = '\0';
|
||||
*cp = '\n';
|
||||
}
|
||||
else if (cp[0] != '\0')
|
||||
*cp++ = '\0';
|
||||
|
||||
if (nmap >= maxmap)
|
||||
if (__builtin_expect (extend_alias_table (), 0))
|
||||
return added;
|
||||
|
||||
alias_len = strlen (alias) + 1;
|
||||
value_len = strlen (value) + 1;
|
||||
|
||||
if (string_space_act + alias_len + value_len > string_space_max)
|
||||
{
|
||||
/* Increase size of memory pool. */
|
||||
size_t new_size = (string_space_max
|
||||
+ (alias_len + value_len > 1024
|
||||
? alias_len + value_len : 1024));
|
||||
char *new_pool = (char *) realloc (string_space, new_size);
|
||||
if (new_pool == NULL)
|
||||
return added;
|
||||
|
||||
if (__builtin_expect (string_space != new_pool, 0))
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < nmap; i++)
|
||||
{
|
||||
map[i].alias += new_pool - string_space;
|
||||
map[i].value += new_pool - string_space;
|
||||
}
|
||||
}
|
||||
|
||||
string_space = new_pool;
|
||||
string_space_max = new_size;
|
||||
}
|
||||
|
||||
map[nmap].alias = memcpy (&string_space[string_space_act],
|
||||
alias, alias_len);
|
||||
string_space_act += alias_len;
|
||||
|
||||
map[nmap].value = memcpy (&string_space[string_space_act],
|
||||
value, value_len);
|
||||
string_space_act += value_len;
|
||||
|
||||
++nmap;
|
||||
++added;
|
||||
}
|
||||
}
|
||||
|
||||
/* Possibly not the whole line fits into the buffer. Ignore
|
||||
the rest of the line. */
|
||||
while (strchr (buf, '\n') == NULL)
|
||||
if (FGETS (buf, sizeof buf, fp) == NULL)
|
||||
/* Make sure the inner loop will be left. The outer loop
|
||||
will exit at the `feof' test. */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Should we test for ferror()? I think we have to silently ignore
|
||||
errors. --drepper */
|
||||
fclose (fp);
|
||||
|
||||
if (added > 0)
|
||||
qsort (map, nmap, sizeof (struct alias_map),
|
||||
(int (*) PARAMS ((const void *, const void *))) alias_compare);
|
||||
|
||||
return added;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
extend_alias_table ()
|
||||
{
|
||||
size_t new_size;
|
||||
struct alias_map *new_map;
|
||||
|
||||
new_size = maxmap == 0 ? 100 : 2 * maxmap;
|
||||
new_map = (struct alias_map *) realloc (map, (new_size
|
||||
* sizeof (struct alias_map)));
|
||||
if (new_map == NULL)
|
||||
/* Simply don't extend: we don't have any more core. */
|
||||
return -1;
|
||||
|
||||
map = new_map;
|
||||
maxmap = new_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
alias_compare (map1, map2)
|
||||
const struct alias_map *map1;
|
||||
const struct alias_map *map2;
|
||||
{
|
||||
#if defined _LIBC || defined HAVE_STRCASECMP
|
||||
return strcasecmp (map1->alias, map2->alias);
|
||||
#else
|
||||
const unsigned char *p1 = (const unsigned char *) map1->alias;
|
||||
const unsigned char *p2 = (const unsigned char *) map2->alias;
|
||||
unsigned char c1, c2;
|
||||
|
||||
if (p1 == p2)
|
||||
return 0;
|
||||
|
||||
do
|
||||
{
|
||||
/* I know this seems to be odd but the tolower() function in
|
||||
some systems libc cannot handle nonalpha characters. */
|
||||
c1 = isupper (*p1) ? tolower (*p1) : *p1;
|
||||
c2 = isupper (*p2) ? tolower (*p2) : *p2;
|
||||
if (c1 == '\0')
|
||||
break;
|
||||
++p1;
|
||||
++p2;
|
||||
}
|
||||
while (c1 == c2);
|
||||
|
||||
return c1 - c2;
|
||||
#endif
|
||||
}
|
772
lib/intl/localename.c
Normal file
772
lib/intl/localename.c
Normal file
|
@ -0,0 +1,772 @@
|
|||
/* Determine the current selected locale.
|
||||
Copyright (C) 1995-1999, 2000-2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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 Ulrich Drepper <drepper@gnu.org>, 1995. */
|
||||
/* Win32 code written by Tor Lillqvist <tml@iki.fi>. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <locale.h>
|
||||
|
||||
#if defined _WIN32 || defined __WIN32__
|
||||
# undef WIN32 /* avoid warning on mingw32 */
|
||||
# define WIN32
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
/* Mingw headers don't have latest language and sublanguage codes. */
|
||||
# ifndef LANG_AFRIKAANS
|
||||
# define LANG_AFRIKAANS 0x36
|
||||
# endif
|
||||
# ifndef LANG_ALBANIAN
|
||||
# define LANG_ALBANIAN 0x1c
|
||||
# endif
|
||||
# ifndef LANG_ARABIC
|
||||
# define LANG_ARABIC 0x01
|
||||
# endif
|
||||
# ifndef LANG_ARMENIAN
|
||||
# define LANG_ARMENIAN 0x2b
|
||||
# endif
|
||||
# ifndef LANG_ASSAMESE
|
||||
# define LANG_ASSAMESE 0x4d
|
||||
# endif
|
||||
# ifndef LANG_AZERI
|
||||
# define LANG_AZERI 0x2c
|
||||
# endif
|
||||
# ifndef LANG_BASQUE
|
||||
# define LANG_BASQUE 0x2d
|
||||
# endif
|
||||
# ifndef LANG_BELARUSIAN
|
||||
# define LANG_BELARUSIAN 0x23
|
||||
# endif
|
||||
# ifndef LANG_BENGALI
|
||||
# define LANG_BENGALI 0x45
|
||||
# endif
|
||||
# ifndef LANG_CATALAN
|
||||
# define LANG_CATALAN 0x03
|
||||
# endif
|
||||
# ifndef LANG_DIVEHI
|
||||
# define LANG_DIVEHI 0x65
|
||||
# endif
|
||||
# ifndef LANG_ESTONIAN
|
||||
# define LANG_ESTONIAN 0x25
|
||||
# endif
|
||||
# ifndef LANG_FAEROESE
|
||||
# define LANG_FAEROESE 0x38
|
||||
# endif
|
||||
# ifndef LANG_FARSI
|
||||
# define LANG_FARSI 0x29
|
||||
# endif
|
||||
# ifndef LANG_GALICIAN
|
||||
# define LANG_GALICIAN 0x56
|
||||
# endif
|
||||
# ifndef LANG_GEORGIAN
|
||||
# define LANG_GEORGIAN 0x37
|
||||
# endif
|
||||
# ifndef LANG_GUJARATI
|
||||
# define LANG_GUJARATI 0x47
|
||||
# endif
|
||||
# ifndef LANG_HEBREW
|
||||
# define LANG_HEBREW 0x0d
|
||||
# endif
|
||||
# ifndef LANG_HINDI
|
||||
# define LANG_HINDI 0x39
|
||||
# endif
|
||||
# ifndef LANG_INDONESIAN
|
||||
# define LANG_INDONESIAN 0x21
|
||||
# endif
|
||||
# ifndef LANG_KANNADA
|
||||
# define LANG_KANNADA 0x4b
|
||||
# endif
|
||||
# ifndef LANG_KASHMIRI
|
||||
# define LANG_KASHMIRI 0x60
|
||||
# endif
|
||||
# ifndef LANG_KAZAK
|
||||
# define LANG_KAZAK 0x3f
|
||||
# endif
|
||||
# ifndef LANG_KONKANI
|
||||
# define LANG_KONKANI 0x57
|
||||
# endif
|
||||
# ifndef LANG_KYRGYZ
|
||||
# define LANG_KYRGYZ 0x40
|
||||
# endif
|
||||
# ifndef LANG_LATVIAN
|
||||
# define LANG_LATVIAN 0x26
|
||||
# endif
|
||||
# ifndef LANG_LITHUANIAN
|
||||
# define LANG_LITHUANIAN 0x27
|
||||
# endif
|
||||
# ifndef LANG_MACEDONIAN
|
||||
# define LANG_MACEDONIAN 0x2f
|
||||
# endif
|
||||
# ifndef LANG_MALAY
|
||||
# define LANG_MALAY 0x3e
|
||||
# endif
|
||||
# ifndef LANG_MALAYALAM
|
||||
# define LANG_MALAYALAM 0x4c
|
||||
# endif
|
||||
# ifndef LANG_MANIPURI
|
||||
# define LANG_MANIPURI 0x58
|
||||
# endif
|
||||
# ifndef LANG_MARATHI
|
||||
# define LANG_MARATHI 0x4e
|
||||
# endif
|
||||
# ifndef LANG_MONGOLIAN
|
||||
# define LANG_MONGOLIAN 0x50
|
||||
# endif
|
||||
# ifndef LANG_NEPALI
|
||||
# define LANG_NEPALI 0x61
|
||||
# endif
|
||||
# ifndef LANG_ORIYA
|
||||
# define LANG_ORIYA 0x48
|
||||
# endif
|
||||
# ifndef LANG_PUNJABI
|
||||
# define LANG_PUNJABI 0x46
|
||||
# endif
|
||||
# ifndef LANG_SANSKRIT
|
||||
# define LANG_SANSKRIT 0x4f
|
||||
# endif
|
||||
# ifndef LANG_SERBIAN
|
||||
# define LANG_SERBIAN 0x1a
|
||||
# endif
|
||||
# ifndef LANG_SINDHI
|
||||
# define LANG_SINDHI 0x59
|
||||
# endif
|
||||
# ifndef LANG_SLOVAK
|
||||
# define LANG_SLOVAK 0x1b
|
||||
# endif
|
||||
# ifndef LANG_SORBIAN
|
||||
# define LANG_SORBIAN 0x2e
|
||||
# endif
|
||||
# ifndef LANG_SWAHILI
|
||||
# define LANG_SWAHILI 0x41
|
||||
# endif
|
||||
# ifndef LANG_SYRIAC
|
||||
# define LANG_SYRIAC 0x5a
|
||||
# endif
|
||||
# ifndef LANG_TAMIL
|
||||
# define LANG_TAMIL 0x49
|
||||
# endif
|
||||
# ifndef LANG_TATAR
|
||||
# define LANG_TATAR 0x44
|
||||
# endif
|
||||
# ifndef LANG_TELUGU
|
||||
# define LANG_TELUGU 0x4a
|
||||
# endif
|
||||
# ifndef LANG_THAI
|
||||
# define LANG_THAI 0x1e
|
||||
# endif
|
||||
# ifndef LANG_UKRAINIAN
|
||||
# define LANG_UKRAINIAN 0x22
|
||||
# endif
|
||||
# ifndef LANG_URDU
|
||||
# define LANG_URDU 0x20
|
||||
# endif
|
||||
# ifndef LANG_UZBEK
|
||||
# define LANG_UZBEK 0x43
|
||||
# endif
|
||||
# ifndef LANG_VIETNAMESE
|
||||
# define LANG_VIETNAMESE 0x2a
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_SAUDI_ARABIA
|
||||
# define SUBLANG_ARABIC_SAUDI_ARABIA 0x01
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_IRAQ
|
||||
# define SUBLANG_ARABIC_IRAQ 0x02
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_EGYPT
|
||||
# define SUBLANG_ARABIC_EGYPT 0x03
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_LIBYA
|
||||
# define SUBLANG_ARABIC_LIBYA 0x04
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_ALGERIA
|
||||
# define SUBLANG_ARABIC_ALGERIA 0x05
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_MOROCCO
|
||||
# define SUBLANG_ARABIC_MOROCCO 0x06
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_TUNISIA
|
||||
# define SUBLANG_ARABIC_TUNISIA 0x07
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_OMAN
|
||||
# define SUBLANG_ARABIC_OMAN 0x08
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_YEMEN
|
||||
# define SUBLANG_ARABIC_YEMEN 0x09
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_SYRIA
|
||||
# define SUBLANG_ARABIC_SYRIA 0x0a
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_JORDAN
|
||||
# define SUBLANG_ARABIC_JORDAN 0x0b
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_LEBANON
|
||||
# define SUBLANG_ARABIC_LEBANON 0x0c
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_KUWAIT
|
||||
# define SUBLANG_ARABIC_KUWAIT 0x0d
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_UAE
|
||||
# define SUBLANG_ARABIC_UAE 0x0e
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_BAHRAIN
|
||||
# define SUBLANG_ARABIC_BAHRAIN 0x0f
|
||||
# endif
|
||||
# ifndef SUBLANG_ARABIC_QATAR
|
||||
# define SUBLANG_ARABIC_QATAR 0x10
|
||||
# endif
|
||||
# ifndef SUBLANG_AZERI_LATIN
|
||||
# define SUBLANG_AZERI_LATIN 0x01
|
||||
# endif
|
||||
# ifndef SUBLANG_AZERI_CYRILLIC
|
||||
# define SUBLANG_AZERI_CYRILLIC 0x02
|
||||
# endif
|
||||
# ifndef SUBLANG_CHINESE_MACAU
|
||||
# define SUBLANG_CHINESE_MACAU 0x05
|
||||
# endif
|
||||
# ifndef SUBLANG_ENGLISH_SOUTH_AFRICA
|
||||
# define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07
|
||||
# endif
|
||||
# ifndef SUBLANG_ENGLISH_JAMAICA
|
||||
# define SUBLANG_ENGLISH_JAMAICA 0x08
|
||||
# endif
|
||||
# ifndef SUBLANG_ENGLISH_CARIBBEAN
|
||||
# define SUBLANG_ENGLISH_CARIBBEAN 0x09
|
||||
# endif
|
||||
# ifndef SUBLANG_ENGLISH_BELIZE
|
||||
# define SUBLANG_ENGLISH_BELIZE 0x0a
|
||||
# endif
|
||||
# ifndef SUBLANG_ENGLISH_TRINIDAD
|
||||
# define SUBLANG_ENGLISH_TRINIDAD 0x0b
|
||||
# endif
|
||||
# ifndef SUBLANG_ENGLISH_ZIMBABWE
|
||||
# define SUBLANG_ENGLISH_ZIMBABWE 0x0c
|
||||
# endif
|
||||
# ifndef SUBLANG_ENGLISH_PHILIPPINES
|
||||
# define SUBLANG_ENGLISH_PHILIPPINES 0x0d
|
||||
# endif
|
||||
# ifndef SUBLANG_FRENCH_LUXEMBOURG
|
||||
# define SUBLANG_FRENCH_LUXEMBOURG 0x05
|
||||
# endif
|
||||
# ifndef SUBLANG_FRENCH_MONACO
|
||||
# define SUBLANG_FRENCH_MONACO 0x06
|
||||
# endif
|
||||
# ifndef SUBLANG_GERMAN_LUXEMBOURG
|
||||
# define SUBLANG_GERMAN_LUXEMBOURG 0x04
|
||||
# endif
|
||||
# ifndef SUBLANG_GERMAN_LIECHTENSTEIN
|
||||
# define SUBLANG_GERMAN_LIECHTENSTEIN 0x05
|
||||
# endif
|
||||
# ifndef SUBLANG_KASHMIRI_INDIA
|
||||
# define SUBLANG_KASHMIRI_INDIA 0x02
|
||||
# endif
|
||||
# ifndef SUBLANG_MALAY_MALAYSIA
|
||||
# define SUBLANG_MALAY_MALAYSIA 0x01
|
||||
# endif
|
||||
# ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM
|
||||
# define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02
|
||||
# endif
|
||||
# ifndef SUBLANG_NEPALI_INDIA
|
||||
# define SUBLANG_NEPALI_INDIA 0x02
|
||||
# endif
|
||||
# ifndef SUBLANG_SERBIAN_LATIN
|
||||
# define SUBLANG_SERBIAN_LATIN 0x02
|
||||
# endif
|
||||
# ifndef SUBLANG_SERBIAN_CYRILLIC
|
||||
# define SUBLANG_SERBIAN_CYRILLIC 0x03
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_GUATEMALA
|
||||
# define SUBLANG_SPANISH_GUATEMALA 0x04
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_COSTA_RICA
|
||||
# define SUBLANG_SPANISH_COSTA_RICA 0x05
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_PANAMA
|
||||
# define SUBLANG_SPANISH_PANAMA 0x06
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_DOMINICAN_REPUBLIC
|
||||
# define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_VENEZUELA
|
||||
# define SUBLANG_SPANISH_VENEZUELA 0x08
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_COLOMBIA
|
||||
# define SUBLANG_SPANISH_COLOMBIA 0x09
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_PERU
|
||||
# define SUBLANG_SPANISH_PERU 0x0a
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_ARGENTINA
|
||||
# define SUBLANG_SPANISH_ARGENTINA 0x0b
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_ECUADOR
|
||||
# define SUBLANG_SPANISH_ECUADOR 0x0c
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_CHILE
|
||||
# define SUBLANG_SPANISH_CHILE 0x0d
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_URUGUAY
|
||||
# define SUBLANG_SPANISH_URUGUAY 0x0e
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_PARAGUAY
|
||||
# define SUBLANG_SPANISH_PARAGUAY 0x0f
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_BOLIVIA
|
||||
# define SUBLANG_SPANISH_BOLIVIA 0x10
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_EL_SALVADOR
|
||||
# define SUBLANG_SPANISH_EL_SALVADOR 0x11
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_HONDURAS
|
||||
# define SUBLANG_SPANISH_HONDURAS 0x12
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_NICARAGUA
|
||||
# define SUBLANG_SPANISH_NICARAGUA 0x13
|
||||
# endif
|
||||
# ifndef SUBLANG_SPANISH_PUERTO_RICO
|
||||
# define SUBLANG_SPANISH_PUERTO_RICO 0x14
|
||||
# endif
|
||||
# ifndef SUBLANG_SWEDISH_FINLAND
|
||||
# define SUBLANG_SWEDISH_FINLAND 0x02
|
||||
# endif
|
||||
# ifndef SUBLANG_URDU_PAKISTAN
|
||||
# define SUBLANG_URDU_PAKISTAN 0x01
|
||||
# endif
|
||||
# ifndef SUBLANG_URDU_INDIA
|
||||
# define SUBLANG_URDU_INDIA 0x02
|
||||
# endif
|
||||
# ifndef SUBLANG_UZBEK_LATIN
|
||||
# define SUBLANG_UZBEK_LATIN 0x01
|
||||
# endif
|
||||
# ifndef SUBLANG_UZBEK_CYRILLIC
|
||||
# define SUBLANG_UZBEK_CYRILLIC 0x02
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* XPG3 defines the result of 'setlocale (category, NULL)' as:
|
||||
"Directs 'setlocale()' to query 'category' and return the current
|
||||
setting of 'local'."
|
||||
However it does not specify the exact format. Neither do SUSV2 and
|
||||
ISO C 99. So we can use this feature only on selected systems (e.g.
|
||||
those using GNU C Library). */
|
||||
#if defined _LIBC || (defined __GNU_LIBRARY__ && __GNU_LIBRARY__ >= 2)
|
||||
# define HAVE_LOCALE_NULL
|
||||
#endif
|
||||
|
||||
/* Determine the current locale's name, and canonicalize it into XPG syntax
|
||||
language[_territory[.codeset]][@modifier]
|
||||
The codeset part in the result is not reliable; the locale_charset()
|
||||
should be used for codeset information instead.
|
||||
The result must not be freed; it is statically allocated. */
|
||||
|
||||
const char *
|
||||
_nl_locale_name (category, categoryname)
|
||||
int category;
|
||||
const char *categoryname;
|
||||
{
|
||||
const char *retval;
|
||||
|
||||
#ifndef WIN32
|
||||
|
||||
/* Use the POSIX methods of looking to 'LC_ALL', 'LC_xxx', and 'LANG'.
|
||||
On some systems this can be done by the 'setlocale' function itself. */
|
||||
# if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
|
||||
retval = setlocale (category, NULL);
|
||||
# else
|
||||
/* Setting of LC_ALL overwrites all other. */
|
||||
retval = getenv ("LC_ALL");
|
||||
if (retval == NULL || retval[0] == '\0')
|
||||
{
|
||||
/* Next comes the name of the desired category. */
|
||||
retval = getenv (categoryname);
|
||||
if (retval == NULL || retval[0] == '\0')
|
||||
{
|
||||
/* Last possibility is the LANG environment variable. */
|
||||
retval = getenv ("LANG");
|
||||
if (retval == NULL || retval[0] == '\0')
|
||||
/* We use C as the default domain. POSIX says this is
|
||||
implementation defined. */
|
||||
retval = "C";
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
return retval;
|
||||
|
||||
#else /* WIN32 */
|
||||
|
||||
/* Return an XPG style locale name language[_territory][@modifier].
|
||||
Don't even bother determining the codeset; it's not useful in this
|
||||
context, because message catalogs are not specific to a single
|
||||
codeset. */
|
||||
|
||||
LCID lcid;
|
||||
LANGID langid;
|
||||
int primary, sub;
|
||||
|
||||
/* Let the user override the system settings through environment
|
||||
variables, as on POSIX systems. */
|
||||
retval = getenv ("LC_ALL");
|
||||
if (retval != NULL && retval[0] != '\0')
|
||||
return retval;
|
||||
retval = getenv (categoryname);
|
||||
if (retval != NULL && retval[0] != '\0')
|
||||
return retval;
|
||||
retval = getenv ("LANG");
|
||||
if (retval != NULL && retval[0] != '\0')
|
||||
return retval;
|
||||
|
||||
/* Use native Win32 API locale ID. */
|
||||
lcid = GetThreadLocale ();
|
||||
|
||||
/* Strip off the sorting rules, keep only the language part. */
|
||||
langid = LANGIDFROMLCID (lcid);
|
||||
|
||||
/* Split into language and territory part. */
|
||||
primary = PRIMARYLANGID (langid);
|
||||
sub = SUBLANGID (langid);
|
||||
|
||||
/* Dispatch on language.
|
||||
See also http://www.unicode.org/unicode/onlinedat/languages.html .
|
||||
For details about languages, see http://www.ethnologue.com/ . */
|
||||
switch (primary)
|
||||
{
|
||||
case LANG_AFRIKAANS: return "af_ZA";
|
||||
case LANG_ALBANIAN: return "sq_AL";
|
||||
case 0x5e: /* AMHARIC */ return "am_ET";
|
||||
case LANG_ARABIC:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_ARABIC_SAUDI_ARABIA: return "ar_SA";
|
||||
case SUBLANG_ARABIC_IRAQ: return "ar_IQ";
|
||||
case SUBLANG_ARABIC_EGYPT: return "ar_EG";
|
||||
case SUBLANG_ARABIC_LIBYA: return "ar_LY";
|
||||
case SUBLANG_ARABIC_ALGERIA: return "ar_DZ";
|
||||
case SUBLANG_ARABIC_MOROCCO: return "ar_MA";
|
||||
case SUBLANG_ARABIC_TUNISIA: return "ar_TN";
|
||||
case SUBLANG_ARABIC_OMAN: return "ar_OM";
|
||||
case SUBLANG_ARABIC_YEMEN: return "ar_YE";
|
||||
case SUBLANG_ARABIC_SYRIA: return "ar_SY";
|
||||
case SUBLANG_ARABIC_JORDAN: return "ar_JO";
|
||||
case SUBLANG_ARABIC_LEBANON: return "ar_LB";
|
||||
case SUBLANG_ARABIC_KUWAIT: return "ar_KW";
|
||||
case SUBLANG_ARABIC_UAE: return "ar_AE";
|
||||
case SUBLANG_ARABIC_BAHRAIN: return "ar_BH";
|
||||
case SUBLANG_ARABIC_QATAR: return "ar_QA";
|
||||
}
|
||||
return "ar";
|
||||
case LANG_ARMENIAN: return "hy_AM";
|
||||
case LANG_ASSAMESE: return "as_IN";
|
||||
case LANG_AZERI:
|
||||
switch (sub)
|
||||
{
|
||||
/* FIXME: Adjust this when Azerbaijani locales appear on Unix. */
|
||||
case SUBLANG_AZERI_LATIN: return "az_AZ@latin";
|
||||
case SUBLANG_AZERI_CYRILLIC: return "az_AZ@cyrillic";
|
||||
}
|
||||
return "az";
|
||||
case LANG_BASQUE:
|
||||
return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR". */
|
||||
case LANG_BELARUSIAN: return "be_BY";
|
||||
case LANG_BENGALI: return "bn_IN";
|
||||
case LANG_BULGARIAN: return "bg_BG";
|
||||
case 0x55: /* BURMESE */ return "my_MM";
|
||||
case 0x53: /* CAMBODIAN */ return "km_KH";
|
||||
case LANG_CATALAN: return "ca_ES";
|
||||
case 0x5c: /* CHEROKEE */ return "chr_US";
|
||||
case LANG_CHINESE:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_CHINESE_TRADITIONAL: return "zh_TW";
|
||||
case SUBLANG_CHINESE_SIMPLIFIED: return "zh_CN";
|
||||
case SUBLANG_CHINESE_HONGKONG: return "zh_HK";
|
||||
case SUBLANG_CHINESE_SINGAPORE: return "zh_SG";
|
||||
case SUBLANG_CHINESE_MACAU: return "zh_MO";
|
||||
}
|
||||
return "zh";
|
||||
case LANG_CROATIAN: /* LANG_CROATIAN == LANG_SERBIAN
|
||||
* What used to be called Serbo-Croatian
|
||||
* should really now be two separate
|
||||
* languages because of political reasons.
|
||||
* (Says tml, who knows nothing about Serbian
|
||||
* or Croatian.)
|
||||
* (I can feel those flames coming already.)
|
||||
*/
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_DEFAULT: return "hr_HR";
|
||||
case SUBLANG_SERBIAN_LATIN: return "sr_YU";
|
||||
case SUBLANG_SERBIAN_CYRILLIC: return "sr_YU@cyrillic";
|
||||
}
|
||||
return "hr";
|
||||
case LANG_CZECH: return "cs_CZ";
|
||||
case LANG_DANISH: return "da_DK";
|
||||
case LANG_DIVEHI: return "div_MV";
|
||||
case LANG_DUTCH:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_DUTCH: return "nl_NL";
|
||||
case SUBLANG_DUTCH_BELGIAN: /* FLEMISH, VLAAMS */ return "nl_BE";
|
||||
}
|
||||
return "nl";
|
||||
case 0x66: /* EDO */ return "bin_NG";
|
||||
case LANG_ENGLISH:
|
||||
switch (sub)
|
||||
{
|
||||
/* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought
|
||||
* English was the language spoken in England.
|
||||
* Oh well.
|
||||
*/
|
||||
case SUBLANG_ENGLISH_US: return "en_US";
|
||||
case SUBLANG_ENGLISH_UK: return "en_GB";
|
||||
case SUBLANG_ENGLISH_AUS: return "en_AU";
|
||||
case SUBLANG_ENGLISH_CAN: return "en_CA";
|
||||
case SUBLANG_ENGLISH_NZ: return "en_NZ";
|
||||
case SUBLANG_ENGLISH_EIRE: return "en_IE";
|
||||
case SUBLANG_ENGLISH_SOUTH_AFRICA: return "en_ZA";
|
||||
case SUBLANG_ENGLISH_JAMAICA: return "en_JM";
|
||||
case SUBLANG_ENGLISH_CARIBBEAN: return "en_GD"; /* Grenada? */
|
||||
case SUBLANG_ENGLISH_BELIZE: return "en_BZ";
|
||||
case SUBLANG_ENGLISH_TRINIDAD: return "en_TT";
|
||||
case SUBLANG_ENGLISH_ZIMBABWE: return "en_ZW";
|
||||
case SUBLANG_ENGLISH_PHILIPPINES: return "en_PH";
|
||||
}
|
||||
return "en";
|
||||
case LANG_ESTONIAN: return "et_EE";
|
||||
case LANG_FAEROESE: return "fo_FO";
|
||||
case LANG_FARSI: return "fa_IR";
|
||||
case LANG_FINNISH: return "fi_FI";
|
||||
case LANG_FRENCH:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_FRENCH: return "fr_FR";
|
||||
case SUBLANG_FRENCH_BELGIAN: /* WALLOON */ return "fr_BE";
|
||||
case SUBLANG_FRENCH_CANADIAN: return "fr_CA";
|
||||
case SUBLANG_FRENCH_SWISS: return "fr_CH";
|
||||
case SUBLANG_FRENCH_LUXEMBOURG: return "fr_LU";
|
||||
case SUBLANG_FRENCH_MONACO: return "fr_MC";
|
||||
}
|
||||
return "fr";
|
||||
case 0x62: /* FRISIAN */ return "fy_NL";
|
||||
case 0x67: /* FULFULDE */ return "ful_NG";
|
||||
case 0x3c: /* GAELIC */
|
||||
switch (sub)
|
||||
{
|
||||
case 0x01: /* SCOTTISH */ return "gd_GB";
|
||||
case 0x02: /* IRISH */ return "ga_IE";
|
||||
}
|
||||
return "C";
|
||||
case LANG_GALICIAN: return "gl_ES";
|
||||
case LANG_GEORGIAN: return "ka_GE";
|
||||
case LANG_GERMAN:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_GERMAN: return "de_DE";
|
||||
case SUBLANG_GERMAN_SWISS: return "de_CH";
|
||||
case SUBLANG_GERMAN_AUSTRIAN: return "de_AT";
|
||||
case SUBLANG_GERMAN_LUXEMBOURG: return "de_LU";
|
||||
case SUBLANG_GERMAN_LIECHTENSTEIN: return "de_LI";
|
||||
}
|
||||
return "de";
|
||||
case LANG_GREEK: return "el_GR";
|
||||
case 0x74: /* GUARANI */ return "gn_PY";
|
||||
case LANG_GUJARATI: return "gu_IN";
|
||||
case 0x68: /* HAUSA */ return "ha_NG";
|
||||
case 0x75: /* HAWAIIAN */
|
||||
/* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers)
|
||||
or Hawaii Creole English ("cpe_US", 600000 speakers)? */
|
||||
return "cpe_US";
|
||||
case LANG_HEBREW: return "he_IL";
|
||||
case LANG_HINDI: return "hi_IN";
|
||||
case LANG_HUNGARIAN: return "hu_HU";
|
||||
case 0x69: /* IBIBIO */ return "nic_NG";
|
||||
case LANG_ICELANDIC: return "is_IS";
|
||||
case 0x70: /* IGBO */ return "ibo_NG";
|
||||
case LANG_INDONESIAN: return "id_ID";
|
||||
case 0x5d: /* INUKTITUT */ return "iu_CA";
|
||||
case LANG_ITALIAN:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_ITALIAN: return "it_IT";
|
||||
case SUBLANG_ITALIAN_SWISS: return "it_CH";
|
||||
}
|
||||
return "it";
|
||||
case LANG_JAPANESE: return "ja_JP";
|
||||
case LANG_KANNADA: return "kn_IN";
|
||||
case 0x71: /* KANURI */ return "kau_NG";
|
||||
case LANG_KASHMIRI:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_DEFAULT: return "ks_PK";
|
||||
case SUBLANG_KASHMIRI_INDIA: return "ks_IN";
|
||||
}
|
||||
return "ks";
|
||||
case LANG_KAZAK: return "kk_KZ";
|
||||
case LANG_KONKANI:
|
||||
/* FIXME: Adjust this when such locales appear on Unix. */
|
||||
return "kok_IN";
|
||||
case LANG_KOREAN: return "ko_KR";
|
||||
case LANG_KYRGYZ: return "ky_KG";
|
||||
case 0x54: /* LAO */ return "lo_LA";
|
||||
case 0x76: /* LATIN */ return "la_VA";
|
||||
case LANG_LATVIAN: return "lv_LV";
|
||||
case LANG_LITHUANIAN: return "lt_LT";
|
||||
case LANG_MACEDONIAN: return "mk_MK";
|
||||
case LANG_MALAY:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_MALAY_MALAYSIA: return "ms_MY";
|
||||
case SUBLANG_MALAY_BRUNEI_DARUSSALAM: return "ms_BN";
|
||||
}
|
||||
return "ms";
|
||||
case LANG_MALAYALAM: return "ml_IN";
|
||||
case 0x3a: /* MALTESE */ return "mt_MT";
|
||||
case LANG_MANIPURI:
|
||||
/* FIXME: Adjust this when such locales appear on Unix. */
|
||||
return "mni_IN";
|
||||
case LANG_MARATHI: return "mr_IN";
|
||||
case LANG_MONGOLIAN:
|
||||
return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN". */
|
||||
case LANG_NEPALI:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_DEFAULT: return "ne_NP";
|
||||
case SUBLANG_NEPALI_INDIA: return "ne_IN";
|
||||
}
|
||||
return "ne";
|
||||
case LANG_NORWEGIAN:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_NORWEGIAN_BOKMAL: return "no_NO";
|
||||
case SUBLANG_NORWEGIAN_NYNORSK: return "nn_NO";
|
||||
}
|
||||
return "no";
|
||||
case LANG_ORIYA: return "or_IN";
|
||||
case 0x72: /* OROMO */ return "om_ET";
|
||||
case 0x79: /* PAPIAMENTU */ return "pap_AN";
|
||||
case 0x63: /* PASHTO */
|
||||
return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF". */
|
||||
case LANG_POLISH: return "pl_PL";
|
||||
case LANG_PORTUGUESE:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_PORTUGUESE: return "pt_PT";
|
||||
/* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT.
|
||||
Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */
|
||||
case SUBLANG_PORTUGUESE_BRAZILIAN: return "pt_BR";
|
||||
}
|
||||
return "pt";
|
||||
case LANG_PUNJABI: return "pa_IN";
|
||||
case 0x17: /* RHAETO-ROMANCE */ return "rm_CH";
|
||||
case LANG_ROMANIAN: return "ro_RO";
|
||||
case LANG_RUSSIAN:
|
||||
return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA". */
|
||||
case 0x3b: /* SAMI */ return "se_NO";
|
||||
case LANG_SANSKRIT: return "sa_IN";
|
||||
case LANG_SINDHI: return "sd";
|
||||
case 0x5b: /* SINHALESE */ return "si_LK";
|
||||
case LANG_SLOVAK: return "sk_SK";
|
||||
case LANG_SLOVENIAN: return "sl_SI";
|
||||
case 0x77: /* SOMALI */ return "so_SO";
|
||||
case LANG_SORBIAN:
|
||||
/* FIXME: Adjust this when such locales appear on Unix. */
|
||||
return "wen_DE";
|
||||
case LANG_SPANISH:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_SPANISH: return "es_ES";
|
||||
case SUBLANG_SPANISH_MEXICAN: return "es_MX";
|
||||
case SUBLANG_SPANISH_MODERN:
|
||||
return "es_ES@modern"; /* not seen on Unix */
|
||||
case SUBLANG_SPANISH_GUATEMALA: return "es_GT";
|
||||
case SUBLANG_SPANISH_COSTA_RICA: return "es_CR";
|
||||
case SUBLANG_SPANISH_PANAMA: return "es_PA";
|
||||
case SUBLANG_SPANISH_DOMINICAN_REPUBLIC: return "es_DO";
|
||||
case SUBLANG_SPANISH_VENEZUELA: return "es_VE";
|
||||
case SUBLANG_SPANISH_COLOMBIA: return "es_CO";
|
||||
case SUBLANG_SPANISH_PERU: return "es_PE";
|
||||
case SUBLANG_SPANISH_ARGENTINA: return "es_AR";
|
||||
case SUBLANG_SPANISH_ECUADOR: return "es_EC";
|
||||
case SUBLANG_SPANISH_CHILE: return "es_CL";
|
||||
case SUBLANG_SPANISH_URUGUAY: return "es_UY";
|
||||
case SUBLANG_SPANISH_PARAGUAY: return "es_PY";
|
||||
case SUBLANG_SPANISH_BOLIVIA: return "es_BO";
|
||||
case SUBLANG_SPANISH_EL_SALVADOR: return "es_SV";
|
||||
case SUBLANG_SPANISH_HONDURAS: return "es_HN";
|
||||
case SUBLANG_SPANISH_NICARAGUA: return "es_NI";
|
||||
case SUBLANG_SPANISH_PUERTO_RICO: return "es_PR";
|
||||
}
|
||||
return "es";
|
||||
case 0x30: /* SUTU */ return "bnt_TZ";
|
||||
case LANG_SWAHILI: return "sw_KE";
|
||||
case LANG_SWEDISH:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_DEFAULT: return "sv_SE";
|
||||
case SUBLANG_SWEDISH_FINLAND: return "sv_FI";
|
||||
}
|
||||
return "sv";
|
||||
case LANG_SYRIAC: return "syr_TR"; /* An extinct language. */
|
||||
case 0x64: /* TAGALOG */ return "tl_PH";
|
||||
case 0x28: /* TAJIK */ return "tg_TJ";
|
||||
case 0x5f: /* TAMAZIGHT */ return "ber_MA";
|
||||
case LANG_TAMIL:
|
||||
return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG". */
|
||||
case LANG_TATAR: return "tt_RU";
|
||||
case LANG_TELUGU: return "te_IN";
|
||||
case LANG_THAI: return "th_TH";
|
||||
case 0x51: /* TIBETAN */ return "bo_CN";
|
||||
case 0x73: /* TIGRINYA */ return "ti_ET";
|
||||
case 0x31: /* TSONGA */ return "ts_ZA";
|
||||
case LANG_TURKISH: return "tr_TR";
|
||||
case 0x42: /* TURKMEN */ return "tk_TM";
|
||||
case LANG_UKRAINIAN: return "uk_UA";
|
||||
case LANG_URDU:
|
||||
switch (sub)
|
||||
{
|
||||
case SUBLANG_URDU_PAKISTAN: return "ur_PK";
|
||||
case SUBLANG_URDU_INDIA: return "ur_IN";
|
||||
}
|
||||
return "ur";
|
||||
case LANG_UZBEK:
|
||||
switch (sub)
|
||||
{
|
||||
/* FIXME: Adjust this when Uzbek locales appear on Unix. */
|
||||
case SUBLANG_UZBEK_LATIN: return "uz_UZ@latin";
|
||||
case SUBLANG_UZBEK_CYRILLIC: return "uz_UZ@cyrillic";
|
||||
}
|
||||
return "uz";
|
||||
case 0x33: /* VENDA */ return "ven_ZA";
|
||||
case LANG_VIETNAMESE: return "vi_VN";
|
||||
case 0x52: /* WELSH */ return "cy_GB";
|
||||
case 0x34: /* XHOSA */ return "xh_ZA";
|
||||
case 0x78: /* YI */ return "sit_CN";
|
||||
case 0x3d: /* YIDDISH */ return "yi_IL";
|
||||
case 0x6a: /* YORUBA */ return "yo_NG";
|
||||
case 0x35: /* ZULU */ return "zu_ZA";
|
||||
default: return "C";
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
104
lib/intl/log.c
Normal file
104
lib/intl/log.c
Normal file
|
@ -0,0 +1,104 @@
|
|||
/* Log file output.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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 <bruno@clisp.org>. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Print an ASCII string with quotes and escape sequences where needed. */
|
||||
static void
|
||||
print_escaped (stream, str)
|
||||
FILE *stream;
|
||||
const char *str;
|
||||
{
|
||||
putc ('"', stream);
|
||||
for (; *str != '\0'; str++)
|
||||
if (*str == '\n')
|
||||
{
|
||||
fputs ("\\n\"", stream);
|
||||
if (str[1] == '\0')
|
||||
return;
|
||||
fputs ("\n\"", stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*str == '"' || *str == '\\')
|
||||
putc ('\\', stream);
|
||||
putc (*str, stream);
|
||||
}
|
||||
putc ('"', stream);
|
||||
}
|
||||
|
||||
/* Add to the log file an entry denoting a failed translation. */
|
||||
void
|
||||
_nl_log_untranslated (logfilename, domainname, msgid1, msgid2, plural)
|
||||
const char *logfilename;
|
||||
const char *domainname;
|
||||
const char *msgid1;
|
||||
const char *msgid2;
|
||||
int plural;
|
||||
{
|
||||
static char *last_logfilename = NULL;
|
||||
static FILE *last_logfile = NULL;
|
||||
FILE *logfile;
|
||||
|
||||
/* Can we reuse the last opened logfile? */
|
||||
if (last_logfilename == NULL || strcmp (logfilename, last_logfilename) != 0)
|
||||
{
|
||||
/* Close the last used logfile. */
|
||||
if (last_logfilename != NULL)
|
||||
{
|
||||
if (last_logfile != NULL)
|
||||
{
|
||||
fclose (last_logfile);
|
||||
last_logfile = NULL;
|
||||
}
|
||||
free (last_logfilename);
|
||||
last_logfilename = NULL;
|
||||
}
|
||||
/* Open the logfile. */
|
||||
last_logfilename = (char *) malloc (strlen (logfilename) + 1);
|
||||
if (last_logfilename == NULL)
|
||||
return;
|
||||
strcpy (last_logfilename, logfilename);
|
||||
last_logfile = fopen (logfilename, "a");
|
||||
if (last_logfile == NULL)
|
||||
return;
|
||||
}
|
||||
logfile = last_logfile;
|
||||
|
||||
fprintf (logfile, "domain ");
|
||||
print_escaped (logfile, domainname);
|
||||
fprintf (logfile, "\nmsgid ");
|
||||
print_escaped (logfile, msgid1);
|
||||
if (plural)
|
||||
{
|
||||
fprintf (logfile, "\nmsgid_plural ");
|
||||
print_escaped (logfile, msgid2);
|
||||
fprintf (logfile, "\nmsgstr[0] \"\"\n");
|
||||
}
|
||||
else
|
||||
fprintf (logfile, "\nmsgstr \"\"\n");
|
||||
putc ('\n', logfile);
|
||||
}
|
68
lib/intl/ngettext.c
Normal file
68
lib/intl/ngettext.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
/* Implementation of ngettext(3) function.
|
||||
Copyright (C) 1995, 1997, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef _LIBC
|
||||
# define __need_NULL
|
||||
# include <stddef.h>
|
||||
#else
|
||||
# include <stdlib.h> /* Just for NULL. */
|
||||
#endif
|
||||
|
||||
#include "gettextP.h"
|
||||
#ifdef _LIBC
|
||||
# include <libintl.h>
|
||||
#else
|
||||
# include "libgnuintl.h"
|
||||
#endif
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
/* @@ end of prolog @@ */
|
||||
|
||||
/* Names for the libintl functions are a problem. They must not clash
|
||||
with existing names and they should follow ANSI C. But this source
|
||||
code is also used in GNU C Library where the names have a __
|
||||
prefix. So we have to make a difference here. */
|
||||
#ifdef _LIBC
|
||||
# define NGETTEXT __ngettext
|
||||
# define DCNGETTEXT __dcngettext
|
||||
#else
|
||||
# define NGETTEXT libintl_ngettext
|
||||
# define DCNGETTEXT libintl_dcngettext
|
||||
#endif
|
||||
|
||||
/* Look up MSGID in the current default message catalog for the current
|
||||
LC_MESSAGES locale. If not found, returns MSGID itself (the default
|
||||
text). */
|
||||
char *
|
||||
NGETTEXT (msgid1, msgid2, n)
|
||||
const char *msgid1;
|
||||
const char *msgid2;
|
||||
unsigned long int n;
|
||||
{
|
||||
return DCNGETTEXT (NULL, msgid1, msgid2, n, LC_MESSAGES);
|
||||
}
|
||||
|
||||
#ifdef _LIBC
|
||||
/* Alias for function name in GNU C Library. */
|
||||
weak_alias (__ngettext, ngettext);
|
||||
#endif
|
98
lib/intl/os2compat.c
Normal file
98
lib/intl/os2compat.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
/* OS/2 compatibility functions.
|
||||
Copyright (C) 2001-2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#define OS2_AWARE
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
/* A version of getenv() that works from DLLs */
|
||||
extern unsigned long DosScanEnv (const unsigned char *pszName, unsigned char **ppszValue);
|
||||
|
||||
char *
|
||||
_nl_getenv (const char *name)
|
||||
{
|
||||
unsigned char *value;
|
||||
if (DosScanEnv (name, &value))
|
||||
return NULL;
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
/* A fixed size buffer. */
|
||||
char libintl_nl_default_dirname[MAXPATHLEN+1];
|
||||
|
||||
char *_nlos2_libdir = NULL;
|
||||
char *_nlos2_localealiaspath = NULL;
|
||||
char *_nlos2_localedir = NULL;
|
||||
|
||||
static __attribute__((constructor)) void
|
||||
nlos2_initialize ()
|
||||
{
|
||||
char *root = getenv ("UNIXROOT");
|
||||
char *gnulocaledir = getenv ("GNULOCALEDIR");
|
||||
|
||||
_nlos2_libdir = gnulocaledir;
|
||||
if (!_nlos2_libdir)
|
||||
{
|
||||
if (root)
|
||||
{
|
||||
size_t sl = strlen (root);
|
||||
_nlos2_libdir = (char *) malloc (sl + strlen (LIBDIR) + 1);
|
||||
memcpy (_nlos2_libdir, root, sl);
|
||||
memcpy (_nlos2_libdir + sl, LIBDIR, strlen (LIBDIR) + 1);
|
||||
}
|
||||
else
|
||||
_nlos2_libdir = LIBDIR;
|
||||
}
|
||||
|
||||
_nlos2_localealiaspath = gnulocaledir;
|
||||
if (!_nlos2_localealiaspath)
|
||||
{
|
||||
if (root)
|
||||
{
|
||||
size_t sl = strlen (root);
|
||||
_nlos2_localealiaspath = (char *) malloc (sl + strlen (LOCALE_ALIAS_PATH) + 1);
|
||||
memcpy (_nlos2_localealiaspath, root, sl);
|
||||
memcpy (_nlos2_localealiaspath + sl, LOCALE_ALIAS_PATH, strlen (LOCALE_ALIAS_PATH) + 1);
|
||||
}
|
||||
else
|
||||
_nlos2_localealiaspath = LOCALE_ALIAS_PATH;
|
||||
}
|
||||
|
||||
_nlos2_localedir = gnulocaledir;
|
||||
if (!_nlos2_localedir)
|
||||
{
|
||||
if (root)
|
||||
{
|
||||
size_t sl = strlen (root);
|
||||
_nlos2_localedir = (char *) malloc (sl + strlen (LOCALEDIR) + 1);
|
||||
memcpy (_nlos2_localedir, root, sl);
|
||||
memcpy (_nlos2_localedir + sl, LOCALEDIR, strlen (LOCALEDIR) + 1);
|
||||
}
|
||||
else
|
||||
_nlos2_localedir = LOCALEDIR;
|
||||
}
|
||||
|
||||
if (strlen (_nlos2_localedir) <= MAXPATHLEN)
|
||||
strcpy (libintl_nl_default_dirname, _nlos2_localedir);
|
||||
}
|
46
lib/intl/os2compat.h
Normal file
46
lib/intl/os2compat.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/* OS/2 compatibility defines.
|
||||
This file is intended to be included from config.h
|
||||
Copyright (C) 2001-2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
/* When included from os2compat.h we need all the original definitions */
|
||||
#ifndef OS2_AWARE
|
||||
|
||||
#undef LIBDIR
|
||||
#define LIBDIR _nlos2_libdir
|
||||
extern char *_nlos2_libdir;
|
||||
|
||||
#undef LOCALEDIR
|
||||
#define LOCALEDIR _nlos2_localedir
|
||||
extern char *_nlos2_localedir;
|
||||
|
||||
#undef LOCALE_ALIAS_PATH
|
||||
#define LOCALE_ALIAS_PATH _nlos2_localealiaspath
|
||||
extern char *_nlos2_localealiaspath;
|
||||
|
||||
#endif
|
||||
|
||||
#undef HAVE_STRCASECMP
|
||||
#define HAVE_STRCASECMP 1
|
||||
#define strcasecmp stricmp
|
||||
#define strncasecmp strnicmp
|
||||
|
||||
/* We have our own getenv() which works even if library is compiled as DLL */
|
||||
#define getenv _nl_getenv
|
||||
|
||||
/* Older versions of gettext used -1 as the value of LC_MESSAGES */
|
||||
#define LC_MESSAGES_COMPAT (-1)
|
24
lib/intl/osdep.c
Normal file
24
lib/intl/osdep.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/* OS dependent parts of libintl.
|
||||
Copyright (C) 2001-2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#if defined __EMX__
|
||||
# include "os2compat.c"
|
||||
#else
|
||||
/* Avoid AIX compiler warning. */
|
||||
typedef int dummy;
|
||||
#endif
|
156
lib/intl/plural-exp.c
Normal file
156
lib/intl/plural-exp.c
Normal file
|
@ -0,0 +1,156 @@
|
|||
/* Expression parsing for plural form selection.
|
||||
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
|
||||
Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "plural-exp.h"
|
||||
|
||||
#if (defined __GNUC__ && !defined __APPLE_CC__) \
|
||||
|| (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
|
||||
|
||||
/* These structs are the constant expression for the germanic plural
|
||||
form determination. It represents the expression "n != 1". */
|
||||
static const struct expression plvar =
|
||||
{
|
||||
.nargs = 0,
|
||||
.operation = var,
|
||||
};
|
||||
static const struct expression plone =
|
||||
{
|
||||
.nargs = 0,
|
||||
.operation = num,
|
||||
.val =
|
||||
{
|
||||
.num = 1
|
||||
}
|
||||
};
|
||||
struct expression GERMANIC_PLURAL =
|
||||
{
|
||||
.nargs = 2,
|
||||
.operation = not_equal,
|
||||
.val =
|
||||
{
|
||||
.args =
|
||||
{
|
||||
[0] = (struct expression *) &plvar,
|
||||
[1] = (struct expression *) &plone
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
# define INIT_GERMANIC_PLURAL()
|
||||
|
||||
#else
|
||||
|
||||
/* For compilers without support for ISO C 99 struct/union initializers:
|
||||
Initialization at run-time. */
|
||||
|
||||
static struct expression plvar;
|
||||
static struct expression plone;
|
||||
struct expression GERMANIC_PLURAL;
|
||||
|
||||
static void
|
||||
init_germanic_plural ()
|
||||
{
|
||||
if (plone.val.num == 0)
|
||||
{
|
||||
plvar.nargs = 0;
|
||||
plvar.operation = var;
|
||||
|
||||
plone.nargs = 0;
|
||||
plone.operation = num;
|
||||
plone.val.num = 1;
|
||||
|
||||
GERMANIC_PLURAL.nargs = 2;
|
||||
GERMANIC_PLURAL.operation = not_equal;
|
||||
GERMANIC_PLURAL.val.args[0] = &plvar;
|
||||
GERMANIC_PLURAL.val.args[1] = &plone;
|
||||
}
|
||||
}
|
||||
|
||||
# define INIT_GERMANIC_PLURAL() init_germanic_plural ()
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
internal_function
|
||||
EXTRACT_PLURAL_EXPRESSION (nullentry, pluralp, npluralsp)
|
||||
const char *nullentry;
|
||||
struct expression **pluralp;
|
||||
unsigned long int *npluralsp;
|
||||
{
|
||||
if (nullentry != NULL)
|
||||
{
|
||||
const char *plural;
|
||||
const char *nplurals;
|
||||
|
||||
plural = strstr (nullentry, "plural=");
|
||||
nplurals = strstr (nullentry, "nplurals=");
|
||||
if (plural == NULL || nplurals == NULL)
|
||||
goto no_plural;
|
||||
else
|
||||
{
|
||||
char *endp;
|
||||
unsigned long int n;
|
||||
struct parse_args args;
|
||||
|
||||
/* First get the number. */
|
||||
nplurals += 9;
|
||||
while (*nplurals != '\0' && isspace ((unsigned char) *nplurals))
|
||||
++nplurals;
|
||||
if (!(*nplurals >= '0' && *nplurals <= '9'))
|
||||
goto no_plural;
|
||||
#if defined HAVE_STRTOUL || defined _LIBC
|
||||
n = strtoul (nplurals, &endp, 10);
|
||||
#else
|
||||
for (endp = nplurals, n = 0; *endp >= '0' && *endp <= '9'; endp++)
|
||||
n = n * 10 + (*endp - '0');
|
||||
#endif
|
||||
if (nplurals == endp)
|
||||
goto no_plural;
|
||||
*npluralsp = n;
|
||||
|
||||
/* Due to the restrictions bison imposes onto the interface of the
|
||||
scanner function we have to put the input string and the result
|
||||
passed up from the parser into the same structure which address
|
||||
is passed down to the parser. */
|
||||
plural += 7;
|
||||
args.cp = plural;
|
||||
if (PLURAL_PARSE (&args) != 0)
|
||||
goto no_plural;
|
||||
*pluralp = args.res;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* By default we are using the Germanic form: singular form only
|
||||
for `one', the plural form otherwise. Yes, this is also what
|
||||
English is using since English is a Germanic language. */
|
||||
no_plural:
|
||||
INIT_GERMANIC_PLURAL ();
|
||||
*pluralp = &GERMANIC_PLURAL;
|
||||
*npluralsp = 2;
|
||||
}
|
||||
}
|
126
lib/intl/plural-exp.h
Normal file
126
lib/intl/plural-exp.h
Normal file
|
@ -0,0 +1,126 @@
|
|||
/* Expression parsing and evaluation for plural form selection.
|
||||
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifndef _PLURAL_EXP_H
|
||||
#define _PLURAL_EXP_H
|
||||
|
||||
#ifndef PARAMS
|
||||
# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES
|
||||
# define PARAMS(args) args
|
||||
# else
|
||||
# define PARAMS(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef internal_function
|
||||
# define internal_function
|
||||
#endif
|
||||
|
||||
#ifndef attribute_hidden
|
||||
# define attribute_hidden
|
||||
#endif
|
||||
|
||||
|
||||
/* This is the representation of the expressions to determine the
|
||||
plural form. */
|
||||
struct expression
|
||||
{
|
||||
int nargs; /* Number of arguments. */
|
||||
enum operator
|
||||
{
|
||||
/* Without arguments: */
|
||||
var, /* The variable "n". */
|
||||
num, /* Decimal number. */
|
||||
/* Unary operators: */
|
||||
lnot, /* Logical NOT. */
|
||||
/* Binary operators: */
|
||||
mult, /* Multiplication. */
|
||||
divide, /* Division. */
|
||||
module, /* Modulo operation. */
|
||||
plus, /* Addition. */
|
||||
minus, /* Subtraction. */
|
||||
less_than, /* Comparison. */
|
||||
greater_than, /* Comparison. */
|
||||
less_or_equal, /* Comparison. */
|
||||
greater_or_equal, /* Comparison. */
|
||||
equal, /* Comparison for equality. */
|
||||
not_equal, /* Comparison for inequality. */
|
||||
land, /* Logical AND. */
|
||||
lor, /* Logical OR. */
|
||||
/* Ternary operators: */
|
||||
qmop /* Question mark operator. */
|
||||
} operation;
|
||||
union
|
||||
{
|
||||
unsigned long int num; /* Number value for `num'. */
|
||||
struct expression *args[3]; /* Up to three arguments. */
|
||||
} val;
|
||||
};
|
||||
|
||||
/* This is the data structure to pass information to the parser and get
|
||||
the result in a thread-safe way. */
|
||||
struct parse_args
|
||||
{
|
||||
const char *cp;
|
||||
struct expression *res;
|
||||
};
|
||||
|
||||
|
||||
/* Names for the libintl functions are a problem. This source code is used
|
||||
1. in the GNU C Library library,
|
||||
2. in the GNU libintl library,
|
||||
3. in the GNU gettext tools.
|
||||
The function names in each situation must be different, to allow for
|
||||
binary incompatible changes in 'struct expression'. Furthermore,
|
||||
1. in the GNU C Library library, the names have a __ prefix,
|
||||
2.+3. in the GNU libintl library and in the GNU gettext tools, the names
|
||||
must follow ANSI C and not start with __.
|
||||
So we have to distinguish the three cases. */
|
||||
#ifdef _LIBC
|
||||
# define FREE_EXPRESSION __gettext_free_exp
|
||||
# define PLURAL_PARSE __gettextparse
|
||||
# define GERMANIC_PLURAL __gettext_germanic_plural
|
||||
# define EXTRACT_PLURAL_EXPRESSION __gettext_extract_plural
|
||||
#elif defined (IN_LIBINTL)
|
||||
# define FREE_EXPRESSION libintl_gettext_free_exp
|
||||
# define PLURAL_PARSE libintl_gettextparse
|
||||
# define GERMANIC_PLURAL libintl_gettext_germanic_plural
|
||||
# define EXTRACT_PLURAL_EXPRESSION libintl_gettext_extract_plural
|
||||
#else
|
||||
# define FREE_EXPRESSION free_plural_expression
|
||||
# define PLURAL_PARSE parse_plural_expression
|
||||
# define GERMANIC_PLURAL germanic_plural
|
||||
# define EXTRACT_PLURAL_EXPRESSION extract_plural_expression
|
||||
#endif
|
||||
|
||||
extern void FREE_EXPRESSION PARAMS ((struct expression *exp))
|
||||
internal_function;
|
||||
extern int PLURAL_PARSE PARAMS ((void *arg));
|
||||
extern struct expression GERMANIC_PLURAL attribute_hidden;
|
||||
extern void EXTRACT_PLURAL_EXPRESSION PARAMS ((const char *nullentry,
|
||||
struct expression **pluralp,
|
||||
unsigned long int *npluralsp))
|
||||
internal_function;
|
||||
|
||||
#if !defined (_LIBC) && !defined (IN_LIBINTL)
|
||||
extern unsigned long int plural_eval PARAMS ((struct expression *pexp,
|
||||
unsigned long int n));
|
||||
#endif
|
||||
|
||||
#endif /* _PLURAL_EXP_H */
|
1518
lib/intl/plural.c
Normal file
1518
lib/intl/plural.c
Normal file
File diff suppressed because it is too large
Load diff
409
lib/intl/plural.y
Normal file
409
lib/intl/plural.y
Normal file
|
@ -0,0 +1,409 @@
|
|||
%{
|
||||
/* Expression parsing for plural form selection.
|
||||
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
|
||||
Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
/* The bison generated parser uses alloca. AIX 3 forces us to put this
|
||||
declaration at the beginning of the file. The declaration in bison's
|
||||
skeleton file comes too late. This must come before <config.h>
|
||||
because <config.h> may include arbitrary system headers. */
|
||||
#if defined _AIX && !defined __GNUC__
|
||||
#pragma alloca
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include "plural-exp.h"
|
||||
|
||||
/* The main function generated by the parser is called __gettextparse,
|
||||
but we want it to be called PLURAL_PARSE. */
|
||||
#ifndef _LIBC
|
||||
# define __gettextparse PLURAL_PARSE
|
||||
#endif
|
||||
|
||||
#define YYLEX_PARAM &((struct parse_args *) arg)->cp
|
||||
#define YYPARSE_PARAM arg
|
||||
%}
|
||||
%pure_parser
|
||||
%expect 7
|
||||
|
||||
%union {
|
||||
unsigned long int num;
|
||||
enum operator op;
|
||||
struct expression *exp;
|
||||
}
|
||||
|
||||
%{
|
||||
/* Prototypes for local functions. */
|
||||
static struct expression *new_exp PARAMS ((int nargs, enum operator op,
|
||||
struct expression * const *args));
|
||||
static inline struct expression *new_exp_0 PARAMS ((enum operator op));
|
||||
static inline struct expression *new_exp_1 PARAMS ((enum operator op,
|
||||
struct expression *right));
|
||||
static struct expression *new_exp_2 PARAMS ((enum operator op,
|
||||
struct expression *left,
|
||||
struct expression *right));
|
||||
static inline struct expression *new_exp_3 PARAMS ((enum operator op,
|
||||
struct expression *bexp,
|
||||
struct expression *tbranch,
|
||||
struct expression *fbranch));
|
||||
static int yylex PARAMS ((YYSTYPE *lval, const char **pexp));
|
||||
static void yyerror PARAMS ((const char *str));
|
||||
|
||||
/* Allocation of expressions. */
|
||||
|
||||
static struct expression *
|
||||
new_exp (nargs, op, args)
|
||||
int nargs;
|
||||
enum operator op;
|
||||
struct expression * const *args;
|
||||
{
|
||||
int i;
|
||||
struct expression *newp;
|
||||
|
||||
/* If any of the argument could not be malloc'ed, just return NULL. */
|
||||
for (i = nargs - 1; i >= 0; i--)
|
||||
if (args[i] == NULL)
|
||||
goto fail;
|
||||
|
||||
/* Allocate a new expression. */
|
||||
newp = (struct expression *) malloc (sizeof (*newp));
|
||||
if (newp != NULL)
|
||||
{
|
||||
newp->nargs = nargs;
|
||||
newp->operation = op;
|
||||
for (i = nargs - 1; i >= 0; i--)
|
||||
newp->val.args[i] = args[i];
|
||||
return newp;
|
||||
}
|
||||
|
||||
fail:
|
||||
for (i = nargs - 1; i >= 0; i--)
|
||||
FREE_EXPRESSION (args[i]);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline struct expression *
|
||||
new_exp_0 (op)
|
||||
enum operator op;
|
||||
{
|
||||
return new_exp (0, op, NULL);
|
||||
}
|
||||
|
||||
static inline struct expression *
|
||||
new_exp_1 (op, right)
|
||||
enum operator op;
|
||||
struct expression *right;
|
||||
{
|
||||
struct expression *args[1];
|
||||
|
||||
args[0] = right;
|
||||
return new_exp (1, op, args);
|
||||
}
|
||||
|
||||
static struct expression *
|
||||
new_exp_2 (op, left, right)
|
||||
enum operator op;
|
||||
struct expression *left;
|
||||
struct expression *right;
|
||||
{
|
||||
struct expression *args[2];
|
||||
|
||||
args[0] = left;
|
||||
args[1] = right;
|
||||
return new_exp (2, op, args);
|
||||
}
|
||||
|
||||
static inline struct expression *
|
||||
new_exp_3 (op, bexp, tbranch, fbranch)
|
||||
enum operator op;
|
||||
struct expression *bexp;
|
||||
struct expression *tbranch;
|
||||
struct expression *fbranch;
|
||||
{
|
||||
struct expression *args[3];
|
||||
|
||||
args[0] = bexp;
|
||||
args[1] = tbranch;
|
||||
args[2] = fbranch;
|
||||
return new_exp (3, op, args);
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
/* This declares that all operators have the same associativity and the
|
||||
precedence order as in C. See [Harbison, Steele: C, A Reference Manual].
|
||||
There is no unary minus and no bitwise operators.
|
||||
Operators with the same syntactic behaviour have been merged into a single
|
||||
token, to save space in the array generated by bison. */
|
||||
%right '?' /* ? */
|
||||
%left '|' /* || */
|
||||
%left '&' /* && */
|
||||
%left EQUOP2 /* == != */
|
||||
%left CMPOP2 /* < > <= >= */
|
||||
%left ADDOP2 /* + - */
|
||||
%left MULOP2 /* * / % */
|
||||
%right '!' /* ! */
|
||||
|
||||
%token <op> EQUOP2 CMPOP2 ADDOP2 MULOP2
|
||||
%token <num> NUMBER
|
||||
%type <exp> exp
|
||||
|
||||
%%
|
||||
|
||||
start: exp
|
||||
{
|
||||
if ($1 == NULL)
|
||||
YYABORT;
|
||||
((struct parse_args *) arg)->res = $1;
|
||||
}
|
||||
;
|
||||
|
||||
exp: exp '?' exp ':' exp
|
||||
{
|
||||
$$ = new_exp_3 (qmop, $1, $3, $5);
|
||||
}
|
||||
| exp '|' exp
|
||||
{
|
||||
$$ = new_exp_2 (lor, $1, $3);
|
||||
}
|
||||
| exp '&' exp
|
||||
{
|
||||
$$ = new_exp_2 (land, $1, $3);
|
||||
}
|
||||
| exp EQUOP2 exp
|
||||
{
|
||||
$$ = new_exp_2 ($2, $1, $3);
|
||||
}
|
||||
| exp CMPOP2 exp
|
||||
{
|
||||
$$ = new_exp_2 ($2, $1, $3);
|
||||
}
|
||||
| exp ADDOP2 exp
|
||||
{
|
||||
$$ = new_exp_2 ($2, $1, $3);
|
||||
}
|
||||
| exp MULOP2 exp
|
||||
{
|
||||
$$ = new_exp_2 ($2, $1, $3);
|
||||
}
|
||||
| '!' exp
|
||||
{
|
||||
$$ = new_exp_1 (lnot, $2);
|
||||
}
|
||||
| 'n'
|
||||
{
|
||||
$$ = new_exp_0 (var);
|
||||
}
|
||||
| NUMBER
|
||||
{
|
||||
if (($$ = new_exp_0 (num)) != NULL)
|
||||
$$->val.num = $1;
|
||||
}
|
||||
| '(' exp ')'
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
void
|
||||
internal_function
|
||||
FREE_EXPRESSION (exp)
|
||||
struct expression *exp;
|
||||
{
|
||||
if (exp == NULL)
|
||||
return;
|
||||
|
||||
/* Handle the recursive case. */
|
||||
switch (exp->nargs)
|
||||
{
|
||||
case 3:
|
||||
FREE_EXPRESSION (exp->val.args[2]);
|
||||
/* FALLTHROUGH */
|
||||
case 2:
|
||||
FREE_EXPRESSION (exp->val.args[1]);
|
||||
/* FALLTHROUGH */
|
||||
case 1:
|
||||
FREE_EXPRESSION (exp->val.args[0]);
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
free (exp);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
yylex (lval, pexp)
|
||||
YYSTYPE *lval;
|
||||
const char **pexp;
|
||||
{
|
||||
const char *exp = *pexp;
|
||||
int result;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (exp[0] == '\0')
|
||||
{
|
||||
*pexp = exp;
|
||||
return YYEOF;
|
||||
}
|
||||
|
||||
if (exp[0] != ' ' && exp[0] != '\t')
|
||||
break;
|
||||
|
||||
++exp;
|
||||
}
|
||||
|
||||
result = *exp++;
|
||||
switch (result)
|
||||
{
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
{
|
||||
unsigned long int n = result - '0';
|
||||
while (exp[0] >= '0' && exp[0] <= '9')
|
||||
{
|
||||
n *= 10;
|
||||
n += exp[0] - '0';
|
||||
++exp;
|
||||
}
|
||||
lval->num = n;
|
||||
result = NUMBER;
|
||||
}
|
||||
break;
|
||||
|
||||
case '=':
|
||||
if (exp[0] == '=')
|
||||
{
|
||||
++exp;
|
||||
lval->op = equal;
|
||||
result = EQUOP2;
|
||||
}
|
||||
else
|
||||
result = YYERRCODE;
|
||||
break;
|
||||
|
||||
case '!':
|
||||
if (exp[0] == '=')
|
||||
{
|
||||
++exp;
|
||||
lval->op = not_equal;
|
||||
result = EQUOP2;
|
||||
}
|
||||
break;
|
||||
|
||||
case '&':
|
||||
case '|':
|
||||
if (exp[0] == result)
|
||||
++exp;
|
||||
else
|
||||
result = YYERRCODE;
|
||||
break;
|
||||
|
||||
case '<':
|
||||
if (exp[0] == '=')
|
||||
{
|
||||
++exp;
|
||||
lval->op = less_or_equal;
|
||||
}
|
||||
else
|
||||
lval->op = less_than;
|
||||
result = CMPOP2;
|
||||
break;
|
||||
|
||||
case '>':
|
||||
if (exp[0] == '=')
|
||||
{
|
||||
++exp;
|
||||
lval->op = greater_or_equal;
|
||||
}
|
||||
else
|
||||
lval->op = greater_than;
|
||||
result = CMPOP2;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
lval->op = mult;
|
||||
result = MULOP2;
|
||||
break;
|
||||
|
||||
case '/':
|
||||
lval->op = divide;
|
||||
result = MULOP2;
|
||||
break;
|
||||
|
||||
case '%':
|
||||
lval->op = module;
|
||||
result = MULOP2;
|
||||
break;
|
||||
|
||||
case '+':
|
||||
lval->op = plus;
|
||||
result = ADDOP2;
|
||||
break;
|
||||
|
||||
case '-':
|
||||
lval->op = minus;
|
||||
result = ADDOP2;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
case '?':
|
||||
case ':':
|
||||
case '(':
|
||||
case ')':
|
||||
/* Nothing, just return the character. */
|
||||
break;
|
||||
|
||||
case ';':
|
||||
case '\n':
|
||||
case '\0':
|
||||
/* Be safe and let the user call this function again. */
|
||||
--exp;
|
||||
result = YYEOF;
|
||||
break;
|
||||
|
||||
default:
|
||||
result = YYERRCODE;
|
||||
#if YYDEBUG != 0
|
||||
--exp;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
*pexp = exp;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
yyerror (str)
|
||||
const char *str;
|
||||
{
|
||||
/* Do nothing. We don't print error messages here. */
|
||||
}
|
31
lib/intl/ref-add.sin
Normal file
31
lib/intl/ref-add.sin
Normal file
|
@ -0,0 +1,31 @@
|
|||
# Add this package to a list of references stored in a text file.
|
||||
#
|
||||
# Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Library 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
|
||||
# Library General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library 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>.
|
||||
#
|
||||
/^# Packages using this file: / {
|
||||
s/# Packages using this file://
|
||||
ta
|
||||
:a
|
||||
s/ @PACKAGE@ / @PACKAGE@ /
|
||||
tb
|
||||
s/ $/ @PACKAGE@ /
|
||||
:b
|
||||
s/^/# Packages using this file:/
|
||||
}
|
26
lib/intl/ref-del.sin
Normal file
26
lib/intl/ref-del.sin
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Remove this package from a list of references stored in a text file.
|
||||
#
|
||||
# Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Library 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
|
||||
# Library General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library 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>.
|
||||
#
|
||||
/^# Packages using this file: / {
|
||||
s/# Packages using this file://
|
||||
s/ @PACKAGE@ / /
|
||||
s/^/# Packages using this file:/
|
||||
}
|
439
lib/intl/relocatable.c
Normal file
439
lib/intl/relocatable.c
Normal file
|
@ -0,0 +1,439 @@
|
|||
/* Provide relocatable packages.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2003.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
|
||||
/* Tell glibc's <stdio.h> to provide a prototype for getline().
|
||||
This must come before <config.h> because <config.h> may include
|
||||
<features.h>, and once <features.h> has been included, it's too late. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
/* Specification. */
|
||||
#include "relocatable.h"
|
||||
|
||||
#if ENABLE_RELOCATABLE
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef NO_XMALLOC
|
||||
# define xmalloc malloc
|
||||
#else
|
||||
# include "xmalloc.h"
|
||||
#endif
|
||||
|
||||
#if DEPENDS_ON_LIBCHARSET
|
||||
# include <libcharset.h>
|
||||
#endif
|
||||
#if DEPENDS_ON_LIBICONV && HAVE_ICONV
|
||||
# include <iconv.h>
|
||||
#endif
|
||||
#if DEPENDS_ON_LIBINTL && ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
#endif
|
||||
|
||||
/* Faked cheap 'bool'. */
|
||||
#undef bool
|
||||
#undef false
|
||||
#undef true
|
||||
#define bool int
|
||||
#define false 0
|
||||
#define true 1
|
||||
|
||||
/* Pathname support.
|
||||
ISSLASH(C) tests whether C is a directory separator character.
|
||||
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_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_PATH_WITH_DIR(P) (strchr (P, '/') != NULL)
|
||||
# define FILESYSTEM_PREFIX_LEN(P) 0
|
||||
#endif
|
||||
|
||||
/* Original installation prefix. */
|
||||
static char *orig_prefix;
|
||||
static size_t orig_prefix_len;
|
||||
/* Current installation prefix. */
|
||||
static char *curr_prefix;
|
||||
static size_t curr_prefix_len;
|
||||
/* These prefixes do not end in a slash. Anything that will be concatenated
|
||||
to them must start with a slash. */
|
||||
|
||||
/* Sets the original and the current installation prefix of this module.
|
||||
Relocation simply replaces a pathname starting with the original prefix
|
||||
by the corresponding pathname with the current prefix instead. Both
|
||||
prefixes should be directory names without trailing slash (i.e. use ""
|
||||
instead of "/"). */
|
||||
static void
|
||||
set_this_relocation_prefix (const char *orig_prefix_arg,
|
||||
const char *curr_prefix_arg)
|
||||
{
|
||||
if (orig_prefix_arg != NULL && curr_prefix_arg != NULL
|
||||
/* Optimization: if orig_prefix and curr_prefix are equal, the
|
||||
relocation is a nop. */
|
||||
&& strcmp (orig_prefix_arg, curr_prefix_arg) != 0)
|
||||
{
|
||||
/* Duplicate the argument strings. */
|
||||
char *memory;
|
||||
|
||||
orig_prefix_len = strlen (orig_prefix_arg);
|
||||
curr_prefix_len = strlen (curr_prefix_arg);
|
||||
memory = (char *) xmalloc (orig_prefix_len + 1 + curr_prefix_len + 1);
|
||||
#ifdef NO_XMALLOC
|
||||
if (memory != NULL)
|
||||
#endif
|
||||
{
|
||||
memcpy (memory, orig_prefix_arg, orig_prefix_len + 1);
|
||||
orig_prefix = memory;
|
||||
memory += orig_prefix_len + 1;
|
||||
memcpy (memory, curr_prefix_arg, curr_prefix_len + 1);
|
||||
curr_prefix = memory;
|
||||
return;
|
||||
}
|
||||
}
|
||||
orig_prefix = NULL;
|
||||
curr_prefix = NULL;
|
||||
/* Don't worry about wasted memory here - this function is usually only
|
||||
called once. */
|
||||
}
|
||||
|
||||
/* Sets the original and the current installation prefix of the package.
|
||||
Relocation simply replaces a pathname starting with the original prefix
|
||||
by the corresponding pathname with the current prefix instead. Both
|
||||
prefixes should be directory names without trailing slash (i.e. use ""
|
||||
instead of "/"). */
|
||||
void
|
||||
set_relocation_prefix (const char *orig_prefix_arg, const char *curr_prefix_arg)
|
||||
{
|
||||
set_this_relocation_prefix (orig_prefix_arg, curr_prefix_arg);
|
||||
|
||||
/* Now notify all dependent libraries. */
|
||||
#if DEPENDS_ON_LIBCHARSET
|
||||
libcharset_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg);
|
||||
#endif
|
||||
#if DEPENDS_ON_LIBICONV && HAVE_ICONV && _LIBICONV_VERSION >= 0x0109
|
||||
libiconv_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg);
|
||||
#endif
|
||||
#if DEPENDS_ON_LIBINTL && ENABLE_NLS && defined libintl_set_relocation_prefix
|
||||
libintl_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Convenience function:
|
||||
Computes the current installation prefix, based on the original
|
||||
installation prefix, the original installation directory of a particular
|
||||
file, and the current pathname of this file. Returns NULL upon failure. */
|
||||
#ifdef IN_LIBRARY
|
||||
#define compute_curr_prefix local_compute_curr_prefix
|
||||
static
|
||||
#endif
|
||||
const char *
|
||||
compute_curr_prefix (const char *orig_installprefix,
|
||||
const char *orig_installdir,
|
||||
const char *curr_pathname)
|
||||
{
|
||||
const char *curr_installdir;
|
||||
const char *rel_installdir;
|
||||
|
||||
if (curr_pathname == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Determine the relative installation directory, relative to the prefix.
|
||||
This is simply the difference between orig_installprefix and
|
||||
orig_installdir. */
|
||||
if (strncmp (orig_installprefix, orig_installdir, strlen (orig_installprefix))
|
||||
!= 0)
|
||||
/* Shouldn't happen - nothing should be installed outside $(prefix). */
|
||||
return NULL;
|
||||
rel_installdir = orig_installdir + strlen (orig_installprefix);
|
||||
|
||||
/* Determine the current installation directory. */
|
||||
{
|
||||
const char *p_base = curr_pathname + FILESYSTEM_PREFIX_LEN (curr_pathname);
|
||||
const char *p = curr_pathname + strlen (curr_pathname);
|
||||
char *q;
|
||||
|
||||
while (p > p_base)
|
||||
{
|
||||
p--;
|
||||
if (ISSLASH (*p))
|
||||
break;
|
||||
}
|
||||
|
||||
q = (char *) xmalloc (p - curr_pathname + 1);
|
||||
#ifdef NO_XMALLOC
|
||||
if (q == NULL)
|
||||
return NULL;
|
||||
#endif
|
||||
memcpy (q, curr_pathname, p - curr_pathname);
|
||||
q[p - curr_pathname] = '\0';
|
||||
curr_installdir = q;
|
||||
}
|
||||
|
||||
/* Compute the current installation prefix by removing the trailing
|
||||
rel_installdir from it. */
|
||||
{
|
||||
const char *rp = rel_installdir + strlen (rel_installdir);
|
||||
const char *cp = curr_installdir + strlen (curr_installdir);
|
||||
const char *cp_base =
|
||||
curr_installdir + FILESYSTEM_PREFIX_LEN (curr_installdir);
|
||||
|
||||
while (rp > rel_installdir && cp > cp_base)
|
||||
{
|
||||
bool same = false;
|
||||
const char *rpi = rp;
|
||||
const char *cpi = cp;
|
||||
|
||||
while (rpi > rel_installdir && cpi > cp_base)
|
||||
{
|
||||
rpi--;
|
||||
cpi--;
|
||||
if (ISSLASH (*rpi) || ISSLASH (*cpi))
|
||||
{
|
||||
if (ISSLASH (*rpi) && ISSLASH (*cpi))
|
||||
same = true;
|
||||
break;
|
||||
}
|
||||
#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__
|
||||
/* Win32, OS/2, DOS - case insignificant filesystem */
|
||||
if ((*rpi >= 'a' && *rpi <= 'z' ? *rpi - 'a' + 'A' : *rpi)
|
||||
!= (*cpi >= 'a' && *cpi <= 'z' ? *cpi - 'a' + 'A' : *cpi))
|
||||
break;
|
||||
#else
|
||||
if (*rpi != *cpi)
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
if (!same)
|
||||
break;
|
||||
/* The last pathname component was the same. opi and cpi now point
|
||||
to the slash before it. */
|
||||
rp = rpi;
|
||||
cp = cpi;
|
||||
}
|
||||
|
||||
if (rp > rel_installdir)
|
||||
/* Unexpected: The curr_installdir does not end with rel_installdir. */
|
||||
return NULL;
|
||||
|
||||
{
|
||||
size_t curr_prefix_len = cp - curr_installdir;
|
||||
char *curr_prefix;
|
||||
|
||||
curr_prefix = (char *) xmalloc (curr_prefix_len + 1);
|
||||
#ifdef NO_XMALLOC
|
||||
if (curr_prefix == NULL)
|
||||
return NULL;
|
||||
#endif
|
||||
memcpy (curr_prefix, curr_installdir, curr_prefix_len);
|
||||
curr_prefix[curr_prefix_len] = '\0';
|
||||
|
||||
return curr_prefix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined PIC && defined INSTALLDIR
|
||||
|
||||
/* Full pathname of shared library, or NULL. */
|
||||
static char *shared_library_fullname;
|
||||
|
||||
#if defined _WIN32 || defined __WIN32__
|
||||
|
||||
/* Determine the full pathname of the shared library when it is loaded. */
|
||||
|
||||
BOOL WINAPI
|
||||
DllMain (HINSTANCE module_handle, DWORD event, LPVOID reserved)
|
||||
{
|
||||
(void) reserved;
|
||||
|
||||
if (event == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
/* The DLL is being loaded into an application's address range. */
|
||||
static char location[MAX_PATH];
|
||||
|
||||
if (!GetModuleFileName (module_handle, location, sizeof (location)))
|
||||
/* Shouldn't happen. */
|
||||
return FALSE;
|
||||
|
||||
if (!IS_PATH_WITH_DIR (location))
|
||||
/* Shouldn't happen. */
|
||||
return FALSE;
|
||||
|
||||
shared_library_fullname = strdup (location);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#else /* Unix */
|
||||
|
||||
static void
|
||||
find_shared_library_fullname ()
|
||||
{
|
||||
#ifdef __linux__
|
||||
FILE *fp;
|
||||
|
||||
/* Open the current process' maps file. It describes one VMA per line. */
|
||||
fp = fopen ("/proc/self/maps", "r");
|
||||
if (fp)
|
||||
{
|
||||
unsigned long address = (unsigned long) &find_shared_library_fullname;
|
||||
for (;;)
|
||||
{
|
||||
unsigned long start, end;
|
||||
int c;
|
||||
|
||||
if (fscanf (fp, "%lx-%lx", &start, &end) != 2)
|
||||
break;
|
||||
if (address >= start && address <= end - 1)
|
||||
{
|
||||
/* Found it. Now see if this line contains a filename. */
|
||||
while (c = getc (fp), c != EOF && c != '\n' && c != '/')
|
||||
continue;
|
||||
if (c == '/')
|
||||
{
|
||||
size_t size;
|
||||
int len;
|
||||
|
||||
ungetc (c, fp);
|
||||
shared_library_fullname = NULL; size = 0;
|
||||
len = getline (&shared_library_fullname, &size, fp);
|
||||
if (len >= 0)
|
||||
{
|
||||
/* Success: filled shared_library_fullname. */
|
||||
if (len > 0 && shared_library_fullname[len - 1] == '\n')
|
||||
shared_library_fullname[len - 1] = '\0';
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
while (c = getc (fp), c != EOF && c != '\n')
|
||||
continue;
|
||||
}
|
||||
fclose (fp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* WIN32 / Unix */
|
||||
|
||||
/* Return the full pathname of the current shared library.
|
||||
Return NULL if unknown.
|
||||
Guaranteed to work only on Linux and Woe32. */
|
||||
static char *
|
||||
get_shared_library_fullname ()
|
||||
{
|
||||
#if !(defined _WIN32 || defined __WIN32__)
|
||||
static bool tried_find_shared_library_fullname;
|
||||
if (!tried_find_shared_library_fullname)
|
||||
{
|
||||
find_shared_library_fullname ();
|
||||
tried_find_shared_library_fullname = true;
|
||||
}
|
||||
#endif
|
||||
return shared_library_fullname;
|
||||
}
|
||||
|
||||
#endif /* PIC */
|
||||
|
||||
/* Returns the pathname, relocated according to the current installation
|
||||
directory. */
|
||||
const char *
|
||||
relocate (const char *pathname)
|
||||
{
|
||||
#if defined PIC && defined INSTALLDIR
|
||||
static int initialized;
|
||||
|
||||
/* Initialization code for a shared library. */
|
||||
if (!initialized)
|
||||
{
|
||||
/* At this point, orig_prefix and curr_prefix likely have already been
|
||||
set through the main program's set_program_name_and_installdir
|
||||
function. This is sufficient in the case that the library has
|
||||
initially been installed in the same orig_prefix. But we can do
|
||||
better, to also cover the cases that 1. it has been installed
|
||||
in a different prefix before being moved to orig_prefix and (later)
|
||||
to curr_prefix, 2. unlike the program, it has not moved away from
|
||||
orig_prefix. */
|
||||
const char *orig_installprefix = INSTALLPREFIX;
|
||||
const char *orig_installdir = INSTALLDIR;
|
||||
const char *curr_prefix_better;
|
||||
|
||||
curr_prefix_better =
|
||||
compute_curr_prefix (orig_installprefix, orig_installdir,
|
||||
get_shared_library_fullname ());
|
||||
if (curr_prefix_better == NULL)
|
||||
curr_prefix_better = curr_prefix;
|
||||
|
||||
set_relocation_prefix (orig_installprefix, curr_prefix_better);
|
||||
|
||||
initialized = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Note: It is not necessary to perform case insensitive comparison here,
|
||||
even for DOS-like filesystems, because the pathname argument was
|
||||
typically created from the same Makefile variable as orig_prefix came
|
||||
from. */
|
||||
if (orig_prefix != NULL && curr_prefix != NULL
|
||||
&& strncmp (pathname, orig_prefix, orig_prefix_len) == 0)
|
||||
{
|
||||
if (pathname[orig_prefix_len] == '\0')
|
||||
/* pathname equals orig_prefix. */
|
||||
return curr_prefix;
|
||||
if (ISSLASH (pathname[orig_prefix_len]))
|
||||
{
|
||||
/* pathname starts with orig_prefix. */
|
||||
const char *pathname_tail = &pathname[orig_prefix_len];
|
||||
char *result =
|
||||
(char *) xmalloc (curr_prefix_len + strlen (pathname_tail) + 1);
|
||||
|
||||
#ifdef NO_XMALLOC
|
||||
if (result != NULL)
|
||||
#endif
|
||||
{
|
||||
memcpy (result, curr_prefix, curr_prefix_len);
|
||||
strcpy (result + curr_prefix_len, pathname_tail);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Nothing to relocate. */
|
||||
return pathname;
|
||||
}
|
||||
|
||||
#endif
|
67
lib/intl/relocatable.h
Normal file
67
lib/intl/relocatable.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/* Provide relocatable packages.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2003.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifndef _RELOCATABLE_H
|
||||
#define _RELOCATABLE_H
|
||||
|
||||
/* This can be enabled through the configure --enable-relocatable option. */
|
||||
#if ENABLE_RELOCATABLE
|
||||
|
||||
/* When building a DLL, we must export some functions. Note that because
|
||||
this is a private .h file, we don't need to use __declspec(dllimport)
|
||||
in any case. */
|
||||
#if defined _MSC_VER && BUILDING_DLL
|
||||
# define RELOCATABLE_DLL_EXPORTED __declspec(dllexport)
|
||||
#else
|
||||
# define RELOCATABLE_DLL_EXPORTED
|
||||
#endif
|
||||
|
||||
/* Sets the original and the current installation prefix of the package.
|
||||
Relocation simply replaces a pathname starting with the original prefix
|
||||
by the corresponding pathname with the current prefix instead. Both
|
||||
prefixes should be directory names without trailing slash (i.e. use ""
|
||||
instead of "/"). */
|
||||
extern RELOCATABLE_DLL_EXPORTED void
|
||||
set_relocation_prefix (const char *orig_prefix,
|
||||
const char *curr_prefix);
|
||||
|
||||
/* Returns the pathname, relocated according to the current installation
|
||||
directory. */
|
||||
extern const char * relocate (const char *pathname);
|
||||
|
||||
/* Memory management: relocate() leaks memory, because it has to construct
|
||||
a fresh pathname. If this is a problem because your program calls
|
||||
relocate() frequently, think about caching the result. */
|
||||
|
||||
/* Convenience function:
|
||||
Computes the current installation prefix, based on the original
|
||||
installation prefix, the original installation directory of a particular
|
||||
file, and the current pathname of this file. Returns NULL upon failure. */
|
||||
extern const char * compute_curr_prefix (const char *orig_installprefix,
|
||||
const char *orig_installdir,
|
||||
const char *curr_pathname);
|
||||
|
||||
#else
|
||||
|
||||
/* By default, we use the hardwired pathnames. */
|
||||
#define relocate(pathname) (pathname)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _RELOCATABLE_H */
|
142
lib/intl/textdomain.c
Normal file
142
lib/intl/textdomain.c
Normal file
|
@ -0,0 +1,142 @@
|
|||
/* Implementation of the textdomain(3) function.
|
||||
Copyright (C) 1995-1998, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library 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. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _LIBC
|
||||
# include <libintl.h>
|
||||
#else
|
||||
# include "libgnuintl.h"
|
||||
#endif
|
||||
#include "gettextP.h"
|
||||
|
||||
#ifdef _LIBC
|
||||
/* We have to handle multi-threaded applications. */
|
||||
# include <bits/libc-lock.h>
|
||||
#else
|
||||
/* Provide dummy implementation if this is outside glibc. */
|
||||
# define __libc_rwlock_define(CLASS, NAME)
|
||||
# define __libc_rwlock_wrlock(NAME)
|
||||
# define __libc_rwlock_unlock(NAME)
|
||||
#endif
|
||||
|
||||
/* The internal variables in the standalone libintl.a must have different
|
||||
names than the internal variables in GNU libc, otherwise programs
|
||||
using libintl.a cannot be linked statically. */
|
||||
#if !defined _LIBC
|
||||
# define _nl_default_default_domain libintl_nl_default_default_domain
|
||||
# define _nl_current_default_domain libintl_nl_current_default_domain
|
||||
#endif
|
||||
|
||||
/* @@ end of prolog @@ */
|
||||
|
||||
/* Name of the default text domain. */
|
||||
extern const char _nl_default_default_domain[] attribute_hidden;
|
||||
|
||||
/* Default text domain in which entries for gettext(3) are to be found. */
|
||||
extern const char *_nl_current_default_domain attribute_hidden;
|
||||
|
||||
|
||||
/* Names for the libintl functions are a problem. They must not clash
|
||||
with existing names and they should follow ANSI C. But this source
|
||||
code is also used in GNU C Library where the names have a __
|
||||
prefix. So we have to make a difference here. */
|
||||
#ifdef _LIBC
|
||||
# define TEXTDOMAIN __textdomain
|
||||
# ifndef strdup
|
||||
# define strdup(str) __strdup (str)
|
||||
# endif
|
||||
#else
|
||||
# define TEXTDOMAIN libintl_textdomain
|
||||
#endif
|
||||
|
||||
/* Lock variable to protect the global data in the gettext implementation. */
|
||||
__libc_rwlock_define (extern, _nl_state_lock attribute_hidden)
|
||||
|
||||
/* Set the current default message catalog to DOMAINNAME.
|
||||
If DOMAINNAME is null, return the current default.
|
||||
If DOMAINNAME is "", reset to the default of "messages". */
|
||||
char *
|
||||
TEXTDOMAIN (domainname)
|
||||
const char *domainname;
|
||||
{
|
||||
char *new_domain;
|
||||
char *old_domain;
|
||||
|
||||
/* A NULL pointer requests the current setting. */
|
||||
if (domainname == NULL)
|
||||
return (char *) _nl_current_default_domain;
|
||||
|
||||
__libc_rwlock_wrlock (_nl_state_lock);
|
||||
|
||||
old_domain = (char *) _nl_current_default_domain;
|
||||
|
||||
/* If domain name is the null string set to default domain "messages". */
|
||||
if (domainname[0] == '\0'
|
||||
|| strcmp (domainname, _nl_default_default_domain) == 0)
|
||||
{
|
||||
_nl_current_default_domain = _nl_default_default_domain;
|
||||
new_domain = (char *) _nl_current_default_domain;
|
||||
}
|
||||
else if (strcmp (domainname, old_domain) == 0)
|
||||
/* This can happen and people will use it to signal that some
|
||||
environment variable changed. */
|
||||
new_domain = old_domain;
|
||||
else
|
||||
{
|
||||
/* If the following malloc fails `_nl_current_default_domain'
|
||||
will be NULL. This value will be returned and so signals we
|
||||
are out of core. */
|
||||
#if defined _LIBC || defined HAVE_STRDUP
|
||||
new_domain = strdup (domainname);
|
||||
#else
|
||||
size_t len = strlen (domainname) + 1;
|
||||
new_domain = (char *) malloc (len);
|
||||
if (new_domain != NULL)
|
||||
memcpy (new_domain, domainname, len);
|
||||
#endif
|
||||
|
||||
if (new_domain != NULL)
|
||||
_nl_current_default_domain = new_domain;
|
||||
}
|
||||
|
||||
/* We use this possibility to signal a change of the loaded catalogs
|
||||
since this is most likely the case and there is no other easy we
|
||||
to do it. Do it only when the call was successful. */
|
||||
if (new_domain != NULL)
|
||||
{
|
||||
++_nl_msg_cat_cntr;
|
||||
|
||||
if (old_domain != new_domain && old_domain != _nl_default_default_domain)
|
||||
free (old_domain);
|
||||
}
|
||||
|
||||
__libc_rwlock_unlock (_nl_state_lock);
|
||||
|
||||
return new_domain;
|
||||
}
|
||||
|
||||
#ifdef _LIBC
|
||||
/* Alias for function name in GNU C Library. */
|
||||
weak_alias (__textdomain, textdomain);
|
||||
#endif
|
|
@ -46,9 +46,16 @@ LDFLAGS = @LDFLAGS@
|
|||
DEFS = @DEFS@
|
||||
LOCAL_DEFS = @LOCAL_DEFS@
|
||||
|
||||
LIBBUILD = ${BUILD_DIR}/lib
|
||||
|
||||
BASHINCDIR = ${topdir}/include
|
||||
|
||||
INCLUDES = -I. -I../.. -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib
|
||||
INTL_LIBSRC = ${topdir}/lib/intl
|
||||
INTL_BUILDDIR = ${LIBBUILD}/intl
|
||||
INTL_INC = @INTL_INC@
|
||||
LIBINTL_H = @LIBINTL_H@
|
||||
|
||||
INCLUDES = -I. -I../.. -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib $(INTL_INC)
|
||||
|
||||
CCFLAGS = ${PROFILE_FLAGS} ${INCLUDES} $(DEFS) $(LOCAL_DEFS) $(LOCAL_CFLAGS) \
|
||||
$(CFLAGS) $(MALLOC_CFLAGS) $(CPPFLAGS)
|
||||
|
@ -116,6 +123,12 @@ trace.o: ${srcdir}/imalloc.h
|
|||
table.o: ${srcdir}/imalloc.h ${srcdir}/table.h
|
||||
watch.o: ${srcdir}/imalloc.h ${srcdir}/watch.h
|
||||
|
||||
malloc.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
|
||||
stats.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
|
||||
trace.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
|
||||
table.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
|
||||
watch.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
|
||||
|
||||
# Rules for deficient makes, like SunOS and Solaris
|
||||
stub.o: stub.c
|
||||
malloc.o: malloc.c
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Emulation of getpagesize() for systems that need it.
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
Copyright (C) 1991-2003 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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* imalloc.h -- internal malloc definitions shared by source files. */
|
||||
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001-2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
|
@ -159,4 +159,10 @@ do { \
|
|||
memcpy ((dest), (src), (nbytes)) \
|
||||
} while(0)
|
||||
|
||||
#if defined (SHELL)
|
||||
# include "bashintl.h"
|
||||
#else
|
||||
# define _(x) x
|
||||
#endif
|
||||
|
||||
#endif /* _IMALLOC_H */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* malloc.c - dynamic memory allocation for bash. */
|
||||
|
||||
/* Copyright (C) 1985, 1987, 1997 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1985-2003 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
|
||||
|
@ -236,7 +236,7 @@ static unsigned long binsizes[NBUCKETS] = {
|
|||
8192UL, 16384UL, 32768UL, 65536UL, 131072UL, 262144UL, 524288UL,
|
||||
1048576UL, 2097152UL, 4194304UL, 8388608UL, 16777216UL, 33554432UL,
|
||||
67108864UL, 134217728UL, 268435456UL, 536870912UL, 1073741824UL,
|
||||
2147483648UL, 4294967296UL-1
|
||||
2147483648UL, 4294967295UL
|
||||
};
|
||||
|
||||
/* binsizes[x] == (1 << ((x) + 3)) */
|
||||
|
@ -291,8 +291,11 @@ extern void mtrace_free __P((PTR_T, int, const char *, int));
|
|||
#if !defined (botch)
|
||||
static void
|
||||
botch (s, file, line)
|
||||
const char *s;
|
||||
const char *file;
|
||||
int line;
|
||||
{
|
||||
fprintf (stderr, "malloc: failed assertion: %s\n", s);
|
||||
fprintf (stderr, _("malloc: failed assertion: %s\n"), s);
|
||||
(void)fflush (stderr);
|
||||
abort ();
|
||||
}
|
||||
|
@ -308,7 +311,7 @@ xbotch (mem, e, s, file, line)
|
|||
const char *file;
|
||||
int line;
|
||||
{
|
||||
fprintf (stderr, "\r\nmalloc: %s:%d: assertion botched\r\n",
|
||||
fprintf (stderr, _("\r\nmalloc: %s:%d: assertion botched\r\n"),
|
||||
file ? file : "unknown", line);
|
||||
#ifdef MALLOC_REGISTER
|
||||
if (mem != NULL && malloc_register)
|
||||
|
@ -734,7 +737,7 @@ internal_malloc (n, file, line, flags) /* get a block */
|
|||
/* If not for this check, we would gobble a clobbered free chain ptr
|
||||
and bomb out on the NEXT allocate of this size block */
|
||||
if (p->mh_alloc != ISFREE || p->mh_index != nunits)
|
||||
xbotch ((PTR_T)(p+1), 0, "malloc: block on free list clobbered", file, line);
|
||||
xbotch ((PTR_T)(p+1), 0, _("malloc: block on free list clobbered"), file, line);
|
||||
|
||||
/* Fill in the info, and set up the magic numbers for range checking. */
|
||||
p->mh_alloc = ISALLOC;
|
||||
|
@ -811,10 +814,10 @@ internal_free (mem, file, line, flags)
|
|||
{
|
||||
if (p->mh_alloc == ISFREE)
|
||||
xbotch (mem, ERR_DUPFREE,
|
||||
"free: called with already freed block argument", file, line);
|
||||
_("free: called with already freed block argument"), file, line);
|
||||
else
|
||||
xbotch (mem, ERR_UNALLOC,
|
||||
"free: called with unallocated block argument", file, line);
|
||||
_("free: called with unallocated block argument"), file, line);
|
||||
}
|
||||
|
||||
ASSERT (p->mh_magic2 == MAGIC2);
|
||||
|
@ -833,13 +836,13 @@ internal_free (mem, file, line, flags)
|
|||
|
||||
if (IN_BUCKET(nbytes, nunits) == 0)
|
||||
xbotch (mem, ERR_UNDERFLOW,
|
||||
"free: underflow detected; mh_nbytes out of range", file, line);
|
||||
_("free: underflow detected; mh_nbytes out of range"), file, line);
|
||||
|
||||
ap += p->mh_nbytes;
|
||||
z = mg.s;
|
||||
*z++ = *ap++, *z++ = *ap++, *z++ = *ap++, *z++ = *ap++;
|
||||
if (mg.i != p->mh_nbytes)
|
||||
xbotch (mem, ERR_ASSERT_FAILED, "free: start and end chunk sizes differ", file, line);
|
||||
xbotch (mem, ERR_ASSERT_FAILED, _("free: start and end chunk sizes differ"), file, line);
|
||||
|
||||
#if 1
|
||||
if (nunits >= LESSCORE_MIN && ((char *)p + binsize(nunits) == memtop))
|
||||
|
@ -879,6 +882,7 @@ internal_free (mem, file, line, flags)
|
|||
busy[nunits] = 0;
|
||||
|
||||
free_return:
|
||||
; /* Empty statement in case this is the end of the function */
|
||||
|
||||
#ifdef MALLOC_STATS
|
||||
_mstats.nmalloc[nunits]--;
|
||||
|
@ -935,7 +939,7 @@ internal_realloc (mem, n, file, line, flags)
|
|||
|
||||
if (p->mh_alloc != ISALLOC)
|
||||
xbotch (mem, ERR_UNALLOC,
|
||||
"realloc: called with unallocated block argument", file, line);
|
||||
_("realloc: called with unallocated block argument"), file, line);
|
||||
|
||||
ASSERT (p->mh_magic2 == MAGIC2);
|
||||
nbytes = ALLOCATED_BYTES(p->mh_nbytes);
|
||||
|
@ -950,13 +954,13 @@ internal_realloc (mem, n, file, line, flags)
|
|||
original number of bytes requested. */
|
||||
if (IN_BUCKET(nbytes, nunits) == 0)
|
||||
xbotch (mem, ERR_UNDERFLOW,
|
||||
"realloc: underflow detected; mh_nbytes out of range", file, line);
|
||||
_("realloc: underflow detected; mh_nbytes out of range"), file, line);
|
||||
|
||||
m = (char *)mem + (tocopy = p->mh_nbytes);
|
||||
z = mg.s;
|
||||
*z++ = *m++, *z++ = *m++, *z++ = *m++, *z++ = *m++;
|
||||
if (mg.i != p->mh_nbytes)
|
||||
xbotch (mem, ERR_ASSERT_FAILED, "realloc: start and end chunk sizes differ", file, line);
|
||||
xbotch (mem, ERR_ASSERT_FAILED, _("realloc: start and end chunk sizes differ"), file, line);
|
||||
|
||||
#ifdef MALLOC_WATCH
|
||||
if (_malloc_nwatch > 0)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* mstats.h - definitions for malloc statistics */
|
||||
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001-2003 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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Functions (currently) for use by the shell to do malloc debugging and
|
||||
tracking. */
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001-2003 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
|
||||
|
@ -53,6 +53,7 @@ extern PTR_T sh_valloc __P((size_t, const char *, int));
|
|||
/* trace.c */
|
||||
extern int malloc_set_trace __P((int));
|
||||
extern void malloc_set_tracefp (); /* full prototype requires stdio.h */
|
||||
extern void malloc_set_tracefn __P((char *, char *));
|
||||
|
||||
/* table.c */
|
||||
extern void mregister_dump_table __P((void));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* stats.c - malloc statistics */
|
||||
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001-2003 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
|
||||
|
@ -35,6 +35,8 @@ extern int malloc_free_blocks __P((int));
|
|||
|
||||
extern struct _malstats _mstats;
|
||||
|
||||
extern FILE *_imalloc_fopen __P((char *, char *, char *, char *, size_t));
|
||||
|
||||
struct bucket_stats
|
||||
malloc_bucket_stats (size)
|
||||
int size;
|
||||
|
@ -129,14 +131,37 @@ fprint_malloc_stats (s, fp)
|
|||
_print_malloc_stats (s, fp);
|
||||
}
|
||||
|
||||
#define TRACEROOT "/var/tmp/maltrace/trace."
|
||||
static char mallbuf[1024];
|
||||
#define TRACEROOT "/var/tmp/maltrace/stats."
|
||||
|
||||
void
|
||||
trace_malloc_stats (s, fn)
|
||||
char *s, *fn;
|
||||
{
|
||||
FILE *fp;
|
||||
char defname[sizeof (TRACEROOT) + 64];
|
||||
static char mallbuf[1024];
|
||||
|
||||
fp = _imalloc_fopen (s, fn, TRACEROOT, defname, sizeof (defname));
|
||||
if (fp)
|
||||
{
|
||||
setvbuf (fp, mallbuf, _IOFBF, sizeof (mallbuf));
|
||||
_print_malloc_stats (s, fp);
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MALLOC_STATS */
|
||||
|
||||
#if defined (MALLOC_STATS) || defined (MALLOC_TRACE)
|
||||
FILE *
|
||||
_imalloc_fopen (s, fn, def, defbuf, defsiz)
|
||||
char *s;
|
||||
char *fn;
|
||||
char *def;
|
||||
char *defbuf;
|
||||
size_t defsiz;
|
||||
{
|
||||
char fname[1024];
|
||||
long l;
|
||||
FILE *fp;
|
||||
|
@ -144,8 +169,8 @@ trace_malloc_stats (s, fn)
|
|||
l = (long)getpid ();
|
||||
if (fn == 0)
|
||||
{
|
||||
sprintf (defname, "%s%ld", TRACEROOT, l);
|
||||
fp = fopen(defname, "w");
|
||||
sprintf (defbuf, "%s%ld", def, l);
|
||||
fp = fopen(defbuf, "w");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -171,14 +196,7 @@ trace_malloc_stats (s, fn)
|
|||
*p = '\0';
|
||||
fp = fopen (fname, "w");
|
||||
}
|
||||
|
||||
if (fp)
|
||||
{
|
||||
setvbuf (fp, mallbuf, _IOFBF, sizeof (mallbuf));
|
||||
_print_malloc_stats (s, fp);
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MALLOC_STATS */
|
||||
return fp;
|
||||
}
|
||||
#endif /* MALLOC_STATS || MALLOC_TRACE */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 1993-2002 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1993-2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* table.c - bookkeeping functions for allocated memory */
|
||||
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001-2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
|
@ -172,14 +172,14 @@ mregister_alloc (tag, mem, size, file, line)
|
|||
if (tentry == 0)
|
||||
{
|
||||
/* oops. table is full. punt. */
|
||||
fprintf (stderr, "register_alloc: alloc table is full with FIND_ALLOC?\n");
|
||||
fprintf (stderr, _("register_alloc: alloc table is full with FIND_ALLOC?\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (tentry->flags & MT_ALLOC)
|
||||
{
|
||||
/* oops. bad bookkeeping. ignore for now */
|
||||
fprintf (stderr, "register_alloc: %p already in table as allocated?\n", mem);
|
||||
fprintf (stderr, _("register_alloc: %p already in table as allocated?\n"), mem);
|
||||
}
|
||||
|
||||
tentry->mem = mem;
|
||||
|
@ -215,7 +215,7 @@ mregister_free (mem, size, file, line)
|
|||
if (tentry->flags & MT_FREE)
|
||||
{
|
||||
/* oops. bad bookkeeping. ignore for now */
|
||||
fprintf (stderr, "register_free: %p already in table as free?\n", mem);
|
||||
fprintf (stderr, _("register_free: %p already in table as free?\n"), mem);
|
||||
}
|
||||
|
||||
tentry->flags = MT_FREE;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* table.h - definitions for tables for keeping track of allocated memory */
|
||||
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001-2003 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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* trace.c - tracing functions for malloc */
|
||||
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001-2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
|
@ -29,6 +29,8 @@ extern int malloc_trace;
|
|||
|
||||
static int _mtrace_verbose = 0;
|
||||
|
||||
extern FILE *_imalloc_fopen __P((char *, char *, char *, char *, size_t));
|
||||
|
||||
#ifdef MALLOC_TRACE
|
||||
|
||||
FILE *_mtrace_fp = NULL;
|
||||
|
@ -101,3 +103,20 @@ malloc_trace_bin (n)
|
|||
_malloc_trace_buckets[n] = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define TRACEROOT "/var/tmp/maltrace/trace."
|
||||
|
||||
void
|
||||
malloc_set_tracefn (s, fn)
|
||||
char *s;
|
||||
char *fn;
|
||||
{
|
||||
#ifdef MALLOC_TRACE
|
||||
FILE *fp;
|
||||
char defname[sizeof (TRACEROOT) + 64];
|
||||
|
||||
fp = _imalloc_fopen (s, fn, TRACEROOT, defname, sizeof (defname));
|
||||
if (fp)
|
||||
malloc_set_tracefp (fp);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* watch.c - watchpoint functions for malloc */
|
||||
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001-2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
|
@ -43,17 +43,17 @@ watch_warn (addr, file, line, type, data)
|
|||
char *tag;
|
||||
|
||||
if (type == W_ALLOC)
|
||||
tag = "allocated";
|
||||
tag = _("allocated");
|
||||
else if (type == W_FREE)
|
||||
tag = "freed";
|
||||
tag = _("freed");
|
||||
else if (type == W_REALLOC)
|
||||
tag = "requesting resize";
|
||||
tag = _("requesting resize");
|
||||
else if (type == W_RESIZED)
|
||||
tag = "just resized";
|
||||
tag = _("just resized");
|
||||
else
|
||||
tag = "bug: unknown operation";
|
||||
tag = _("bug: unknown operation");
|
||||
|
||||
fprintf (stderr, "malloc: watch alert: %p %s ", addr, tag);
|
||||
fprintf (stderr, _("malloc: watch alert: %p %s "), addr, tag);
|
||||
if (data != (unsigned long)-1)
|
||||
fprintf (stderr, "(size %lu) ", data);
|
||||
fprintf (stderr, "from '%s:%d'\n", file ? file : "unknown", line);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* watch.h - definitions for tables for keeping track of allocated memory */
|
||||
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001-2003 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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* xmalloc.c -- safe versions of malloc and realloc */
|
||||
|
||||
/* Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991-2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Readline, a library for reading lines
|
||||
of text with interactive input and history editing.
|
||||
|
|
|
@ -20,6 +20,14 @@
|
|||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
||||
|
||||
PACKAGE = @PACKAGE_NAME@
|
||||
VERSION = @PACKAGE_VERSION@
|
||||
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
|
||||
srcdir = @srcdir@
|
||||
VPATH = .:@srcdir@
|
||||
topdir = @top_srcdir@
|
||||
|
@ -345,7 +353,7 @@ search.o: search.c
|
|||
shell.o: shell.c
|
||||
signals.o: signals.c
|
||||
terminal.o: terminal.c
|
||||
text.o: terminal.c
|
||||
text.o: text.c
|
||||
tilde.o: tilde.c
|
||||
undo.o: undo.c
|
||||
util.o: util.c
|
||||
|
|
|
@ -19,8 +19,13 @@
|
|||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (__TANDEM)
|
||||
# include <floss.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
@ -148,6 +153,34 @@ rl_bind_key_in_map (key, function, map)
|
|||
return (result);
|
||||
}
|
||||
|
||||
/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right
|
||||
now, this is always used to attempt to bind the arrow keys, hence the
|
||||
check for rl_vi_movement_mode. */
|
||||
int
|
||||
rl_bind_key_if_unbound_in_map (key, default_func, kmap)
|
||||
int key;
|
||||
rl_command_func_t *default_func;
|
||||
Keymap kmap;
|
||||
{
|
||||
char keyseq[2];
|
||||
|
||||
keyseq[0] = (unsigned char)key;
|
||||
keyseq[1] = '\0';
|
||||
return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap));
|
||||
}
|
||||
|
||||
int
|
||||
rl_bind_key_if_unbound (key, default_func)
|
||||
int key;
|
||||
rl_command_func_t *default_func;
|
||||
{
|
||||
char keyseq[2];
|
||||
|
||||
keyseq[0] = (unsigned char)key;
|
||||
keyseq[1] = '\0';
|
||||
return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap));
|
||||
}
|
||||
|
||||
/* Make KEY do nothing in the currently selected keymap.
|
||||
Returns non-zero in case of error. */
|
||||
int
|
||||
|
@ -199,10 +232,31 @@ rl_unbind_command_in_map (command, map)
|
|||
return (rl_unbind_function_in_map (func, map));
|
||||
}
|
||||
|
||||
/* Bind the key sequence represented by the string KEYSEQ to
|
||||
FUNCTION, starting in the current keymap. This makes new
|
||||
keymaps as necessary. */
|
||||
int
|
||||
rl_bind_keyseq (keyseq, function)
|
||||
const char *keyseq;
|
||||
rl_command_func_t *function;
|
||||
{
|
||||
return (rl_generic_bind (ISFUNC, keyseq, (char *)function, _rl_keymap));
|
||||
}
|
||||
|
||||
/* Bind the key sequence represented by the string KEYSEQ to
|
||||
FUNCTION. This makes new keymaps as necessary. The initial
|
||||
place to do bindings is in MAP. */
|
||||
int
|
||||
rl_bind_keyseq_in_map (keyseq, function, map)
|
||||
const char *keyseq;
|
||||
rl_command_func_t *function;
|
||||
Keymap map;
|
||||
{
|
||||
return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));
|
||||
}
|
||||
|
||||
/* Backwards compatibility; equivalent to rl_bind_keyseq_in_map() */
|
||||
int
|
||||
rl_set_key (keyseq, function, map)
|
||||
const char *keyseq;
|
||||
rl_command_func_t *function;
|
||||
|
@ -211,6 +265,40 @@ rl_set_key (keyseq, function, map)
|
|||
return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));
|
||||
}
|
||||
|
||||
/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right
|
||||
now, this is always used to attempt to bind the arrow keys, hence the
|
||||
check for rl_vi_movement_mode. */
|
||||
int
|
||||
rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap)
|
||||
const char *keyseq;
|
||||
rl_command_func_t *default_func;
|
||||
Keymap kmap;
|
||||
{
|
||||
rl_command_func_t *func;
|
||||
|
||||
if (keyseq)
|
||||
{
|
||||
func = rl_function_of_keyseq (keyseq, kmap, (int *)NULL);
|
||||
#if defined (VI_MODE)
|
||||
if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode)
|
||||
#else
|
||||
if (!func || func == rl_do_lowercase_version)
|
||||
#endif
|
||||
return (rl_bind_keyseq_in_map (keyseq, default_func, kmap));
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rl_bind_keyseq_if_unbound (keyseq, default_func)
|
||||
const char *keyseq;
|
||||
rl_command_func_t *default_func;
|
||||
{
|
||||
return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap));
|
||||
}
|
||||
|
||||
/* Bind the key sequence represented by the string KEYSEQ to
|
||||
the string of characters MACRO. This makes new keymaps as
|
||||
necessary. The initial place to do bindings is in MAP. */
|
||||
|
@ -311,7 +399,7 @@ rl_generic_bind (type, keyseq, data, map)
|
|||
mapped to something, `abc' to be mapped to something else,
|
||||
and the function bound to `a' to be executed when the user
|
||||
types `abx', leaving `bx' in the input queue. */
|
||||
if (k.function /* && k.type == ISFUNC */)
|
||||
if (k.function && ((k.type == ISFUNC && k.function != rl_do_lowercase_version) || k.type == ISMACR))
|
||||
{
|
||||
map[ANYOTHERKEY] = k;
|
||||
k.function = 0;
|
||||
|
@ -912,9 +1000,15 @@ parser_else (args)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Check the previous (n - 1) levels of the stack to make sure that
|
||||
we haven't previously turned off parsing. */
|
||||
for (i = 0; i < if_stack_depth - 1; i++)
|
||||
#else
|
||||
/* Check the previous (n) levels of the stack to make sure that
|
||||
we haven't previously turned off parsing. */
|
||||
for (i = 0; i < if_stack_depth; i++)
|
||||
#endif
|
||||
if (if_stack[i] == 1)
|
||||
return 0;
|
||||
|
||||
|
@ -1161,7 +1255,7 @@ rl_parse_and_bind (string)
|
|||
}
|
||||
|
||||
/* If this is a new-style key-binding, then do the binding with
|
||||
rl_set_key (). Otherwise, let the older code deal with it. */
|
||||
rl_bind_keyseq (). Otherwise, let the older code deal with it. */
|
||||
if (*string == '"')
|
||||
{
|
||||
char *seq;
|
||||
|
@ -1200,7 +1294,7 @@ rl_parse_and_bind (string)
|
|||
rl_macro_bind (seq, &funname[1], _rl_keymap);
|
||||
}
|
||||
else
|
||||
rl_set_key (seq, rl_named_function (funname), _rl_keymap);
|
||||
rl_bind_keyseq (seq, rl_named_function (funname));
|
||||
|
||||
free (seq);
|
||||
return 0;
|
||||
|
@ -1281,6 +1375,7 @@ static struct {
|
|||
{ "prefer-visible-bell", &_rl_prefer_visible_bell, V_SPECIAL },
|
||||
{ "print-completions-horizontally", &_rl_print_completions_horizontally, 0 },
|
||||
{ "show-all-if-ambiguous", &_rl_complete_show_all, 0 },
|
||||
{ "show-all-if-unmodified", &_rl_complete_show_unmodified, 0 },
|
||||
#if defined (VISIBLE_STATS)
|
||||
{ "visible-stats", &rl_visible_stats, 0 },
|
||||
#endif /* VISIBLE_STATS */
|
||||
|
@ -1650,7 +1745,7 @@ rl_get_keymap_name_from_edit_mode ()
|
|||
/* Each of the following functions produces information about the
|
||||
state of keybindings and functions known to Readline. The info
|
||||
is always printed to rl_outstream, and in such a way that it can
|
||||
be read back in (i.e., passed to rl_parse_and_bind (). */
|
||||
be read back in (i.e., passed to rl_parse_and_bind ()). */
|
||||
|
||||
/* Print the names of functions known to Readline. */
|
||||
void
|
||||
|
@ -2112,28 +2207,6 @@ rl_dump_variables (count, key)
|
|||
return (0);
|
||||
}
|
||||
|
||||
/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right
|
||||
now, this is always used to attempt to bind the arrow keys, hence the
|
||||
check for rl_vi_movement_mode. */
|
||||
void
|
||||
_rl_bind_if_unbound (keyseq, default_func)
|
||||
const char *keyseq;
|
||||
rl_command_func_t *default_func;
|
||||
{
|
||||
rl_command_func_t *func;
|
||||
|
||||
if (keyseq)
|
||||
{
|
||||
func = rl_function_of_keyseq (keyseq, _rl_keymap, (int *)NULL);
|
||||
#if defined (VI_MODE)
|
||||
if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode)
|
||||
#else
|
||||
if (!func || func == rl_do_lowercase_version)
|
||||
#endif
|
||||
rl_set_key (keyseq, default_func, _rl_keymap);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return non-zero if any members of ARRAY are a substring in STRING. */
|
||||
static int
|
||||
substring_member_of_array (string, array)
|
||||
|
|
|
@ -131,7 +131,7 @@ rl_callback_read_char ()
|
|||
if (in_handler == 0 && rl_linefunc)
|
||||
_rl_callback_newline ();
|
||||
}
|
||||
if (rl_pending_input)
|
||||
if (rl_pending_input || _rl_pushed_input_available ())
|
||||
eof = readline_internal_char ();
|
||||
else
|
||||
break;
|
||||
|
|
|
@ -77,7 +77,11 @@
|
|||
# define isxdigit(c) (isdigit((c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
|
||||
#endif
|
||||
|
||||
#define NON_NEGATIVE(c) ((unsigned char)(c) == (c))
|
||||
#if defined (CTYPE_NON_ASCII)
|
||||
# define NON_NEGATIVE(c) 1
|
||||
#else
|
||||
# define NON_NEGATIVE(c) ((unsigned char)(c) == (c))
|
||||
#endif
|
||||
|
||||
/* Some systems define these; we want our definitions. */
|
||||
#undef ISPRINT
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* complete.c -- filename completion for readline. */
|
||||
|
||||
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
@ -28,7 +28,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#if defined (HAVE_SYS_FILE_H)
|
||||
#include <sys/file.h>
|
||||
# include <sys/file.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
|
@ -99,12 +99,16 @@ rl_compdisp_func_t *rl_completion_display_matches_hook = (rl_compdisp_func_t *)N
|
|||
static int stat_char PARAMS((char *));
|
||||
#endif
|
||||
|
||||
static int path_isdir PARAMS((const char *));
|
||||
|
||||
static char *rl_quote_filename PARAMS((char *, int, char *));
|
||||
|
||||
static void set_completion_defaults PARAMS((int));
|
||||
static int get_y_or_n PARAMS((int));
|
||||
static int _rl_internal_pager PARAMS((int));
|
||||
static char *printable_part PARAMS((char *));
|
||||
static int fnwidth PARAMS((const char *));
|
||||
static int fnprint PARAMS((const char *));
|
||||
static int print_filename PARAMS((char *, char *));
|
||||
|
||||
static char **gen_completion_matches PARAMS((char *, int, int, rl_compentry_func_t *, int, int));
|
||||
|
@ -130,6 +134,10 @@ static char *make_quoted_replacement PARAMS((char *, int, char *));
|
|||
/* If non-zero, non-unique completions always show the list of matches. */
|
||||
int _rl_complete_show_all = 0;
|
||||
|
||||
/* If non-zero, non-unique completions show the list of matches, unless it
|
||||
is not possible to do partial completion and modify the line. */
|
||||
int _rl_complete_show_unmodified = 0;
|
||||
|
||||
/* If non-zero, completed directory names have a slash appended. */
|
||||
int _rl_complete_mark_directories = 1;
|
||||
|
||||
|
@ -214,7 +222,12 @@ const char *rl_basic_quote_characters = "\"'";
|
|||
/* The list of characters that signal a break between words for
|
||||
rl_complete_internal. The default list is the contents of
|
||||
rl_basic_word_break_characters. */
|
||||
const char *rl_completer_word_break_characters = (const char *)NULL;
|
||||
/*const*/ char *rl_completer_word_break_characters = (/*const*/ char *)NULL;
|
||||
|
||||
/* Hook function to allow an application to set the completion word
|
||||
break characters before readline breaks up the line. Allows
|
||||
position-dependent word break characters. */
|
||||
rl_cpvfunc_t *rl_completion_word_break_hook = (rl_cpvfunc_t *)NULL;
|
||||
|
||||
/* List of characters which can be used to quote a substring of the line.
|
||||
Completion occurs on the entire substring, and within the substring
|
||||
|
@ -282,6 +295,19 @@ int rl_completion_suppress_append = 0;
|
|||
default is a space. */
|
||||
int rl_completion_append_character = ' ';
|
||||
|
||||
/* If non-zero, the completion functions don't append any closing quote.
|
||||
This is set to 0 by rl_complete_internal and may be changed by an
|
||||
application-specific completion function. */
|
||||
int rl_completion_suppress_quote = 0;
|
||||
|
||||
/* Set to any quote character readline thinks it finds before any application
|
||||
completion function is called. */
|
||||
int rl_completion_quote_character;
|
||||
|
||||
/* Set to a non-zero value if readline found quoting anywhere in the word to
|
||||
be completed; set before any application completion function is called. */
|
||||
int rl_completion_found_quote;
|
||||
|
||||
/* If non-zero, a slash will be appended to completed filenames that are
|
||||
symbolic links to directory names, subject to the value of the
|
||||
mark-directories variable (which is user-settable). This exists so
|
||||
|
@ -320,6 +346,8 @@ rl_complete (ignore, invoking_key)
|
|||
return (rl_complete_internal ('?'));
|
||||
else if (_rl_complete_show_all)
|
||||
return (rl_complete_internal ('!'));
|
||||
else if (_rl_complete_show_unmodified)
|
||||
return (rl_complete_internal ('@'));
|
||||
else
|
||||
return (rl_complete_internal (TAB));
|
||||
}
|
||||
|
@ -352,6 +380,8 @@ rl_completion_mode (cfunc)
|
|||
return '?';
|
||||
else if (_rl_complete_show_all)
|
||||
return '!';
|
||||
else if (_rl_complete_show_unmodified)
|
||||
return '@';
|
||||
else
|
||||
return TAB;
|
||||
}
|
||||
|
@ -372,7 +402,7 @@ set_completion_defaults (what_to_do)
|
|||
rl_filename_completion_desired = 0;
|
||||
rl_filename_quoting_desired = 1;
|
||||
rl_completion_type = what_to_do;
|
||||
rl_completion_suppress_append = 0;
|
||||
rl_completion_suppress_append = rl_completion_suppress_quote = 0;
|
||||
|
||||
/* The completion entry function may optionally change this. */
|
||||
rl_completion_mark_symlink_dirs = _rl_complete_mark_symlink_dirs;
|
||||
|
@ -423,6 +453,15 @@ _rl_internal_pager (lines)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
path_isdir (filename)
|
||||
const char *filename;
|
||||
{
|
||||
struct stat finfo;
|
||||
|
||||
return (stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode));
|
||||
}
|
||||
|
||||
#if defined (VISIBLE_STATS)
|
||||
/* Return the character which best describes FILENAME.
|
||||
`@' for symbolic links
|
||||
|
@ -520,53 +559,140 @@ printable_part (pathname)
|
|||
return ++temp;
|
||||
}
|
||||
|
||||
/* Compute width of STRING when displayed on screen by print_filename */
|
||||
static int
|
||||
fnwidth (string)
|
||||
const char *string;
|
||||
{
|
||||
int width, pos;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
mbstate_t ps;
|
||||
int left, w;
|
||||
size_t clen;
|
||||
wchar_t wc;
|
||||
|
||||
left = strlen (string) + 1;
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
#endif
|
||||
|
||||
width = pos = 0;
|
||||
while (string[pos])
|
||||
{
|
||||
if (CTRL_CHAR (*string) || *string == RUBOUT)
|
||||
{
|
||||
width += 2;
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
clen = mbrtowc (&wc, string + pos, left - pos, &ps);
|
||||
if (MB_INVALIDCH (clen))
|
||||
{
|
||||
width++;
|
||||
pos++;
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
}
|
||||
else if (MB_NULLWCH (clen))
|
||||
break;
|
||||
else
|
||||
{
|
||||
pos += clen;
|
||||
w = wcwidth (wc);
|
||||
width += (w >= 0) ? w : 1;
|
||||
}
|
||||
#else
|
||||
width++;
|
||||
pos++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
static int
|
||||
fnprint (to_print)
|
||||
const char *to_print;
|
||||
{
|
||||
int printed_len;
|
||||
const char *s;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
mbstate_t ps;
|
||||
const char *end;
|
||||
size_t tlen;
|
||||
|
||||
end = to_print + strlen (to_print) + 1;
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
#endif
|
||||
|
||||
printed_len = 0;
|
||||
s = to_print;
|
||||
while (*s)
|
||||
{
|
||||
if (CTRL_CHAR (*s))
|
||||
{
|
||||
putc ('^', rl_outstream);
|
||||
putc (UNCTRL (*s), rl_outstream);
|
||||
printed_len += 2;
|
||||
s++;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
#endif
|
||||
}
|
||||
else if (*s == RUBOUT)
|
||||
{
|
||||
putc ('^', rl_outstream);
|
||||
putc ('?', rl_outstream);
|
||||
printed_len += 2;
|
||||
s++;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
tlen = mbrlen (s, end - s, &ps);
|
||||
if (MB_INVALIDCH (tlen))
|
||||
{
|
||||
tlen = 1;
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
}
|
||||
else if (MB_NULLWCH (tlen))
|
||||
break;
|
||||
fwrite (s, 1, tlen, rl_outstream);
|
||||
s += tlen;
|
||||
#else
|
||||
putc (*s, rl_outstream);
|
||||
s++;
|
||||
#endif
|
||||
printed_len++;
|
||||
}
|
||||
}
|
||||
|
||||
return printed_len;
|
||||
}
|
||||
|
||||
/* Output TO_PRINT to rl_outstream. If VISIBLE_STATS is defined and we
|
||||
are using it, check for and output a single character for `special'
|
||||
filenames. Return the number of characters we output. */
|
||||
|
||||
#define PUTX(c) \
|
||||
do { \
|
||||
if (CTRL_CHAR (c)) \
|
||||
{ \
|
||||
putc ('^', rl_outstream); \
|
||||
putc (UNCTRL (c), rl_outstream); \
|
||||
printed_len += 2; \
|
||||
} \
|
||||
else if (c == RUBOUT) \
|
||||
{ \
|
||||
putc ('^', rl_outstream); \
|
||||
putc ('?', rl_outstream); \
|
||||
printed_len += 2; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
putc (c, rl_outstream); \
|
||||
printed_len++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static int
|
||||
print_filename (to_print, full_pathname)
|
||||
char *to_print, *full_pathname;
|
||||
{
|
||||
int printed_len = 0;
|
||||
#if !defined (VISIBLE_STATS)
|
||||
char *s;
|
||||
|
||||
for (s = to_print; *s; s++)
|
||||
{
|
||||
PUTX (*s);
|
||||
}
|
||||
#else
|
||||
int printed_len, extension_char, slen, tlen;
|
||||
char *s, c, *new_full_pathname;
|
||||
int extension_char, slen, tlen;
|
||||
|
||||
for (s = to_print; *s; s++)
|
||||
{
|
||||
PUTX (*s);
|
||||
}
|
||||
extension_char = 0;
|
||||
printed_len = fnprint (to_print);
|
||||
|
||||
if (rl_filename_completion_desired && rl_visible_stats)
|
||||
#if defined (VISIBLE_STATS)
|
||||
if (rl_filename_completion_desired && (rl_visible_stats || _rl_complete_mark_directories))
|
||||
#else
|
||||
if (rl_filename_completion_desired && _rl_complete_mark_directories)
|
||||
#endif
|
||||
{
|
||||
/* If to_print != full_pathname, to_print is the basename of the
|
||||
path passed. In this case, we try to expand the directory
|
||||
|
@ -593,7 +719,13 @@ print_filename (to_print, full_pathname)
|
|||
new_full_pathname[slen] = '/';
|
||||
strcpy (new_full_pathname + slen + 1, to_print);
|
||||
|
||||
extension_char = stat_char (new_full_pathname);
|
||||
#if defined (VISIBLE_STATS)
|
||||
if (rl_visible_stats)
|
||||
extension_char = stat_char (new_full_pathname);
|
||||
else
|
||||
#endif
|
||||
if (path_isdir (new_full_pathname))
|
||||
extension_char = '/';
|
||||
|
||||
free (new_full_pathname);
|
||||
to_print[-1] = c;
|
||||
|
@ -601,7 +733,13 @@ print_filename (to_print, full_pathname)
|
|||
else
|
||||
{
|
||||
s = tilde_expand (full_pathname);
|
||||
extension_char = stat_char (s);
|
||||
#if defined (VISIBLE_STATS)
|
||||
if (rl_visible_stats)
|
||||
extension_char = stat_char (s);
|
||||
else
|
||||
#endif
|
||||
if (path_isdir (s))
|
||||
extension_char = '/';
|
||||
}
|
||||
|
||||
free (s);
|
||||
|
@ -611,7 +749,7 @@ print_filename (to_print, full_pathname)
|
|||
printed_len++;
|
||||
}
|
||||
}
|
||||
#endif /* VISIBLE_STATS */
|
||||
|
||||
return printed_len;
|
||||
}
|
||||
|
||||
|
@ -651,19 +789,32 @@ _rl_find_completion_word (fp, dp)
|
|||
int *fp, *dp;
|
||||
{
|
||||
int scan, end, found_quote, delimiter, pass_next, isbrk;
|
||||
char quote_char;
|
||||
char quote_char, *brkchars;
|
||||
|
||||
end = rl_point;
|
||||
found_quote = delimiter = 0;
|
||||
quote_char = '\0';
|
||||
|
||||
brkchars = 0;
|
||||
if (rl_completion_word_break_hook)
|
||||
brkchars = (*rl_completion_word_break_hook) ();
|
||||
if (brkchars == 0)
|
||||
brkchars = rl_completer_word_break_characters;
|
||||
|
||||
if (rl_completer_quote_characters)
|
||||
{
|
||||
/* We have a list of characters which can be used in pairs to
|
||||
quote substrings for the completer. Try to find the start
|
||||
of an unclosed quoted substring. */
|
||||
/* FOUND_QUOTE is set so we know what kind of quotes we found. */
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
for (scan = pass_next = 0; scan < end;
|
||||
scan = ((MB_CUR_MAX == 1 || rl_byte_oriented)
|
||||
? (scan + 1)
|
||||
: _rl_find_next_mbchar (rl_line_buffer, scan, 1, MB_FIND_ANY)))
|
||||
#else
|
||||
for (scan = pass_next = 0; scan < end; scan++)
|
||||
#endif
|
||||
{
|
||||
if (pass_next)
|
||||
{
|
||||
|
@ -721,7 +872,7 @@ _rl_find_completion_word (fp, dp)
|
|||
{
|
||||
scan = rl_line_buffer[rl_point];
|
||||
|
||||
if (strchr (rl_completer_word_break_characters, scan) == 0)
|
||||
if (strchr (brkchars, scan) == 0)
|
||||
continue;
|
||||
|
||||
/* Call the application-specific function to tell us whether
|
||||
|
@ -749,9 +900,9 @@ _rl_find_completion_word (fp, dp)
|
|||
if (rl_char_is_quoted_p)
|
||||
isbrk = (found_quote == 0 ||
|
||||
(*rl_char_is_quoted_p) (rl_line_buffer, rl_point) == 0) &&
|
||||
strchr (rl_completer_word_break_characters, scan) != 0;
|
||||
strchr (brkchars, scan) != 0;
|
||||
else
|
||||
isbrk = strchr (rl_completer_word_break_characters, scan) != 0;
|
||||
isbrk = strchr (brkchars, scan) != 0;
|
||||
|
||||
if (isbrk)
|
||||
{
|
||||
|
@ -786,6 +937,9 @@ gen_completion_matches (text, start, end, our_func, found_quote, quote_char)
|
|||
{
|
||||
char **matches, *temp;
|
||||
|
||||
rl_completion_found_quote = found_quote;
|
||||
rl_completion_quote_character = quote_char;
|
||||
|
||||
/* If the user wants to TRY to complete, but then wants to give
|
||||
up and use the default completion function, they set the
|
||||
variable rl_attempted_completion_function. */
|
||||
|
@ -889,6 +1043,7 @@ compute_lcd_of_matches (match_list, matches, text)
|
|||
{
|
||||
register int i, c1, c2, si;
|
||||
int low; /* Count of max-matched characters. */
|
||||
char *dtext; /* dequoted TEXT, if needed */
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
int v;
|
||||
mbstate_t ps1, ps2;
|
||||
|
@ -980,6 +1135,26 @@ compute_lcd_of_matches (match_list, matches, text)
|
|||
the user typed in the face of multiple matches differing in case. */
|
||||
if (_rl_completion_case_fold)
|
||||
{
|
||||
/* We're making an assumption here:
|
||||
IF we're completing filenames AND
|
||||
the application has defined a filename dequoting function AND
|
||||
we found a quote character AND
|
||||
the application has requested filename quoting
|
||||
THEN
|
||||
we assume that TEXT was dequoted before checking against
|
||||
the file system and needs to be dequoted here before we
|
||||
check against the list of matches
|
||||
FI */
|
||||
dtext = (char *)NULL;
|
||||
if (rl_filename_completion_desired &&
|
||||
rl_filename_dequoting_function &&
|
||||
rl_completion_found_quote &&
|
||||
rl_filename_quoting_desired)
|
||||
{
|
||||
dtext = (*rl_filename_dequoting_function) (text, rl_completion_quote_character);
|
||||
text = dtext;
|
||||
}
|
||||
|
||||
/* sort the list to get consistent answers. */
|
||||
qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare);
|
||||
|
||||
|
@ -999,6 +1174,8 @@ compute_lcd_of_matches (match_list, matches, text)
|
|||
else
|
||||
/* otherwise, just use the text the user typed. */
|
||||
strncpy (match_list[0], text, low);
|
||||
|
||||
FREE (dtext);
|
||||
}
|
||||
else
|
||||
strncpy (match_list[0], match_list[1], low);
|
||||
|
@ -1203,7 +1380,7 @@ display_matches (matches)
|
|||
for (max = 0, i = 1; matches[i]; i++)
|
||||
{
|
||||
temp = printable_part (matches[i]);
|
||||
len = strlen (temp);
|
||||
len = fnwidth (temp);
|
||||
|
||||
if (len > max)
|
||||
max = len;
|
||||
|
@ -1338,7 +1515,8 @@ append_to_match (text, delimiter, quote_char, nontrivial_match)
|
|||
struct stat finfo;
|
||||
|
||||
temp_string_index = 0;
|
||||
if (quote_char && rl_point && rl_line_buffer[rl_point - 1] != quote_char)
|
||||
if (quote_char && rl_point && rl_completion_suppress_quote == 0 &&
|
||||
rl_line_buffer[rl_point - 1] != quote_char)
|
||||
temp_string[temp_string_index++] = quote_char;
|
||||
|
||||
if (delimiter)
|
||||
|
@ -1449,7 +1627,9 @@ _rl_free_match_list (matches)
|
|||
TAB means do standard completion.
|
||||
`*' means insert all of the possible completions.
|
||||
`!' means to do standard completion, and list all possible completions if
|
||||
there is more than one. */
|
||||
there is more than one.
|
||||
`@' means to do standard completion, and list all possible completions if
|
||||
there is more than one and partial completion is not possible. */
|
||||
int
|
||||
rl_complete_internal (what_to_do)
|
||||
int what_to_do;
|
||||
|
@ -1468,7 +1648,6 @@ rl_complete_internal (what_to_do)
|
|||
our_func = rl_completion_entry_function
|
||||
? rl_completion_entry_function
|
||||
: rl_filename_completion_function;
|
||||
|
||||
/* We now look backwards for the start of a filename/variable word. */
|
||||
end = rl_point;
|
||||
found_quote = delimiter = 0;
|
||||
|
@ -1516,6 +1695,7 @@ rl_complete_internal (what_to_do)
|
|||
{
|
||||
case TAB:
|
||||
case '!':
|
||||
case '@':
|
||||
/* Insert the first match with proper quoting. */
|
||||
if (*matches[0])
|
||||
insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, "e_char);
|
||||
|
@ -1535,6 +1715,12 @@ rl_complete_internal (what_to_do)
|
|||
display_matches (matches);
|
||||
break;
|
||||
}
|
||||
else if (what_to_do == '@')
|
||||
{
|
||||
if (nontrivial_lcd == 0)
|
||||
display_matches (matches);
|
||||
break;
|
||||
}
|
||||
else if (rl_editing_mode != vi_mode)
|
||||
rl_ding (); /* There are other matches remaining. */
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* display.c -- readline redisplay facility. */
|
||||
|
||||
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
@ -70,7 +70,7 @@ static void insert_some_chars PARAMS((char *, int, int));
|
|||
static void cr PARAMS((void));
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
static int _rl_col_width PARAMS((char *, int, int));
|
||||
static int _rl_col_width PARAMS((const char *, int, int));
|
||||
static int *_rl_wrapped_line;
|
||||
#else
|
||||
# define _rl_col_width(l, s, e) (((e) <= (s)) ? 0 : (e) - (s))
|
||||
|
@ -178,12 +178,15 @@ static int prompt_invis_chars_first_line;
|
|||
|
||||
static int prompt_last_screen_line;
|
||||
|
||||
static int prompt_physical_chars;
|
||||
|
||||
/* Expand the prompt string S and return the number of visible
|
||||
characters in *LP, if LP is not null. This is currently more-or-less
|
||||
a placeholder for expansion. LIP, if non-null is a place to store the
|
||||
index of the last invisible character in the returned string. NIFLP,
|
||||
if non-zero, is a place to store the number of invisible characters in
|
||||
the first prompt line. */
|
||||
the first prompt line. The previous are used as byte counts -- indexes
|
||||
into a character buffer. */
|
||||
|
||||
/* Current implementation:
|
||||
\001 (^A) start non-visible characters
|
||||
|
@ -193,19 +196,25 @@ static int prompt_last_screen_line;
|
|||
\002 are assumed to be `visible'. */
|
||||
|
||||
static char *
|
||||
expand_prompt (pmt, lp, lip, niflp)
|
||||
expand_prompt (pmt, lp, lip, niflp, vlp)
|
||||
char *pmt;
|
||||
int *lp, *lip, *niflp;
|
||||
int *lp, *lip, *niflp, *vlp;
|
||||
{
|
||||
char *r, *ret, *p;
|
||||
int l, rl, last, ignoring, ninvis, invfl;
|
||||
int l, rl, last, ignoring, ninvis, invfl, ind, pind, physchars;
|
||||
|
||||
/* Short-circuit if we can. */
|
||||
if (strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
|
||||
if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
|
||||
{
|
||||
r = savestring (pmt);
|
||||
if (lp)
|
||||
*lp = strlen (r);
|
||||
if (lip)
|
||||
*lip = 0;
|
||||
if (niflp)
|
||||
*niflp = 0;
|
||||
if (vlp)
|
||||
*vlp = lp ? *lp : strlen (r);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -214,7 +223,7 @@ expand_prompt (pmt, lp, lip, niflp)
|
|||
|
||||
invfl = 0; /* invisible chars in first line of prompt */
|
||||
|
||||
for (rl = ignoring = last = ninvis = 0, p = pmt; p && *p; p++)
|
||||
for (rl = ignoring = last = ninvis = physchars = 0, p = pmt; p && *p; p++)
|
||||
{
|
||||
/* This code strips the invisible character string markers
|
||||
RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
|
||||
|
@ -231,13 +240,35 @@ expand_prompt (pmt, lp, lip, niflp)
|
|||
}
|
||||
else
|
||||
{
|
||||
*r++ = *p;
|
||||
if (!ignoring)
|
||||
rl++;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
pind = p - pmt;
|
||||
ind = _rl_find_next_mbchar (pmt, pind, 1, MB_FIND_NONZERO);
|
||||
l = ind - pind;
|
||||
while (l--)
|
||||
*r++ = *p++;
|
||||
if (!ignoring)
|
||||
rl += ind - pind;
|
||||
else
|
||||
ninvis += ind - pind;
|
||||
p--; /* compensate for later increment */
|
||||
}
|
||||
else
|
||||
ninvis++;
|
||||
if (rl == _rl_screenwidth)
|
||||
#endif
|
||||
{
|
||||
*r++ = *p;
|
||||
if (!ignoring)
|
||||
rl++; /* visible length byte counter */
|
||||
else
|
||||
ninvis++; /* invisible chars byte counter */
|
||||
}
|
||||
|
||||
if (rl >= _rl_screenwidth)
|
||||
invfl = ninvis;
|
||||
|
||||
if (ignoring == 0)
|
||||
physchars++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -251,6 +282,8 @@ expand_prompt (pmt, lp, lip, niflp)
|
|||
*lip = last;
|
||||
if (niflp)
|
||||
*niflp = invfl;
|
||||
if (vlp)
|
||||
*vlp = physchars;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -262,7 +295,7 @@ _rl_strip_prompt (pmt)
|
|||
{
|
||||
char *ret;
|
||||
|
||||
ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL);
|
||||
ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -306,7 +339,8 @@ rl_expand_prompt (prompt)
|
|||
/* The prompt is only one logical line, though it might wrap. */
|
||||
local_prompt = expand_prompt (prompt, &prompt_visible_length,
|
||||
&prompt_last_invisible,
|
||||
&prompt_invis_chars_first_line);
|
||||
&prompt_invis_chars_first_line,
|
||||
&prompt_physical_chars);
|
||||
local_prompt_prefix = (char *)0;
|
||||
return (prompt_visible_length);
|
||||
}
|
||||
|
@ -316,13 +350,15 @@ rl_expand_prompt (prompt)
|
|||
t = ++p;
|
||||
local_prompt = expand_prompt (p, &prompt_visible_length,
|
||||
&prompt_last_invisible,
|
||||
&prompt_invis_chars_first_line);
|
||||
(int *)NULL,
|
||||
(int *)NULL);
|
||||
c = *t; *t = '\0';
|
||||
/* The portion of the prompt string up to and including the
|
||||
final newline is now null-terminated. */
|
||||
local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
|
||||
(int *)NULL,
|
||||
&prompt_invis_chars_first_line);
|
||||
&prompt_invis_chars_first_line,
|
||||
&prompt_physical_chars);
|
||||
*t = c;
|
||||
return (prompt_prefix_length);
|
||||
}
|
||||
|
@ -381,7 +417,7 @@ rl_redisplay ()
|
|||
register int in, out, c, linenum, cursor_linenum;
|
||||
register char *line;
|
||||
int c_pos, inv_botlin, lb_botlin, lb_linenum;
|
||||
int newlines, lpos, temp;
|
||||
int newlines, lpos, temp, modmark;
|
||||
char *prompt_this_line;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
wchar_t wc;
|
||||
|
@ -411,10 +447,12 @@ rl_redisplay ()
|
|||
|
||||
/* Mark the line as modified or not. We only do this for history
|
||||
lines. */
|
||||
modmark = 0;
|
||||
if (_rl_mark_modified_lines && current_history () && rl_undo_list)
|
||||
{
|
||||
line[out++] = '*';
|
||||
line[out] = '\0';
|
||||
modmark = 1;
|
||||
}
|
||||
|
||||
/* If someone thought that the redisplay was handled, but the currently
|
||||
|
@ -468,7 +506,7 @@ rl_redisplay ()
|
|||
}
|
||||
}
|
||||
|
||||
pmtlen = strlen (prompt_this_line);
|
||||
prompt_physical_chars = pmtlen = strlen (prompt_this_line);
|
||||
temp = pmtlen + out + 2;
|
||||
if (temp >= line_size)
|
||||
{
|
||||
|
@ -527,7 +565,12 @@ rl_redisplay ()
|
|||
|
||||
/* inv_lbreaks[i] is where line i starts in the buffer. */
|
||||
inv_lbreaks[newlines = 0] = 0;
|
||||
#if 0
|
||||
lpos = out - wrap_offset;
|
||||
#else
|
||||
lpos = prompt_physical_chars + modmark;
|
||||
#endif
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
memset (_rl_wrapped_line, 0, vis_lbsize);
|
||||
#endif
|
||||
|
@ -546,15 +589,13 @@ rl_redisplay ()
|
|||
prompt_invis_chars_first_line variable could be made into an array
|
||||
saying how many invisible characters there are per line, but that's
|
||||
probably too much work for the benefit gained. How many people have
|
||||
prompts that exceed two physical lines? */
|
||||
prompts that exceed two physical lines?
|
||||
Additional logic fix from Edward Catmur <ed@catmur.co.uk> */
|
||||
temp = ((newlines + 1) * _rl_screenwidth) +
|
||||
#if 0
|
||||
((newlines == 0) ? prompt_invis_chars_first_line : 0) +
|
||||
#else
|
||||
((newlines == 0 && local_prompt_prefix == 0) ? prompt_invis_chars_first_line : 0) +
|
||||
#endif
|
||||
((newlines == 1) ? wrap_offset : 0);
|
||||
|
||||
((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line
|
||||
: ((newlines == 1) ? wrap_offset : 0))
|
||||
: ((newlines == 0) ? wrap_offset :0));
|
||||
|
||||
inv_lbreaks[++newlines] = temp;
|
||||
lpos -= _rl_screenwidth;
|
||||
}
|
||||
|
@ -586,7 +627,7 @@ rl_redisplay ()
|
|||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
if (wc_bytes == (size_t)-1 || wc_bytes == (size_t)-2)
|
||||
if (MB_INVALIDCH (wc_bytes))
|
||||
{
|
||||
/* Byte sequence is invalid or shortened. Assume that the
|
||||
first byte represents a character. */
|
||||
|
@ -595,12 +636,12 @@ rl_redisplay ()
|
|||
wc_width = 1;
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
}
|
||||
else if (wc_bytes == (size_t)0)
|
||||
else if (MB_NULLWCH (wc_bytes))
|
||||
break; /* Found '\0' */
|
||||
else
|
||||
{
|
||||
temp = wcwidth (wc);
|
||||
wc_width = (temp < 0) ? 1 : temp;
|
||||
wc_width = (temp >= 0) ? temp : 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -867,7 +908,7 @@ rl_redisplay ()
|
|||
#endif
|
||||
_rl_output_some_chars (local_prompt, nleft);
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
_rl_last_c_pos = _rl_col_width(local_prompt, 0, nleft);
|
||||
_rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft);
|
||||
else
|
||||
_rl_last_c_pos = nleft;
|
||||
}
|
||||
|
@ -1069,12 +1110,12 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
|||
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps);
|
||||
if (ret == (size_t)-1 || ret == (size_t)-2)
|
||||
if (MB_INVALIDCH (ret))
|
||||
{
|
||||
tempwidth = 1;
|
||||
ret = 1;
|
||||
}
|
||||
else if (ret == 0)
|
||||
else if (MB_NULLWCH (ret))
|
||||
tempwidth = 0;
|
||||
else
|
||||
tempwidth = wcwidth (wc);
|
||||
|
@ -1091,7 +1132,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
|||
ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps);
|
||||
if (ret != 0 && bytes != 0)
|
||||
{
|
||||
if (ret == (size_t)-1 || ret == (size_t)-2)
|
||||
if (MB_INVALIDCH (ret))
|
||||
memmove (old+bytes, old+1, strlen (old+1));
|
||||
else
|
||||
memmove (old+bytes, old+ret, strlen (old+ret));
|
||||
|
@ -1126,18 +1167,37 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
|||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
memset (&ps_new, 0, sizeof(mbstate_t));
|
||||
memset (&ps_old, 0, sizeof(mbstate_t));
|
||||
|
||||
new_offset = old_offset = 0;
|
||||
for (ofd = old, nfd = new;
|
||||
(ofd - old < omax) && *ofd &&
|
||||
_rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); )
|
||||
/* See if the old line is a subset of the new line, so that the
|
||||
only change is adding characters. */
|
||||
temp = (omax < nmax) ? omax : nmax;
|
||||
if (memcmp (old, new, temp) == 0)
|
||||
{
|
||||
old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY);
|
||||
new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY);
|
||||
ofd = old + old_offset;
|
||||
nfd = new + new_offset;
|
||||
ofd = old + temp;
|
||||
nfd = new + temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset (&ps_new, 0, sizeof(mbstate_t));
|
||||
memset (&ps_old, 0, sizeof(mbstate_t));
|
||||
|
||||
if (omax == nmax && STREQN (new, old, omax))
|
||||
{
|
||||
ofd = old + omax;
|
||||
nfd = new + nmax;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_offset = old_offset = 0;
|
||||
for (ofd = old, nfd = new;
|
||||
(ofd - old < omax) && *ofd &&
|
||||
_rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); )
|
||||
{
|
||||
old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY);
|
||||
new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY);
|
||||
ofd = old + old_offset;
|
||||
nfd = new + new_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1169,8 +1229,11 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
|||
memset (&ps_old, 0, sizeof (mbstate_t));
|
||||
memset (&ps_new, 0, sizeof (mbstate_t));
|
||||
|
||||
#if 0
|
||||
/* On advice from jir@yamato.ibm.com */
|
||||
_rl_adjust_point (old, ols - old, &ps_old);
|
||||
_rl_adjust_point (new, nls - new, &ps_new);
|
||||
#endif
|
||||
|
||||
if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0)
|
||||
break;
|
||||
|
@ -1324,7 +1387,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
|||
insert_some_chars (nfd, lendiff, col_lendiff);
|
||||
_rl_last_c_pos += col_lendiff;
|
||||
}
|
||||
else if (*ols == 0)
|
||||
else if (*ols == 0 && lendiff > 0)
|
||||
{
|
||||
/* At the end of a line the characters do not have to
|
||||
be "inserted". They can just be placed on the screen. */
|
||||
|
@ -1347,10 +1410,14 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
|||
if ((temp - lendiff) > 0)
|
||||
{
|
||||
_rl_output_some_chars (nfd + lendiff, temp - lendiff);
|
||||
#if 0
|
||||
_rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-lendiff) - col_lendiff;
|
||||
#else
|
||||
#if 1
|
||||
/* XXX -- this bears closer inspection. Fixes a redisplay bug
|
||||
reported against bash-3.0-alpha by Andreas Schwab involving
|
||||
multibyte characters and prompt strings with invisible
|
||||
characters, but was previously disabled. */
|
||||
_rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-col_lendiff);
|
||||
#else
|
||||
_rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-lendiff);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1426,12 +1493,13 @@ rl_on_new_line ()
|
|||
|
||||
/* Tell the update routines that we have moved onto a new line with the
|
||||
prompt already displayed. Code originally from the version of readline
|
||||
distributed with CLISP. */
|
||||
distributed with CLISP. rl_expand_prompt must have already been called
|
||||
(explicitly or implicitly). This still doesn't work exactly right. */
|
||||
int
|
||||
rl_on_new_line_with_prompt ()
|
||||
{
|
||||
int prompt_size, i, l, real_screenwidth, newlines;
|
||||
char *prompt_last_line;
|
||||
char *prompt_last_line, *lprompt;
|
||||
|
||||
/* Initialize visible_line and invisible_line to ensure that they can hold
|
||||
the already-displayed prompt. */
|
||||
|
@ -1440,8 +1508,9 @@ rl_on_new_line_with_prompt ()
|
|||
|
||||
/* Make sure the line structures hold the already-displayed prompt for
|
||||
redisplay. */
|
||||
strcpy (visible_line, rl_prompt);
|
||||
strcpy (invisible_line, rl_prompt);
|
||||
lprompt = local_prompt ? local_prompt : rl_prompt;
|
||||
strcpy (visible_line, lprompt);
|
||||
strcpy (invisible_line, lprompt);
|
||||
|
||||
/* If the prompt contains newlines, take the last tail. */
|
||||
prompt_last_line = strrchr (rl_prompt, '\n');
|
||||
|
@ -1476,6 +1545,8 @@ rl_on_new_line_with_prompt ()
|
|||
vis_lbreaks[newlines] = l;
|
||||
visible_wrap_offset = 0;
|
||||
|
||||
rl_display_prompt = rl_prompt; /* XXX - make sure it's set */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1510,8 +1581,15 @@ _rl_move_cursor_relative (new, data)
|
|||
#if defined (HANDLE_MULTIBYTE)
|
||||
/* If we have multibyte characters, NEW is indexed by the buffer point in
|
||||
a multibyte string, but _rl_last_c_pos is the display position. In
|
||||
this case, NEW's display position is not obvious. */
|
||||
if ((MB_CUR_MAX == 1 || rl_byte_oriented ) && _rl_last_c_pos == new) return;
|
||||
this case, NEW's display position is not obvious and must be
|
||||
calculated. */
|
||||
if (MB_CUR_MAX == 1 || rl_byte_oriented)
|
||||
{
|
||||
if (_rl_last_c_pos == new)
|
||||
return;
|
||||
}
|
||||
else if (_rl_last_c_pos == _rl_col_width (data, 0, new))
|
||||
return;
|
||||
#else
|
||||
if (_rl_last_c_pos == new) return;
|
||||
#endif
|
||||
|
@ -1594,11 +1672,7 @@ _rl_move_cursor_relative (new, data)
|
|||
#endif
|
||||
{
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
tputs (_rl_term_cr, 1, _rl_output_character_function);
|
||||
for (i = 0; i < new; i++)
|
||||
putc (data[i], rl_outstream);
|
||||
}
|
||||
_rl_backspace (_rl_last_c_pos - _rl_col_width (data, 0, new));
|
||||
else
|
||||
_rl_backspace (_rl_last_c_pos - new);
|
||||
}
|
||||
|
@ -1764,10 +1838,14 @@ rl_reset_line_state ()
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* These are getting numerous enough that it's time to create a struct. */
|
||||
|
||||
static char *saved_local_prompt;
|
||||
static char *saved_local_prefix;
|
||||
static int saved_last_invisible;
|
||||
static int saved_visible_length;
|
||||
static int saved_invis_chars_first_line;
|
||||
static int saved_physical_chars;
|
||||
|
||||
void
|
||||
rl_save_prompt ()
|
||||
|
@ -1776,9 +1854,12 @@ rl_save_prompt ()
|
|||
saved_local_prefix = local_prompt_prefix;
|
||||
saved_last_invisible = prompt_last_invisible;
|
||||
saved_visible_length = prompt_visible_length;
|
||||
saved_invis_chars_first_line = prompt_invis_chars_first_line;
|
||||
saved_physical_chars = prompt_physical_chars;
|
||||
|
||||
local_prompt = local_prompt_prefix = (char *)0;
|
||||
prompt_last_invisible = prompt_visible_length = 0;
|
||||
prompt_invis_chars_first_line = prompt_physical_chars = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1791,6 +1872,8 @@ rl_restore_prompt ()
|
|||
local_prompt_prefix = saved_local_prefix;
|
||||
prompt_last_invisible = saved_last_invisible;
|
||||
prompt_visible_length = saved_visible_length;
|
||||
prompt_invis_chars_first_line = saved_invis_chars_first_line;
|
||||
prompt_physical_chars = saved_physical_chars;
|
||||
}
|
||||
|
||||
char *
|
||||
|
@ -1823,6 +1906,7 @@ _rl_make_prompt_for_search (pchar)
|
|||
prompt_last_invisible = saved_last_invisible;
|
||||
prompt_visible_length = saved_visible_length + 1;
|
||||
}
|
||||
|
||||
return pmt;
|
||||
}
|
||||
|
||||
|
@ -1999,7 +2083,7 @@ redraw_prompt (t)
|
|||
char *t;
|
||||
{
|
||||
char *oldp, *oldl, *oldlprefix;
|
||||
int oldlen, oldlast, oldplen, oldninvis;
|
||||
int oldlen, oldlast, oldplen, oldninvis, oldphyschars;
|
||||
|
||||
/* Geez, I should make this a struct. */
|
||||
oldp = rl_display_prompt;
|
||||
|
@ -2009,11 +2093,13 @@ redraw_prompt (t)
|
|||
oldplen = prompt_prefix_length;
|
||||
oldlast = prompt_last_invisible;
|
||||
oldninvis = prompt_invis_chars_first_line;
|
||||
oldphyschars = prompt_physical_chars;
|
||||
|
||||
rl_display_prompt = t;
|
||||
local_prompt = expand_prompt (t, &prompt_visible_length,
|
||||
&prompt_last_invisible,
|
||||
&prompt_invis_chars_first_line);
|
||||
&prompt_invis_chars_first_line,
|
||||
&prompt_physical_chars);
|
||||
local_prompt_prefix = (char *)NULL;
|
||||
rl_forced_update_display ();
|
||||
|
||||
|
@ -2024,6 +2110,7 @@ redraw_prompt (t)
|
|||
prompt_prefix_length = oldplen;
|
||||
prompt_last_invisible = oldlast;
|
||||
prompt_invis_chars_first_line = oldninvis;
|
||||
prompt_physical_chars = oldphyschars;
|
||||
}
|
||||
|
||||
/* Redisplay the current line after a SIGWINCH is received. */
|
||||
|
@ -2117,7 +2204,7 @@ _rl_current_display_line ()
|
|||
scan from the beginning of the string to take the state into account. */
|
||||
static int
|
||||
_rl_col_width (str, start, end)
|
||||
char *str;
|
||||
const char *str;
|
||||
int start, end;
|
||||
{
|
||||
wchar_t wc;
|
||||
|
@ -2133,7 +2220,7 @@ _rl_col_width (str, start, end)
|
|||
while (point < start)
|
||||
{
|
||||
tmp = mbrlen (str + point, max, &ps);
|
||||
if ((size_t)tmp == (size_t)-1 || (size_t)tmp == (size_t)-2)
|
||||
if (MB_INVALIDCH ((size_t)tmp))
|
||||
{
|
||||
/* In this case, the bytes are invalid or too short to compose a
|
||||
multibyte character, so we assume that the first byte represents
|
||||
|
@ -2145,8 +2232,8 @@ _rl_col_width (str, start, end)
|
|||
effect of mbstate is undefined. */
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
}
|
||||
else if (tmp == 0)
|
||||
break; /* Found '\0' */
|
||||
else if (MB_NULLWCH (tmp))
|
||||
break; /* Found '\0' */
|
||||
else
|
||||
{
|
||||
point += tmp;
|
||||
|
@ -2162,7 +2249,7 @@ _rl_col_width (str, start, end)
|
|||
while (point < end)
|
||||
{
|
||||
tmp = mbrtowc (&wc, str + point, max, &ps);
|
||||
if ((size_t)tmp == (size_t)-1 || (size_t)tmp == (size_t)-2)
|
||||
if (MB_INVALIDCH ((size_t)tmp))
|
||||
{
|
||||
/* In this case, the bytes are invalid or too short to compose a
|
||||
multibyte character, so we assume that the first byte represents
|
||||
|
@ -2177,8 +2264,8 @@ _rl_col_width (str, start, end)
|
|||
effect of mbstate is undefined. */
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
}
|
||||
else if (tmp == 0)
|
||||
break; /* Found '\0' */
|
||||
else if (MB_NULLWCH (tmp))
|
||||
break; /* Found '\0' */
|
||||
else
|
||||
{
|
||||
point += tmp;
|
||||
|
@ -2193,4 +2280,3 @@ _rl_col_width (str, start, end)
|
|||
return width;
|
||||
}
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
|
||||
|
|
|
@ -49,11 +49,11 @@ QUIETPS = #set this to -q to shut up dvips
|
|||
PSDPI = 300 # I don't have any 600-dpi printers
|
||||
DVIPS = dvips -D ${PSDPI} $(QUIETPS) -o $@ # tricky
|
||||
|
||||
RLSRC = $(srcdir)/rlman.texinfo $(srcdir)/rluser.texinfo \
|
||||
$(srcdir)/rltech.texinfo $(srcdir)/manvers.texinfo \
|
||||
$(srcdir)/rluserman.texinfo
|
||||
HISTSRC = $(srcdir)/hist.texinfo $(srcdir)/hsuser.texinfo \
|
||||
$(srcdir)/hstech.texinfo $(srcdir)/manvers.texinfo
|
||||
RLSRC = $(srcdir)/rlman.texi $(srcdir)/rluser.texi \
|
||||
$(srcdir)/rltech.texi $(srcdir)/version.texi \
|
||||
$(srcdir)/rluserman.texi
|
||||
HISTSRC = $(srcdir)/history.texi $(srcdir)/hsuser.texi \
|
||||
$(srcdir)/hstech.texi $(srcdir)/version.texi
|
||||
|
||||
# This should be a program that converts troff to an ascii-readable format
|
||||
NROFF = groff -Tascii
|
||||
|
@ -66,7 +66,7 @@ INFOOBJ = readline.info history.info rluserman.info
|
|||
PSOBJ = readline.ps history.ps rluserman.ps
|
||||
HTMLOBJ = readline.html history.html rluserman.html
|
||||
|
||||
INTERMEDIATE_OBJ = rlman.dvi hist.dvi rluserman.dvi
|
||||
INTERMEDIATE_OBJ = rlman.dvi
|
||||
|
||||
CREATED_DOCS = $(DVIOBJ) $(INFOOBJ) $(PSOBJ) $(HTMLOBJ)
|
||||
|
||||
|
@ -76,24 +76,23 @@ all: info dvi html ps
|
|||
nodvi: info html
|
||||
|
||||
readline.dvi: $(RLSRC)
|
||||
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/rlman.texinfo
|
||||
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/rlman.texi
|
||||
mv rlman.dvi readline.dvi
|
||||
|
||||
readline.info: $(RLSRC)
|
||||
$(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/rlman.texinfo
|
||||
$(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/rlman.texi
|
||||
|
||||
rluserman.dvi: $(RLSRC)
|
||||
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/rluserman.texinfo
|
||||
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/rluserman.texi
|
||||
|
||||
rluserman.info: $(RLSRC)
|
||||
$(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/rluserman.texinfo
|
||||
$(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/rluserman.texi
|
||||
|
||||
history.dvi: ${HISTSRC}
|
||||
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/hist.texinfo
|
||||
mv hist.dvi history.dvi
|
||||
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/history.texi
|
||||
|
||||
history.info: ${HISTSRC}
|
||||
$(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/hist.texinfo
|
||||
$(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/history.texi
|
||||
|
||||
readline.ps: readline.dvi
|
||||
$(RM) $@
|
||||
|
@ -108,17 +107,15 @@ history.ps: history.dvi
|
|||
$(DVIPS) history.dvi
|
||||
|
||||
readline.html: ${RLSRC}
|
||||
$(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/rlman.texinfo
|
||||
$(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/rlman.texi
|
||||
sed -e 's:rlman.html:readline.html:' rlman.html > readline.html
|
||||
$(RM) rlman.html
|
||||
|
||||
rluserman.html: ${RLSRC}
|
||||
$(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/rluserman.texinfo
|
||||
$(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/rluserman.texi
|
||||
|
||||
history.html: ${HISTSRC}
|
||||
$(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/hist.texinfo
|
||||
sed -e 's:hist.html:history.html:' hist.html > history.html
|
||||
$(RM) hist.html
|
||||
$(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/history.texi
|
||||
|
||||
info: $(INFOOBJ)
|
||||
dvi: $(DVIOBJ)
|
||||
|
|
452
lib/readline/doc/fdl.texi
Normal file
452
lib/readline/doc/fdl.texi
Normal file
|
@ -0,0 +1,452 @@
|
|||
|
||||
@node GNU Free Documentation License
|
||||
@appendixsec GNU Free Documentation License
|
||||
|
||||
@cindex FDL, GNU Free Documentation License
|
||||
@center Version 1.2, November 2002
|
||||
|
||||
@display
|
||||
Copyright @copyright{} 2000,2001,2002 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||
|
||||
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
|
||||
@sc{ascii} without markup, Texinfo input format, La@TeX{} input
|
||||
format, @acronym{SGML} or @acronym{XML} using a publicly available
|
||||
@acronym{DTD}, and standard-conforming simple @acronym{HTML},
|
||||
PostScript or @acronym{PDF} designed for human modification. Examples
|
||||
of transparent image formats include @acronym{PNG}, @acronym{XCF} and
|
||||
@acronym{JPG}. Opaque formats include proprietary formats that can be
|
||||
read and edited only by proprietary word processors, @acronym{SGML} or
|
||||
@acronym{XML} for which the @acronym{DTD} and/or processing tools are
|
||||
not generally available, and the machine-generated @acronym{HTML},
|
||||
PostScript or @acronym{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.
|
||||
|
||||
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 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 for under this License. Any other attempt to
|
||||
copy, modify, sublicense or distribute the Document is void, and will
|
||||
automatically terminate your rights under this License. However,
|
||||
parties who have received copies, or rights, from you under this
|
||||
License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
@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.
|
||||
@end enumerate
|
||||
|
||||
@page
|
||||
@appendixsubsec 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.2
|
||||
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...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:
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
\input texinfo @c -*-texinfo-*-
|
||||
@c %**start of header (This is for running Texinfo on a region.)
|
||||
@setfilename history.info
|
||||
@settitle GNU History Library
|
||||
@c %**end of header (This is for running Texinfo on a region.)
|
||||
|
||||
@setchapternewpage odd
|
||||
|
||||
@include manvers.texinfo
|
||||
|
||||
@ifinfo
|
||||
@dircategory Libraries
|
||||
@direntry
|
||||
* History: (history). The GNU history library API
|
||||
@end direntry
|
||||
|
||||
This document describes the GNU History library, a programming tool that
|
||||
provides a consistent user interface for recalling lines of previously
|
||||
typed input.
|
||||
|
||||
Copyright (C) 1988-2002 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
pare preserved on all copies.
|
||||
|
||||
@ignore
|
||||
Permission is granted to process this file through TeX and print the
|
||||
results, provided the printed document carries copying permission
|
||||
notice identical to this one except for the removal of this paragraph
|
||||
(this paragraph not being relevant to the printed manual).
|
||||
@end ignore
|
||||
|
||||
Permission is granted to copy and distribute modified versions of this
|
||||
manual under the conditions for verbatim copying, provided that the entire
|
||||
resulting derived work is distributed under the terms of a permission
|
||||
notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this manual
|
||||
into another language, under the above conditions for modified versions,
|
||||
except that this permission notice may be stated in a translation approved
|
||||
by the Free Software Foundation.
|
||||
@end ifinfo
|
||||
|
||||
@titlepage
|
||||
@title GNU History Library
|
||||
@subtitle Edition @value{EDITION}, for @code{History Library} Version @value{VERSION}.
|
||||
@subtitle @value{UPDATE-MONTH}
|
||||
@author Brian Fox, Free Software Foundation
|
||||
@author Chet Ramey, Case Western Reserve University
|
||||
|
||||
@page
|
||||
This document describes the GNU History library, a programming tool that
|
||||
provides a consistent user interface for recalling lines of previously
|
||||
typed input.
|
||||
|
||||
Published by the Free Software Foundation @*
|
||||
59 Temple Place, Suite 330, @*
|
||||
Boston, MA 02111 USA
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
are preserved on all copies.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of this
|
||||
manual under the conditions for verbatim copying, provided that the entire
|
||||
resulting derived work is distributed under the terms of a permission
|
||||
notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this manual
|
||||
into another language, under the above conditions for modified versions,
|
||||
except that this permission notice may be stated in a translation approved
|
||||
by the Free Software Foundation.
|
||||
|
||||
@vskip 0pt plus 1filll
|
||||
Copyright @copyright{} 1988-2002 Free Software Foundation, Inc.
|
||||
@end titlepage
|
||||
|
||||
@ifinfo
|
||||
@node Top
|
||||
@top GNU History Library
|
||||
|
||||
This document describes the GNU History library, a programming tool that
|
||||
provides a consistent user interface for recalling lines of previously
|
||||
typed input.
|
||||
|
||||
@menu
|
||||
* Using History Interactively:: GNU History User's Manual.
|
||||
* Programming with GNU History:: GNU History Programmer's Manual.
|
||||
* Concept Index:: Index of concepts described in this manual.
|
||||
* Function and Variable Index:: Index of externally visible functions
|
||||
and variables.
|
||||
@end menu
|
||||
@end ifinfo
|
||||
|
||||
@syncodeindex fn vr
|
||||
|
||||
@include hsuser.texinfo
|
||||
@include hstech.texinfo
|
||||
|
||||
@node Concept Index
|
||||
@appendix Concept Index
|
||||
@printindex cp
|
||||
|
||||
@node Function and Variable Index
|
||||
@appendix Function and Variable Index
|
||||
@printindex vr
|
||||
|
||||
@contents
|
||||
@bye
|
104
lib/readline/doc/history.texi
Normal file
104
lib/readline/doc/history.texi
Normal file
|
@ -0,0 +1,104 @@
|
|||
\input texinfo @c -*-texinfo-*-
|
||||
@c %**start of header (This is for running Texinfo on a region.)
|
||||
@setfilename history.info
|
||||
@settitle GNU History Library
|
||||
@c %**end of header (This is for running Texinfo on a region.)
|
||||
|
||||
@setchapternewpage odd
|
||||
|
||||
@include version.texi
|
||||
|
||||
@copying
|
||||
This document describes the GNU History library
|
||||
(version @value{VERSION}, @value{UPDATED}),
|
||||
a programming tool that provides a consistent user interface for
|
||||
recalling lines of previously typed input.
|
||||
|
||||
Copyright @copyright{} 1988-2004 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
are preserved on all copies.
|
||||
|
||||
@quotation
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.1 or
|
||||
any later version published by the Free Software Foundation; with no
|
||||
Invariant Sections, with the Front-Cover texts being ``A GNU Manual,''
|
||||
and with the Back-Cover Texts as in (a) below. A copy of the license is
|
||||
included in the section entitled ``GNU Free Documentation License.''
|
||||
|
||||
(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
|
||||
this GNU Manual, like GNU software. Copies published by the Free
|
||||
Software Foundation raise funds for GNU development.''
|
||||
@end quotation
|
||||
@end copying
|
||||
|
||||
@dircategory Libraries
|
||||
@direntry
|
||||
* History: (history). The GNU history library API.
|
||||
@end direntry
|
||||
|
||||
@titlepage
|
||||
@title GNU History Library
|
||||
@subtitle Edition @value{EDITION}, for @code{History Library} Version @value{VERSION}.
|
||||
@subtitle @value{UPDATED-MONTH}
|
||||
@author Chet Ramey, Case Western Reserve University
|
||||
@author Brian Fox, Free Software Foundation
|
||||
|
||||
@page
|
||||
|
||||
@vskip 0pt plus 1filll
|
||||
@insertcopying
|
||||
|
||||
@sp 1
|
||||
Published by the Free Software Foundation @*
|
||||
59 Temple Place, Suite 330, @*
|
||||
Boston, MA 02111-1307 @*
|
||||
USA @*
|
||||
|
||||
@end titlepage
|
||||
|
||||
@contents
|
||||
|
||||
@ifnottex
|
||||
@node Top
|
||||
@top GNU History Library
|
||||
|
||||
This document describes the GNU History library, a programming tool that
|
||||
provides a consistent user interface for recalling lines of previously
|
||||
typed input.
|
||||
|
||||
@menu
|
||||
* Using History Interactively:: GNU History User's Manual.
|
||||
* Programming with GNU History:: GNU History Programmer's Manual.
|
||||
* Copying This Manual:: Copying This Manual.
|
||||
* Concept Index:: Index of concepts described in this manual.
|
||||
* Function and Variable Index:: Index of externally visible functions
|
||||
and variables.
|
||||
@end menu
|
||||
@end ifnottex
|
||||
|
||||
@syncodeindex fn vr
|
||||
|
||||
@include hsuser.texi
|
||||
@include hstech.texi
|
||||
|
||||
@node Copying This Manual
|
||||
@appendix Copying This Manual
|
||||
|
||||
@menu
|
||||
* GNU Free Documentation License:: License for copying this manual.
|
||||
@end menu
|
||||
|
||||
@include fdl.texi
|
||||
|
||||
@node Concept Index
|
||||
@appendix Concept Index
|
||||
@printindex cp
|
||||
|
||||
@node Function and Variable Index
|
||||
@appendix Function and Variable Index
|
||||
@printindex vr
|
||||
|
||||
@bye
|
|
@ -84,6 +84,7 @@ typedef void *histdata_t;
|
|||
|
||||
typedef struct _hist_entry @{
|
||||
char *line;
|
||||
char *timestamp;
|
||||
histdata_t data;
|
||||
@} HIST_ENTRY;
|
||||
@end example
|
||||
|
@ -167,15 +168,27 @@ Place @var{string} at the end of the history list. The associated data
|
|||
field (if any) is set to @code{NULL}.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun void add_history_time (const char *string)
|
||||
Change the time stamp associated with the most recent history entry to
|
||||
@var{string}.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun {HIST_ENTRY *} remove_history (int which)
|
||||
Remove history entry at offset @var{which} from the history. The
|
||||
removed element is returned so you can free the line, data,
|
||||
and containing structure.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun {histdata_t} free_history_entry (HIST_ENTRY *histent)
|
||||
Free the history entry @var{histent} and any history library private
|
||||
data associated with it. Returns the application-specific data
|
||||
so the caller can dispose of it.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun {HIST_ENTRY *} replace_history_entry (int which, const char *line, histdata_t data)
|
||||
Make the history entry at offset @var{which} have @var{line} and @var{data}.
|
||||
This returns the old entry so you can dispose of the data. In the case
|
||||
This returns the old entry so the caller can dispose of any
|
||||
application-specific data. In the case
|
||||
of an invalid @var{which}, a @code{NULL} pointer is returned.
|
||||
@end deftypefun
|
||||
|
||||
|
@ -227,6 +240,10 @@ If there is no entry there, or if @var{offset}
|
|||
is greater than the history length, return a @code{NULL} pointer.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun time_t history_get_time (HIST_ENTRY *entry)
|
||||
Return the time stamp associated with the history entry @var{entry}.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int history_total_bytes (void)
|
||||
Return the number of bytes that the primary history entries are using.
|
||||
This function returns the sum of the lengths of all the lines in the
|
||||
|
@ -405,6 +422,12 @@ The maximum number of history entries. This must be changed using
|
|||
@code{stifle_history()}.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar int history_write_timestamps
|
||||
If non-zero, timestamps are written to the history file, so they can be
|
||||
preserved between sessions. The default value is 0, meaning that
|
||||
timestamps are not saved.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar char history_expansion_char
|
||||
The character that introduces a history event. The default is @samp{!}.
|
||||
Setting this to 0 inhibits history expansion.
|
||||
|
@ -427,18 +450,18 @@ The characters that separate tokens for @code{history_tokenize()}.
|
|||
The default value is @code{" \t\n()<>;&|"}.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {char *} history_no_expand_chars
|
||||
The list of characters which inhibit history expansion if found immediately
|
||||
following @var{history_expansion_char}. The default is space, tab, newline,
|
||||
carriage return, and @samp{=}.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {char *} history_search_delimiter_chars
|
||||
The list of additional characters which can delimit a history search
|
||||
string, in addition to space, TAB, @samp{:} and @samp{?} in the case of
|
||||
a substring search. The default is empty.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {char *} history_no_expand_chars
|
||||
The list of characters which inhibit history expansion if found immediately
|
||||
following @var{history_expansion_char}. The default is space, tab, newline,
|
||||
carriage return, and @samp{=}.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar int history_quotes_inhibit_expansion
|
||||
If non-zero, single-quoted words are not scanned for the history expansion
|
||||
character. The default value is 0.
|
|
@ -96,6 +96,9 @@ not saved. After saving the history, the history file is truncated
|
|||
to contain no more than @env{$HISTFILESIZE}
|
||||
lines. If @env{HISTFILESIZE} is not set, no truncation is performed.
|
||||
|
||||
If the @env{HISTTIMEFORMAT} is set, the time stamp information
|
||||
associated with each history entry is written to the history file.
|
||||
|
||||
The builtin command @code{fc} may be used to list or edit and re-execute
|
||||
a portion of the history list.
|
||||
The @code{history} builtin may be used to display or modify the history
|
||||
|
@ -172,6 +175,12 @@ history -ps @var{arg}
|
|||
With no options, display the history list with line numbers.
|
||||
Lines prefixed with a @samp{*} have been modified.
|
||||
An argument of @var{n} lists only the last @var{n} lines.
|
||||
If the shell variable @env{HISTTIMEFORMAT} is set and not null,
|
||||
it is used as a format string for @var{strftime} to display
|
||||
the time stamp associated with each displayed history entry.
|
||||
No intervening blank is printed between the formatted time stamp
|
||||
and the history line.
|
||||
|
||||
Options, if supplied, have the following meanings:
|
||||
|
||||
@table @code
|
||||
|
@ -288,8 +297,15 @@ history list.
|
|||
@table @asis
|
||||
|
||||
@item @code{!}
|
||||
@ifset BashFeatures
|
||||
Start a history substitution, except when followed by a space, tab,
|
||||
the end of the line, @samp{=} or @samp{(}.
|
||||
the end of the line, @samp{=} or @samp{(} (when the
|
||||
@code{extglob} shell option is enabled using the @code{shopt} builtin).
|
||||
@end ifset
|
||||
@ifclear BashFeatures
|
||||
Start a history substitution, except when followed by a space, tab,
|
||||
the end of the line, or @samp{=}.
|
||||
@end ifclear
|
||||
|
||||
@item @code{!@var{n}}
|
||||
Refer to command line @var{n}.
|
||||
|
@ -430,8 +446,12 @@ character on the input line.
|
|||
Repeat the previous substitution.
|
||||
|
||||
@item g
|
||||
@itemx a
|
||||
Cause changes to be applied over the entire event line. Used in
|
||||
conjunction with @samp{s}, as in @code{gs/@var{old}/@var{new}/},
|
||||
or with @samp{&}.
|
||||
|
||||
@item G
|
||||
Apply the following @samp{s} modifier once to each word in the event.
|
||||
|
||||
@end table
|
|
@ -1,10 +0,0 @@
|
|||
@ignore
|
||||
Copyright (C) 1988-2002 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set EDITION 4.3
|
||||
@set VERSION 4.3
|
||||
@set UPDATED 2002 March 4
|
||||
@set UPDATE-MONTH March 2002
|
||||
|
||||
@set LASTCHANGE Mon Mar 4 12:00:16 EST 2002
|
101
lib/readline/doc/rlman.texi
Normal file
101
lib/readline/doc/rlman.texi
Normal file
|
@ -0,0 +1,101 @@
|
|||
\input texinfo @c -*-texinfo-*-
|
||||
@comment %**start of header (This is for running Texinfo on a region.)
|
||||
@setfilename readline.info
|
||||
@settitle GNU Readline Library
|
||||
@comment %**end of header (This is for running Texinfo on a region.)
|
||||
@synindex vr fn
|
||||
@setchapternewpage odd
|
||||
|
||||
@include version.texi
|
||||
|
||||
@copying
|
||||
This manual describes the GNU Readline Library
|
||||
(version @value{VERSION}, @value{UPDATED}), a library which aids in the
|
||||
consistency of user interface across discrete programs which provide
|
||||
a command line interface.
|
||||
|
||||
Copyright @copyright{} 1988-2004 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
are preserved on all copies.
|
||||
|
||||
@quotation
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.1 or
|
||||
any later version published by the Free Software Foundation; with no
|
||||
Invariant Sections, with the Front-Cover texts being ``A GNU Manual,''
|
||||
and with the Back-Cover Texts as in (a) below. A copy of the license is
|
||||
included in the section entitled ``GNU Free Documentation License.''
|
||||
|
||||
(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
|
||||
this GNU Manual, like GNU software. Copies published by the Free
|
||||
Software Foundation raise funds for GNU development.''
|
||||
@end quotation
|
||||
@end copying
|
||||
|
||||
@dircategory Libraries
|
||||
@direntry
|
||||
* Readline: (readline). The GNU readline library API.
|
||||
@end direntry
|
||||
|
||||
@titlepage
|
||||
@title GNU Readline Library
|
||||
@subtitle Edition @value{EDITION}, for @code{Readline Library} Version @value{VERSION}.
|
||||
@subtitle @value{UPDATED-MONTH}
|
||||
@author Chet Ramey, Case Western Reserve University
|
||||
@author Brian Fox, Free Software Foundation
|
||||
|
||||
@page
|
||||
@vskip 0pt plus 1filll
|
||||
@insertcopying
|
||||
|
||||
@sp 1
|
||||
Published by the Free Software Foundation @*
|
||||
59 Temple Place, Suite 330, @*
|
||||
Boston, MA 02111-1307 @*
|
||||
USA @*
|
||||
|
||||
@end titlepage
|
||||
|
||||
@contents
|
||||
|
||||
@ifnottex
|
||||
@node Top
|
||||
@top GNU Readline Library
|
||||
|
||||
This document describes the GNU Readline Library, a utility which aids
|
||||
in the consistency of user interface across discrete programs which
|
||||
provide a command line interface.
|
||||
|
||||
@menu
|
||||
* Command Line Editing:: GNU Readline User's Manual.
|
||||
* Programming with GNU Readline:: GNU Readline Programmer's Manual.
|
||||
* Copying This Manual:: Copying this manual.
|
||||
* Concept Index:: Index of concepts described in this manual.
|
||||
* Function and Variable Index:: Index of externally visible functions
|
||||
and variables.
|
||||
@end menu
|
||||
@end ifnottex
|
||||
|
||||
@include rluser.texi
|
||||
@include rltech.texi
|
||||
|
||||
@node Copying This Manual
|
||||
@appendix Copying This Manual
|
||||
|
||||
@menu
|
||||
* GNU Free Documentation License:: License for copying this manual.
|
||||
@end menu
|
||||
|
||||
@include fdl.texi
|
||||
|
||||
@node Concept Index
|
||||
@unnumbered Concept Index
|
||||
@printindex cp
|
||||
|
||||
@node Function and Variable Index
|
||||
@unnumbered Function and Variable Index
|
||||
@printindex fn
|
||||
|
||||
@bye
|
|
@ -1,108 +0,0 @@
|
|||
\input texinfo @c -*-texinfo-*-
|
||||
@comment %**start of header (This is for running Texinfo on a region.)
|
||||
@setfilename readline.info
|
||||
@settitle GNU Readline Library
|
||||
@comment %**end of header (This is for running Texinfo on a region.)
|
||||
@synindex vr fn
|
||||
@setchapternewpage odd
|
||||
|
||||
@include manvers.texinfo
|
||||
|
||||
@ifinfo
|
||||
@dircategory Libraries
|
||||
@direntry
|
||||
* Readline: (readline). The GNU readline library API
|
||||
@end direntry
|
||||
|
||||
This document describes the GNU Readline Library, a utility which aids
|
||||
in the consistency of user interface across discrete programs that need
|
||||
to provide a command line interface.
|
||||
|
||||
Copyright (C) 1988-2002 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
pare preserved on all copies.
|
||||
|
||||
@ignore
|
||||
Permission is granted to process this file through TeX and print the
|
||||
results, provided the printed document carries copying permission
|
||||
notice identical to this one except for the removal of this paragraph
|
||||
(this paragraph not being relevant to the printed manual).
|
||||
@end ignore
|
||||
|
||||
Permission is granted to copy and distribute modified versions of this
|
||||
manual under the conditions for verbatim copying, provided that the entire
|
||||
resulting derived work is distributed under the terms of a permission
|
||||
notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this manual
|
||||
into another language, under the above conditions for modified versions,
|
||||
except that this permission notice may be stated in a translation approved
|
||||
by the Free Software Foundation.
|
||||
@end ifinfo
|
||||
|
||||
@titlepage
|
||||
@title GNU Readline Library
|
||||
@subtitle Edition @value{EDITION}, for @code{Readline Library} Version @value{VERSION}.
|
||||
@subtitle @value{UPDATE-MONTH}
|
||||
@author Brian Fox, Free Software Foundation
|
||||
@author Chet Ramey, Case Western Reserve University
|
||||
|
||||
@page
|
||||
This document describes the GNU Readline Library, a utility which aids
|
||||
in the consistency of user interface across discrete programs that need
|
||||
to provide a command line interface.
|
||||
|
||||
Published by the Free Software Foundation @*
|
||||
59 Temple Place, Suite 330, @*
|
||||
Boston, MA 02111 USA
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
are preserved on all copies.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of this
|
||||
manual under the conditions for verbatim copying, provided that the entire
|
||||
resulting derived work is distributed under the terms of a permission
|
||||
notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this manual
|
||||
into another language, under the above conditions for modified versions,
|
||||
except that this permission notice may be stated in a translation approved
|
||||
by the Free Software Foundation.
|
||||
|
||||
@vskip 0pt plus 1filll
|
||||
Copyright @copyright{} 1988-2002 Free Software Foundation, Inc.
|
||||
@end titlepage
|
||||
|
||||
@ifinfo
|
||||
@node Top
|
||||
@top GNU Readline Library
|
||||
|
||||
This document describes the GNU Readline Library, a utility which aids
|
||||
in the consistency of user interface across discrete programs that need
|
||||
to provide a command line interface.
|
||||
|
||||
@menu
|
||||
* Command Line Editing:: GNU Readline User's Manual.
|
||||
* Programming with GNU Readline:: GNU Readline Programmer's Manual.
|
||||
* Concept Index:: Index of concepts described in this manual.
|
||||
* Function and Variable Index:: Index of externally visible functions
|
||||
and variables.
|
||||
@end menu
|
||||
@end ifinfo
|
||||
|
||||
@include rluser.texinfo
|
||||
@include rltech.texinfo
|
||||
|
||||
@node Concept Index
|
||||
@unnumbered Concept Index
|
||||
@printindex cp
|
||||
|
||||
@node Function and Variable Index
|
||||
@unnumbered Function and Variable Index
|
||||
@printindex fn
|
||||
|
||||
@contents
|
||||
@bye
|
|
@ -8,7 +8,7 @@ This document describes the GNU Readline Library, a utility for aiding
|
|||
in the consitency of user interface across discrete programs that need
|
||||
to provide a command line interface.
|
||||
|
||||
Copyright (C) 1988-2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2004 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
|
@ -578,11 +578,11 @@ the function that gets called. If @var{key} is not -1, then bind it to
|
|||
@var{function} using @code{rl_bind_key()}.
|
||||
@end deftypefun
|
||||
|
||||
Using this function alone is sufficient for most applications. It is
|
||||
the recommended way to add a few functions to the default functions that
|
||||
Readline has built in. If you need to do something other
|
||||
than adding a function to Readline, you may need to use the
|
||||
underlying functions described below.
|
||||
Using this function alone is sufficient for most applications.
|
||||
It is the recommended way to add a few functions to the default
|
||||
functions that Readline has built in.
|
||||
If you need to do something other than adding a function to Readline,
|
||||
you may need to use the underlying functions described below.
|
||||
|
||||
@node Keymaps
|
||||
@subsection Selecting a Keymap
|
||||
|
@ -658,8 +658,21 @@ Returns non-zero in the case of an invalid @var{key}.
|
|||
@end deftypefun
|
||||
|
||||
@deftypefun int rl_bind_key_in_map (int key, rl_command_func_t *function, Keymap map)
|
||||
Bind @var{key} to @var{function} in @var{map}. Returns non-zero in the case
|
||||
of an invalid @var{key}.
|
||||
Bind @var{key} to @var{function} in @var{map}.
|
||||
Returns non-zero in the case of an invalid @var{key}.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int rl_bind_key_if_unbound (int key, rl_command_func_t *function)
|
||||
Binds @var{key} to @var{function} if it is not already bound in the
|
||||
currently active keymap.
|
||||
Returns non-zero in the case of an invalid @var{key} or if @var{key} is
|
||||
already bound.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int rl_bind_key_if_unbound_in_map (int key, rl_command_func_t *function, Keymap map)
|
||||
Binds @var{key} to @var{function} if it is not already bound in @var{map}.
|
||||
Returns non-zero in the case of an invalid @var{key} or if @var{key} is
|
||||
already bound.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int rl_unbind_key (int key)
|
||||
|
@ -680,10 +693,35 @@ Unbind all keys that execute @var{function} in @var{map}.
|
|||
Unbind all keys that are bound to @var{command} in @var{map}.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int rl_set_key (const char *keyseq, rl_command_func_t *function, Keymap map)
|
||||
@deftypefun int rl_bind_keyseq (const char *keyseq, rl_command_func_t *function)
|
||||
Bind the key sequence represented by the string @var{keyseq} to the function
|
||||
@var{function}. This makes new keymaps as
|
||||
necessary. The initial keymap in which to do bindings is @var{map}.
|
||||
@var{function}, beginning in the current keymap.
|
||||
This makes new keymaps as necessary.
|
||||
The return value is non-zero if @var{keyseq} is invalid.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int rl_bind_keyseq_in_map (const char *keyseq, rl_command_func_t *function, Keymap map)
|
||||
Bind the key sequence represented by the string @var{keyseq} to the function
|
||||
@var{function}. This makes new keymaps as necessary.
|
||||
Initial bindings are performed in @var{map}.
|
||||
The return value is non-zero if @var{keyseq} is invalid.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int rl_set_key (const char *keyseq, rl_command_func_t *function, Keymap map)
|
||||
Equivalent to @code{rl_bind_keyseq_in_map}.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int rl_bind_keyseq_if_unbound (const char *keyseq, rl_command_func_t *function)
|
||||
Binds @var{keyseq} to @var{function} if it is not already bound in the
|
||||
currently active keymap.
|
||||
Returns non-zero in the case of an invalid @var{keyseq} or if @var{keyseq} is
|
||||
already bound.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int rl_bind_keyseq_if_unbound_in_map (const char *keyseq, rl_command_func_t *function, Keymap map)
|
||||
Binds @var{keyseq} to @var{function} if it is not already bound in @var{map}.
|
||||
Returns non-zero in the case of an invalid @var{keyseq} or if @var{keyseq} is
|
||||
already bound.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int rl_generic_bind (int type, const char *keyseq, char *data, Keymap map)
|
||||
|
@ -895,6 +933,11 @@ expand the primary prompt if the @code{rl_on_new_line_with_prompt()}
|
|||
function or @code{rl_already_prompted} variable is used.
|
||||
It returns the number of visible characters on the last line of the
|
||||
(possibly multi-line) prompt.
|
||||
Applications may indicate that the prompt contains characters that take
|
||||
up no physical screen space when displayed by bracketing a sequence of
|
||||
such characters with the special markers @code{RL_PROMPT_START_IGNORE}
|
||||
and @code{RL_PROMPT_END_IGNORE} (declared in @file{readline.h}. This may
|
||||
be used to embed terminal-specific escape sequences in prompts.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int rl_set_prompt (const char *prompt)
|
||||
|
@ -996,9 +1039,15 @@ the state in which it was before the most recent call to
|
|||
@end deftypefun
|
||||
|
||||
@deftypefun void rl_tty_set_default_bindings (Keymap kmap)
|
||||
Read the operating system's terminal editing characters (as would be displayed
|
||||
by @code{stty}) to their Readline equivalents. The bindings are performed
|
||||
in @var{kmap}.
|
||||
Read the operating system's terminal editing characters (as would be
|
||||
displayed by @code{stty}) to their Readline equivalents.
|
||||
The bindings are performed in @var{kmap}.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun void rl_tty_unset_default_bindings (Keymap kmap)
|
||||
Reset the bindings manipulated by @code{rl_tty_set_default_bindings} so
|
||||
that the terminal editing characters are bound to @code{rl_insert}.
|
||||
The bindings are performed in @var{kmap}.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int rl_reset_terminal (const char *terminal_name)
|
||||
|
@ -1357,6 +1406,7 @@ Remove all of the Readline signal handlers installed by
|
|||
|
||||
@node Custom Completers
|
||||
@section Custom Completers
|
||||
@cindex application-specific completion functions
|
||||
|
||||
Typically, a program that reads commands from the user has a way of
|
||||
disambiguating commands and data. If your program is one of these, then
|
||||
|
@ -1417,6 +1467,8 @@ list of possible completions when @var{state} is zero, and returns them
|
|||
one at a time on subsequent calls. Each string the generator function
|
||||
returns as a match must be allocated with @code{malloc()}; Readline
|
||||
frees the strings when it has finished with them.
|
||||
Such a generator function is referred to as an
|
||||
@dfn{application-specific completion function}.
|
||||
|
||||
@end enumerate
|
||||
|
||||
|
@ -1432,6 +1484,9 @@ This is a pointer to the generator function for
|
|||
If the value of @code{rl_completion_entry_function} is
|
||||
@code{NULL} then the default filename generator
|
||||
function, @code{rl_filename_completion_function()}, is used.
|
||||
An @dfn{application-specific completion function} is a function whose
|
||||
address is assigned to @code{rl_completion_entry_function} and whose
|
||||
return values are used to generate possible completions.
|
||||
@end deftypevar
|
||||
|
||||
@node Completion Functions
|
||||
|
@ -1446,7 +1501,9 @@ with the completion. A value of @samp{?} means list the possible
|
|||
completions. @samp{TAB} means do standard completion. @samp{*} means
|
||||
insert all of the possible completions. @samp{!} means to display
|
||||
all of the possible completions, if there is more than one, as well as
|
||||
performing partial completion.
|
||||
performing partial completion. @samp{@@} is similar to @samp{!}, but
|
||||
possible completions are not listed if the possible completions share
|
||||
a common prefix.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int rl_complete (int ignore, int invoking_key)
|
||||
|
@ -1473,7 +1530,8 @@ This calls @code{rl_complete_internal()} with an argument of @samp{*}.
|
|||
@deftypefun int rl_completion_mode (rl_command_func_t *cfunc)
|
||||
Returns the apppriate value to pass to @code{rl_complete_internal()}
|
||||
depending on whether @var{cfunc} was called twice in succession and
|
||||
the value of the @code{show-all-if-ambiguous} variable.
|
||||
the values of the @code{show-all-if-ambiguous} and
|
||||
@code{show-all-if-unmodified} variables.
|
||||
Application-specific completion functions may use this function to present
|
||||
the same interface as @code{rl_complete()}.
|
||||
@end deftypefun
|
||||
|
@ -1495,7 +1553,7 @@ when there are no more matches.
|
|||
@deftypefun {char *} rl_filename_completion_function (const char *text, int state)
|
||||
A generator function for filename completion in the general case.
|
||||
@var{text} is a partial filename.
|
||||
The Bash source is a useful reference for writing custom
|
||||
The Bash source is a useful reference for writing application-specific
|
||||
completion functions (the Bash completion functions call this and other
|
||||
Readline functions).
|
||||
@end deftypefun
|
||||
|
@ -1512,8 +1570,8 @@ for subsequent calls.
|
|||
|
||||
@deftypevar {rl_compentry_func_t *} rl_completion_entry_function
|
||||
A pointer to the generator function for @code{rl_completion_matches()}.
|
||||
@code{NULL} means to use @code{rl_filename_completion_function()}, the default
|
||||
filename completer.
|
||||
@code{NULL} means to use @code{rl_filename_completion_function()},
|
||||
the default filename completer.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {rl_completion_func_t *} rl_attempted_completion_function
|
||||
|
@ -1618,6 +1676,15 @@ The list of characters that signal a break between words for
|
|||
@code{rl_basic_word_break_characters}.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {rl_cpvfunc_t *} rl_completion_word_break_hook
|
||||
If non-zero, this is the address of a function to call when Readline is
|
||||
deciding where to separate words for word completion. It should return
|
||||
a character string like @code{rl_completer_word_break_characters} to be
|
||||
used to perform the current completion. The function may choose to set
|
||||
@code{rl_completer_word_break_characters} itself. If the function
|
||||
returns @code{NULL}, @code{rl_completer_word_break_characters} is used.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {const char *} rl_completer_quote_characters
|
||||
A list of characters which can be used to quote a substring of the line.
|
||||
Completion occurs on the entire substring, and within the substring
|
||||
|
@ -1649,27 +1716,49 @@ When a single completion alternative matches at the end of the command
|
|||
line, this character is appended to the inserted completion text. The
|
||||
default is a space character (@samp{ }). Setting this to the null
|
||||
character (@samp{\0}) prevents anything being appended automatically.
|
||||
This can be changed in custom completion functions to
|
||||
This can be changed in application-specific completion functions to
|
||||
provide the ``most sensible word separator character'' according to
|
||||
an application-specific command line syntax specification.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar int rl_completion_suppress_append
|
||||
If non-zero, @var{rl_completion_append_character} is not appended to
|
||||
matches at the end of the command line, as described above. It is
|
||||
set to 0 before any application-specific completion function is called.
|
||||
matches at the end of the command line, as described above.
|
||||
It is set to 0 before any application-specific completion function
|
||||
is called, and may only be changed within such a function.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar int rl_completion_quote_character
|
||||
When Readline is completing quoted text, as delimited by one of the
|
||||
characters in @var{rl_completer_quote_characters}, it sets this variable
|
||||
to the quoting character found.
|
||||
This is set before any application-specific completion function is called.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar int rl_completion_suppress_quote
|
||||
If non-zero, Readline does not append a matching quote character when
|
||||
performing completion on a quoted string.
|
||||
It is set to 0 before any application-specific completion function
|
||||
is called, and may only be changed within such a function.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar int rl_completion_found_quote
|
||||
When Readline is completing quoted text, it sets this variable
|
||||
to a non-zero value if the word being completed contains or is delimited
|
||||
by any quoting characters, including backslashes.
|
||||
This is set before any application-specific completion function is called.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar int rl_completion_mark_symlink_dirs
|
||||
If non-zero, a slash will be appended to completed filenames that are
|
||||
symbolic links to directory names, subject to the value of the
|
||||
user-settable @var{mark-directories} variable.
|
||||
This variable exists so that application completion functions can
|
||||
override the user's global preference (set via the
|
||||
This variable exists so that application-specific completion functions
|
||||
can override the user's global preference (set via the
|
||||
@var{mark-symlinked-directories} Readline variable) if appropriate.
|
||||
This variable is set to the user's preference before any
|
||||
application completion function is called, so unless that function
|
||||
modifies the value, the user's preferences are honored.
|
||||
application-specific completion function is called, so unless that
|
||||
function modifies the value, the user's preferences are honored.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar int rl_ignore_completion_duplicates
|
||||
|
@ -1679,12 +1768,13 @@ The default is 1.
|
|||
|
||||
@deftypevar int rl_filename_completion_desired
|
||||
Non-zero means that the results of the matches are to be treated as
|
||||
filenames. This is @emph{always} zero on entry, and can only be changed
|
||||
within a completion entry generator function. If it is set to a non-zero
|
||||
value, directory names have a slash appended and Readline attempts to
|
||||
quote completed filenames if they contain any characters in
|
||||
@code{rl_filename_quote_characters} and @code{rl_filename_quoting_desired}
|
||||
is set to a non-zero value.
|
||||
filenames. This is @emph{always} zero when completion is attempted,
|
||||
and can only be changed
|
||||
within an application-specific completion function. If it is set to a
|
||||
non-zero value by such a function, directory names have a slash appended
|
||||
and Readline attempts to quote completed filenames if they contain any
|
||||
characters in @code{rl_filename_quote_characters} and
|
||||
@code{rl_filename_quoting_desired} is set to a non-zero value.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar int rl_filename_quoting_desired
|
||||
|
@ -1692,8 +1782,9 @@ Non-zero means that the results of the matches are to be quoted using
|
|||
double quotes (or an application-specific quoting mechanism) if the
|
||||
completed filename contains any characters in
|
||||
@code{rl_filename_quote_chars}. This is @emph{always} non-zero
|
||||
on entry, and can only be changed within a completion entry generator
|
||||
function. The quoting is effected via a call to the function pointed to
|
||||
when completion is attempted, and can only be changed within an
|
||||
application-specific completion function.
|
||||
The quoting is effected via a call to the function pointed to
|
||||
by @code{rl_filename_quoting_function}.
|
||||
@end deftypevar
|
||||
|
||||
|
@ -1709,6 +1800,9 @@ It should be set only by an application's completion function.
|
|||
Set to a character describing the type of completion Readline is currently
|
||||
attempting; see the description of @code{rl_complete_internal()}
|
||||
(@pxref{Completion Functions}) for the list of characters.
|
||||
This is set to the appropriate value before any application-specific
|
||||
completion function is called, allowing such functions to present
|
||||
the same interface as @code{rl_complete()}.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar int rl_inhibit_completion
|
|
@ -10,7 +10,7 @@ use these features. There is a document entitled "readline.texinfo"
|
|||
which contains both end-user and programmer documentation for the
|
||||
GNU Readline Library.
|
||||
|
||||
Copyright (C) 1988-2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2004 Free Software Foundation, Inc.
|
||||
|
||||
Authored by Brian Fox and Chet Ramey.
|
||||
|
||||
|
@ -418,8 +418,8 @@ The default value is @samp{off}.
|
|||
@item completion-query-items
|
||||
@vindex completion-query-items
|
||||
The number of possible completions that determines when the user is
|
||||
asked whether he wants to see the list of possibilities. If the
|
||||
number of possible completions is greater than this value,
|
||||
asked whether the list of possibilities should be displayed.
|
||||
If the number of possible completions is greater than this value,
|
||||
Readline will ask the user whether or not he wishes to view
|
||||
them; otherwise, they are simply listed.
|
||||
This variable must be set to an integer value greater than or equal to 0.
|
||||
|
@ -458,7 +458,7 @@ attempts word completion. The default is @samp{off}.
|
|||
|
||||
@vindex history-preserve-point
|
||||
If set to @samp{on}, the history code attempts to place point at the
|
||||
same location on each history line retrived with @code{previous-history}
|
||||
same location on each history line retrieved with @code{previous-history}
|
||||
or @code{next-history}.
|
||||
|
||||
@item horizontal-scroll-mode
|
||||
|
@ -552,6 +552,17 @@ words which have more than one possible completion cause the
|
|||
matches to be listed immediately instead of ringing the bell.
|
||||
The default value is @samp{off}.
|
||||
|
||||
@item show-all-if-unmodified
|
||||
@vindex show-all-if-unmodified
|
||||
This alters the default behavior of the completion functions in
|
||||
a fashion similar to @var{show-all-if-ambiguous}.
|
||||
If set to @samp{on},
|
||||
words which have more than one possible completion without any
|
||||
possible partial completion (the possible completions don't share
|
||||
a common prefix) cause the matches to be listed immediately instead
|
||||
of ringing the bell.
|
||||
The default value is @samp{off}.
|
||||
|
||||
@item visible-stats
|
||||
@vindex visible-stats
|
||||
If set to @samp{on}, a character denoting a file's type
|
||||
|
@ -1115,6 +1126,11 @@ Word boundaries are the same as @code{backward-word}.
|
|||
Kill the word behind point, using white space as a word boundary.
|
||||
The killed text is saved on the kill-ring.
|
||||
|
||||
@item unix-filename-rubout ()
|
||||
Kill the word behind point, using white space and the slash character
|
||||
as the word boundaries.
|
||||
The killed text is saved on the kill-ring.
|
||||
|
||||
@item delete-horizontal-space ()
|
||||
Delete all spaces and tabs around point. By default, this is unbound.
|
||||
|
||||
|
@ -1425,7 +1441,7 @@ argument is ignored.
|
|||
Invoke an editor on the current command line, and execute the result as shell
|
||||
commands.
|
||||
Bash attempts to invoke
|
||||
@code{$FCEDIT}, @code{$EDITOR}, and @code{emacs}
|
||||
@code{$VISUAL}, @code{$EDITOR}, and @code{emacs}
|
||||
as the editor, in that order.
|
||||
|
||||
@end ifset
|
||||
|
@ -1568,13 +1584,21 @@ If the previously-applied actions do not generate any matches, and the
|
|||
@option{-o dirnames} option was supplied to @code{complete} when the
|
||||
compspec was defined, directory name completion is attempted.
|
||||
|
||||
If the @option{-o plusdirs} option was supplied to @code{complete} when
|
||||
the compspec was defined, directory name completion is attempted and any
|
||||
matches are added to the results of the other actions.
|
||||
|
||||
By default, if a compspec is found, whatever it generates is returned to
|
||||
the completion code as the full set of possible completions.
|
||||
The default Bash completions are not attempted, and the Readline default
|
||||
of filename completion is disabled.
|
||||
If the @option{-o bashdefault} option was supplied to @code{complete} when
|
||||
the compspec was defined, the default Bash completions are attempted
|
||||
if the compspec generates no matches.
|
||||
If the @option{-o default} option was supplied to @code{complete} when the
|
||||
compspec was defined, Readline's default completion will be performed
|
||||
if the compspec generates no matches.
|
||||
if the compspec (and, if attempted, the default Bash completions)
|
||||
generate no matches.
|
||||
|
||||
When a compspec indicates that directory name completion is desired,
|
||||
the programmable completion functions force Readline to append a slash
|
||||
|
@ -1649,6 +1673,10 @@ beyond the simple generation of completions.
|
|||
|
||||
@table @code
|
||||
|
||||
@item bashdefault
|
||||
Perform the rest of the default Bash completions if the compspec
|
||||
generates no matches.
|
||||
|
||||
@item default
|
||||
Use Readline's default filename completion if the compspec generates
|
||||
no matches.
|
||||
|
@ -1658,7 +1686,7 @@ Perform directory name completion if the compspec generates no matches.
|
|||
|
||||
@item filenames
|
||||
Tell Readline that the compspec generates filenames, so it can perform any
|
||||
filename\-specific processing (like adding a slash to directory names or
|
||||
filename-specific processing (like adding a slash to directory names or
|
||||
suppressing trailing spaces). This option is intended to be used with
|
||||
shell functions specified with @option{-F}.
|
||||
|
88
lib/readline/doc/rluserman.texi
Normal file
88
lib/readline/doc/rluserman.texi
Normal file
|
@ -0,0 +1,88 @@
|
|||
\input texinfo @c -*-texinfo-*-
|
||||
@comment %**start of header (This is for running Texinfo on a region.)
|
||||
@setfilename rluserman.info
|
||||
@settitle GNU Readline Library
|
||||
@comment %**end of header (This is for running Texinfo on a region.)
|
||||
|
||||
@setchapternewpage odd
|
||||
|
||||
@include version.texi
|
||||
|
||||
@copying
|
||||
This manual describes the end user interface of the GNU Readline Library
|
||||
(version @value{VERSION}, @value{UPDATED}), a library which aids in the
|
||||
consistency of user interface across discrete programs which provide
|
||||
a command line interface.
|
||||
|
||||
Copyright @copyright{} 1988-2004 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
are preserved on all copies.
|
||||
|
||||
@quotation
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.1 or
|
||||
any later version published by the Free Software Foundation; with no
|
||||
Invariant Sections, with the Front-Cover texts being ``A GNU Manual,''
|
||||
and with the Back-Cover Texts as in (a) below. A copy of the license is
|
||||
included in the section entitled ``GNU Free Documentation License.''
|
||||
|
||||
(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
|
||||
this GNU Manual, like GNU software. Copies published by the Free
|
||||
Software Foundation raise funds for GNU development.''
|
||||
@end quotation
|
||||
@end copying
|
||||
|
||||
@dircategory Libraries
|
||||
@direntry
|
||||
* RLuserman: (rluserman). The GNU readline library User's Manual.
|
||||
@end direntry
|
||||
|
||||
@titlepage
|
||||
@title GNU Readline Library User Interface
|
||||
@subtitle Edition @value{EDITION}, for @code{Readline Library} Version @value{VERSION}.
|
||||
@subtitle @value{UPDATED-MONTH}
|
||||
@author Chet Ramey, Case Western Reserve University
|
||||
@author Brian Fox, Free Software Foundation
|
||||
|
||||
@page
|
||||
@vskip 0pt plus 1filll
|
||||
@insertcopying
|
||||
|
||||
@sp 1
|
||||
Published by the Free Software Foundation @*
|
||||
59 Temple Place, Suite 330, @*
|
||||
Boston, MA 02111-1307 @*
|
||||
USA @*
|
||||
|
||||
@end titlepage
|
||||
|
||||
@contents
|
||||
|
||||
@ifnottex
|
||||
@node Top
|
||||
@top GNU Readline Library
|
||||
|
||||
This document describes the end user interface of the GNU Readline Library,
|
||||
a utility which aids in the consistency of user interface across discrete
|
||||
programs which provide a command line interface.
|
||||
|
||||
@menu
|
||||
* Command Line Editing:: GNU Readline User's Manual.
|
||||
* Copying This Manual:: Copying This Manual.
|
||||
@end menu
|
||||
@end ifnottex
|
||||
|
||||
@include rluser.texi
|
||||
|
||||
@node Copying This Manual
|
||||
@appendix Copying This Manual
|
||||
|
||||
@menu
|
||||
* GNU Free Documentation License:: License for copying this manual.
|
||||
@end menu
|
||||
|
||||
@include fdl.texi
|
||||
|
||||
@bye
|
|
@ -1,94 +0,0 @@
|
|||
\input texinfo @c -*-texinfo-*-
|
||||
@comment %**start of header (This is for running Texinfo on a region.)
|
||||
@setfilename rluserman.info
|
||||
@settitle GNU Readline Library
|
||||
@comment %**end of header (This is for running Texinfo on a region.)
|
||||
@setchapternewpage odd
|
||||
|
||||
@include manvers.texinfo
|
||||
|
||||
@ifinfo
|
||||
@dircategory Libraries
|
||||
@direntry
|
||||
* RLuserman: (rluserman). The GNU readline library User's Manual.
|
||||
@end direntry
|
||||
|
||||
This document describes the end user interface of the GNU Readline Library,
|
||||
a utility which aids in the consistency of user interface across discrete
|
||||
programs that need to provide a command line interface.
|
||||
|
||||
Copyright (C) 1988-2002 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
pare preserved on all copies.
|
||||
|
||||
@ignore
|
||||
Permission is granted to process this file through TeX and print the
|
||||
results, provided the printed document carries copying permission
|
||||
notice identical to this one except for the removal of this paragraph
|
||||
(this paragraph not being relevant to the printed manual).
|
||||
@end ignore
|
||||
|
||||
Permission is granted to copy and distribute modified versions of this
|
||||
manual under the conditions for verbatim copying, provided that the entire
|
||||
resulting derived work is distributed under the terms of a permission
|
||||
notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this manual
|
||||
into another language, under the above conditions for modified versions,
|
||||
except that this permission notice may be stated in a translation approved
|
||||
by the Free Software Foundation.
|
||||
@end ifinfo
|
||||
|
||||
@titlepage
|
||||
@title GNU Readline Library User Interface
|
||||
@subtitle Edition @value{EDITION}, for @code{Readline Library} Version @value{VERSION}.
|
||||
@subtitle @value{UPDATE-MONTH}
|
||||
@author Brian Fox, Free Software Foundation
|
||||
@author Chet Ramey, Case Western Reserve University
|
||||
|
||||
@page
|
||||
This document describes the end user interface of the GNU Readline Library,
|
||||
a utility which aids in the consistency of user interface across discrete
|
||||
programs that need to provide a command line interface.
|
||||
|
||||
Published by the Free Software Foundation @*
|
||||
59 Temple Place, Suite 330, @*
|
||||
Boston, MA 02111 USA
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
are preserved on all copies.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of this
|
||||
manual under the conditions for verbatim copying, provided that the entire
|
||||
resulting derived work is distributed under the terms of a permission
|
||||
notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this manual
|
||||
into another language, under the above conditions for modified versions,
|
||||
except that this permission notice may be stated in a translation approved
|
||||
by the Free Software Foundation.
|
||||
|
||||
@vskip 0pt plus 1filll
|
||||
Copyright @copyright{} 1988-2002 Free Software Foundation, Inc.
|
||||
@end titlepage
|
||||
|
||||
@ifinfo
|
||||
@node Top
|
||||
@top GNU Readline Library
|
||||
|
||||
This document describes the end user interface of the GNU Readline Library,
|
||||
a utility which aids in the consistency of user interface across discrete
|
||||
programs that need to provide a command line interface.
|
||||
|
||||
@menu
|
||||
* Command Line Editing:: GNU Readline User's Manual.
|
||||
@end menu
|
||||
@end ifinfo
|
||||
|
||||
@include rluser.texinfo
|
||||
|
||||
@contents
|
||||
@bye
|
10
lib/readline/doc/version.texi
Normal file
10
lib/readline/doc/version.texi
Normal file
|
@ -0,0 +1,10 @@
|
|||
@ignore
|
||||
Copyright (C) 1988-2004 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set EDITION 5.0
|
||||
@set VERSION 5.0
|
||||
@set UPDATED 28 January 2004
|
||||
@set UPDATED-MONTH January 2004
|
||||
|
||||
@set LASTCHANGE Wed Jan 28 15:46:54 EST 2004
|
|
@ -31,9 +31,10 @@ main (argc, argv)
|
|||
char **argv;
|
||||
{
|
||||
char line[1024], *t;
|
||||
int len, done = 0;
|
||||
int len, done;
|
||||
|
||||
line[0] = 0;
|
||||
done = 0;
|
||||
|
||||
using_history ();
|
||||
while (!done)
|
||||
|
@ -42,71 +43,80 @@ main (argc, argv)
|
|||
fflush (stdout);
|
||||
t = fgets (line, sizeof (line) - 1, stdin);
|
||||
if (t && *t)
|
||||
{
|
||||
len = strlen (t);
|
||||
if (t[len - 1] == '\n')
|
||||
t[len - 1] = '\0';
|
||||
}
|
||||
{
|
||||
len = strlen (t);
|
||||
if (t[len - 1] == '\n')
|
||||
t[len - 1] = '\0';
|
||||
}
|
||||
|
||||
if (!t)
|
||||
strcpy (line, "quit");
|
||||
strcpy (line, "quit");
|
||||
|
||||
if (line[0])
|
||||
{
|
||||
char *expansion;
|
||||
int result;
|
||||
{
|
||||
char *expansion;
|
||||
int result;
|
||||
|
||||
using_history ();
|
||||
using_history ();
|
||||
|
||||
result = history_expand (line, &expansion);
|
||||
if (result)
|
||||
fprintf (stderr, "%s\n", expansion);
|
||||
result = history_expand (line, &expansion);
|
||||
if (result)
|
||||
fprintf (stderr, "%s\n", expansion);
|
||||
|
||||
if (result < 0 || result == 2)
|
||||
{
|
||||
free (expansion);
|
||||
continue;
|
||||
}
|
||||
if (result < 0 || result == 2)
|
||||
{
|
||||
free (expansion);
|
||||
continue;
|
||||
}
|
||||
|
||||
add_history (expansion);
|
||||
strncpy (line, expansion, sizeof (line) - 1);
|
||||
free (expansion);
|
||||
}
|
||||
add_history (expansion);
|
||||
strncpy (line, expansion, sizeof (line) - 1);
|
||||
free (expansion);
|
||||
}
|
||||
|
||||
if (strcmp (line, "quit") == 0)
|
||||
done = 1;
|
||||
done = 1;
|
||||
else if (strcmp (line, "save") == 0)
|
||||
write_history ("history_file");
|
||||
write_history ("history_file");
|
||||
else if (strcmp (line, "read") == 0)
|
||||
read_history ("history_file");
|
||||
read_history ("history_file");
|
||||
else if (strcmp (line, "list") == 0)
|
||||
{
|
||||
register HIST_ENTRY **the_list;
|
||||
register int i;
|
||||
{
|
||||
register HIST_ENTRY **the_list;
|
||||
register int i;
|
||||
time_t tt;
|
||||
char timestr[128];
|
||||
|
||||
the_list = history_list ();
|
||||
if (the_list)
|
||||
for (i = 0; the_list[i]; i++)
|
||||
printf ("%d: %s\n", i + history_base, the_list[i]->line);
|
||||
}
|
||||
the_list = history_list ();
|
||||
if (the_list)
|
||||
for (i = 0; the_list[i]; i++)
|
||||
{
|
||||
tt = history_get_time (the_list[i]);
|
||||
if (tt)
|
||||
strftime (timestr, sizeof (timestr), "%a %R", localtime(&tt));
|
||||
else
|
||||
strcpy (timestr, "??");
|
||||
printf ("%d: %s: %s\n", i + history_base, timestr, the_list[i]->line);
|
||||
}
|
||||
}
|
||||
else if (strncmp (line, "delete", 6) == 0)
|
||||
{
|
||||
int which;
|
||||
if ((sscanf (line + 6, "%d", &which)) == 1)
|
||||
{
|
||||
HIST_ENTRY *entry = remove_history (which);
|
||||
if (!entry)
|
||||
fprintf (stderr, "No such entry %d\n", which);
|
||||
else
|
||||
{
|
||||
free (entry->line);
|
||||
free (entry);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "non-numeric arg given to `delete'\n");
|
||||
}
|
||||
}
|
||||
{
|
||||
int which;
|
||||
if ((sscanf (line + 6, "%d", &which)) == 1)
|
||||
{
|
||||
HIST_ENTRY *entry = remove_history (which);
|
||||
if (!entry)
|
||||
fprintf (stderr, "No such entry %d\n", which);
|
||||
else
|
||||
{
|
||||
free (entry->line);
|
||||
free (entry);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "non-numeric arg given to `delete'\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,6 +131,7 @@ static FUNMAP default_funmap[] = {
|
|||
{ "tty-status", rl_tty_status },
|
||||
{ "undo", rl_undo_command },
|
||||
{ "universal-argument", rl_universal_argument },
|
||||
{ "unix-filename-rubout", rl_unix_filename_rubout },
|
||||
{ "unix-line-discard", rl_unix_line_discard },
|
||||
{ "unix-word-rubout", rl_unix_word_rubout },
|
||||
{ "upcase-word", rl_upcase_word },
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* histexpand.c -- history expansion. */
|
||||
|
||||
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1989-2004 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the GNU History Library (the Library), a set of
|
||||
routines for managing the text of previously typed lines.
|
||||
|
@ -52,6 +52,8 @@
|
|||
#define HISTORY_WORD_DELIMITERS " \t\n;&()|<>"
|
||||
#define HISTORY_QUOTE_CHARACTERS "\"'`"
|
||||
|
||||
#define slashify_in_quotes "\\`\"$"
|
||||
|
||||
typedef int _hist_search_func_t PARAMS((const char *, int));
|
||||
|
||||
extern int rl_byte_oriented; /* declared in mbutil.c */
|
||||
|
@ -65,6 +67,8 @@ static int subst_rhs_len;
|
|||
|
||||
static char *get_history_word_specifier PARAMS((char *, char *, int *));
|
||||
static char *history_find_word PARAMS((char *, int));
|
||||
static int history_tokenize_word PARAMS((const char *, int));
|
||||
static char *history_substring PARAMS((const char *, int, int));
|
||||
|
||||
static char *quote_breaks PARAMS((char *));
|
||||
|
||||
|
@ -211,8 +215,8 @@ get_history_event (string, caller_index, delimiting_quote)
|
|||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
/* These produce warnings because we're passing a const string to a
|
||||
function that takes a non-const string. */
|
||||
_rl_adjust_point (string, i, &ps);
|
||||
if ((v = _rl_get_char_len (string + i, &ps)) > 1)
|
||||
_rl_adjust_point ((char *)string, i, &ps);
|
||||
if ((v = _rl_get_char_len ((char *)string + i, &ps)) > 1)
|
||||
{
|
||||
i += v - 1;
|
||||
continue;
|
||||
|
@ -517,7 +521,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
|
|||
char *current_line; /* for !# */
|
||||
{
|
||||
int i, n, starting_index;
|
||||
int substitute_globally, want_quotes, print_only;
|
||||
int substitute_globally, subst_bywords, want_quotes, print_only;
|
||||
char *event, *temp, *result, *tstr, *t, c, *word_spec;
|
||||
int result_len;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
|
@ -599,19 +603,25 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
|
|||
FREE (word_spec);
|
||||
|
||||
/* Perhaps there are other modifiers involved. Do what they say. */
|
||||
want_quotes = substitute_globally = print_only = 0;
|
||||
want_quotes = substitute_globally = subst_bywords = print_only = 0;
|
||||
starting_index = i;
|
||||
|
||||
while (string[i] == ':')
|
||||
{
|
||||
c = string[i + 1];
|
||||
|
||||
if (c == 'g')
|
||||
if (c == 'g' || c == 'a')
|
||||
{
|
||||
substitute_globally = 1;
|
||||
i++;
|
||||
c = string[i + 1];
|
||||
}
|
||||
else if (c == 'G')
|
||||
{
|
||||
subst_bywords = 1;
|
||||
i++;
|
||||
c = string[i + 1];
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
|
@ -683,7 +693,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
|
|||
case 's':
|
||||
{
|
||||
char *new_event;
|
||||
int delimiter, failed, si, l_temp;
|
||||
int delimiter, failed, si, l_temp, ws, we;
|
||||
|
||||
if (c == 's')
|
||||
{
|
||||
|
@ -760,33 +770,67 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
|
|||
}
|
||||
|
||||
/* Find the first occurrence of THIS in TEMP. */
|
||||
si = 0;
|
||||
/* Substitute SUBST_RHS for SUBST_LHS in TEMP. There are three
|
||||
cases to consider:
|
||||
|
||||
1. substitute_globally == subst_bywords == 0
|
||||
2. substitute_globally == 1 && subst_bywords == 0
|
||||
3. substitute_globally == 0 && subst_bywords == 1
|
||||
|
||||
In the first case, we substitute for the first occurrence only.
|
||||
In the second case, we substitute for every occurrence.
|
||||
In the third case, we tokenize into words and substitute the
|
||||
first occurrence of each word. */
|
||||
|
||||
si = we = 0;
|
||||
for (failed = 1; (si + subst_lhs_len) <= l_temp; si++)
|
||||
if (STREQN (temp+si, subst_lhs, subst_lhs_len))
|
||||
{
|
||||
int len = subst_rhs_len - subst_lhs_len + l_temp;
|
||||
new_event = (char *)xmalloc (1 + len);
|
||||
strncpy (new_event, temp, si);
|
||||
strncpy (new_event + si, subst_rhs, subst_rhs_len);
|
||||
strncpy (new_event + si + subst_rhs_len,
|
||||
temp + si + subst_lhs_len,
|
||||
l_temp - (si + subst_lhs_len));
|
||||
new_event[len] = '\0';
|
||||
free (temp);
|
||||
temp = new_event;
|
||||
{
|
||||
/* First skip whitespace and find word boundaries if
|
||||
we're past the end of the word boundary we found
|
||||
the last time. */
|
||||
if (subst_bywords && si > we)
|
||||
{
|
||||
for (; temp[si] && whitespace (temp[si]); si++)
|
||||
;
|
||||
ws = si;
|
||||
we = history_tokenize_word (temp, si);
|
||||
}
|
||||
|
||||
failed = 0;
|
||||
if (STREQN (temp+si, subst_lhs, subst_lhs_len))
|
||||
{
|
||||
int len = subst_rhs_len - subst_lhs_len + l_temp;
|
||||
new_event = (char *)xmalloc (1 + len);
|
||||
strncpy (new_event, temp, si);
|
||||
strncpy (new_event + si, subst_rhs, subst_rhs_len);
|
||||
strncpy (new_event + si + subst_rhs_len,
|
||||
temp + si + subst_lhs_len,
|
||||
l_temp - (si + subst_lhs_len));
|
||||
new_event[len] = '\0';
|
||||
free (temp);
|
||||
temp = new_event;
|
||||
|
||||
if (substitute_globally)
|
||||
{
|
||||
si += subst_rhs_len;
|
||||
l_temp = strlen (temp);
|
||||
substitute_globally++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
failed = 0;
|
||||
|
||||
if (substitute_globally)
|
||||
{
|
||||
/* Reported to fix a bug that causes it to skip every
|
||||
other match when matching a single character. Was
|
||||
si += subst_rhs_len previously. */
|
||||
si += subst_rhs_len - 1;
|
||||
l_temp = strlen (temp);
|
||||
substitute_globally++;
|
||||
continue;
|
||||
}
|
||||
else if (subst_bywords)
|
||||
{
|
||||
si = we;
|
||||
l_temp = strlen (temp);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (substitute_globally > 1)
|
||||
{
|
||||
|
@ -879,7 +923,7 @@ history_expand (hstring, output)
|
|||
char **output;
|
||||
{
|
||||
register int j;
|
||||
int i, r, l, passc, cc, modified, eindex, only_printing;
|
||||
int i, r, l, passc, cc, modified, eindex, only_printing, dquote;
|
||||
char *string;
|
||||
|
||||
/* The output string, and its length. */
|
||||
|
@ -942,7 +986,7 @@ history_expand (hstring, output)
|
|||
|
||||
/* `!' followed by one of the characters in history_no_expand_chars
|
||||
is NOT an expansion. */
|
||||
for (i = 0; string[i]; i++)
|
||||
for (i = dquote = 0; string[i]; i++)
|
||||
{
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
|
@ -984,9 +1028,19 @@ history_expand (hstring, output)
|
|||
else
|
||||
break;
|
||||
}
|
||||
/* XXX - at some point, might want to extend this to handle
|
||||
double quotes as well. */
|
||||
else if (history_quotes_inhibit_expansion && string[i] == '\'')
|
||||
/* Shell-like quoting: allow backslashes to quote double quotes
|
||||
inside a double-quoted string. */
|
||||
else if (dquote && string[i] == '\\' && cc == '"')
|
||||
i++;
|
||||
/* More shell-like quoting: if we're paying attention to single
|
||||
quotes and letting them quote the history expansion character,
|
||||
then we need to pay attention to double quotes, because single
|
||||
quotes are not special inside double-quoted strings. */
|
||||
else if (history_quotes_inhibit_expansion && string[i] == '"')
|
||||
{
|
||||
dquote = 1 - dquote;
|
||||
}
|
||||
else if (dquote == 0 && history_quotes_inhibit_expansion && string[i] == '\'')
|
||||
{
|
||||
/* If this is bash, single quotes inhibit history expansion. */
|
||||
i++;
|
||||
|
@ -999,6 +1053,7 @@ history_expand (hstring, output)
|
|||
if (cc == '\'' || cc == history_expansion_char)
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (string[i] != history_expansion_char)
|
||||
|
@ -1010,7 +1065,7 @@ history_expand (hstring, output)
|
|||
}
|
||||
|
||||
/* Extract and perform the substitution. */
|
||||
for (passc = i = j = 0; i < l; i++)
|
||||
for (passc = dquote = i = j = 0; i < l; i++)
|
||||
{
|
||||
int tchar = string[i];
|
||||
|
||||
|
@ -1061,11 +1116,16 @@ history_expand (hstring, output)
|
|||
ADD_CHAR (tchar);
|
||||
break;
|
||||
|
||||
case '"':
|
||||
dquote = 1 - dquote;
|
||||
ADD_CHAR (tchar);
|
||||
break;
|
||||
|
||||
case '\'':
|
||||
{
|
||||
/* If history_quotes_inhibit_expansion is set, single quotes
|
||||
inhibit history expansion. */
|
||||
if (history_quotes_inhibit_expansion)
|
||||
if (dquote == 0 && history_quotes_inhibit_expansion)
|
||||
{
|
||||
int quote, slen;
|
||||
|
||||
|
@ -1160,7 +1220,9 @@ history_expand (hstring, output)
|
|||
|
||||
if (only_printing)
|
||||
{
|
||||
#if 0
|
||||
add_history (result);
|
||||
#endif
|
||||
return (2);
|
||||
}
|
||||
|
||||
|
@ -1223,7 +1285,10 @@ get_history_word_specifier (spec, from, caller_index)
|
|||
if (spec[i] == '-')
|
||||
first = 0;
|
||||
else if (spec[i] == '^')
|
||||
first = 1;
|
||||
{
|
||||
first = 1;
|
||||
i++;
|
||||
}
|
||||
else if (_rl_digit_p (spec[i]) && expecting_word_spec)
|
||||
{
|
||||
for (first = 0; _rl_digit_p (spec[i]); i++)
|
||||
|
@ -1338,7 +1403,103 @@ history_arg_extract (first, last, string)
|
|||
return (result);
|
||||
}
|
||||
|
||||
#define slashify_in_quotes "\\`\"$"
|
||||
static int
|
||||
history_tokenize_word (string, ind)
|
||||
const char *string;
|
||||
int ind;
|
||||
{
|
||||
register int i;
|
||||
int delimiter;
|
||||
|
||||
i = ind;
|
||||
delimiter = 0;
|
||||
|
||||
if (member (string[i], "()\n"))
|
||||
{
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
if (member (string[i], "<>;&|$"))
|
||||
{
|
||||
int peek = string[i + 1];
|
||||
|
||||
if (peek == string[i] && peek != '$')
|
||||
{
|
||||
if (peek == '<' && string[i + 2] == '-')
|
||||
i++;
|
||||
i += 2;
|
||||
return i;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((peek == '&' && (string[i] == '>' || string[i] == '<')) ||
|
||||
(peek == '>' && string[i] == '&') ||
|
||||
(peek == '(' && (string[i] == '>' || string[i] == '<')) || /* ) */
|
||||
(peek == '(' && string[i] == '$')) /* ) */
|
||||
{
|
||||
i += 2;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
if (string[i] != '$')
|
||||
{
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get word from string + i; */
|
||||
|
||||
if (member (string[i], HISTORY_QUOTE_CHARACTERS))
|
||||
delimiter = string[i++];
|
||||
|
||||
for (; string[i]; i++)
|
||||
{
|
||||
if (string[i] == '\\' && string[i + 1] == '\n')
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string[i] == '\\' && delimiter != '\'' &&
|
||||
(delimiter != '"' || member (string[i], slashify_in_quotes)))
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (delimiter && string[i] == delimiter)
|
||||
{
|
||||
delimiter = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!delimiter && (member (string[i], history_word_delimiters)))
|
||||
break;
|
||||
|
||||
if (!delimiter && member (string[i], HISTORY_QUOTE_CHARACTERS))
|
||||
delimiter = string[i];
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static char *
|
||||
history_substring (string, start, end)
|
||||
const char *string;
|
||||
int start, end;
|
||||
{
|
||||
register int len;
|
||||
register char *result;
|
||||
|
||||
len = end - start;
|
||||
result = (char *)xmalloc (len + 1);
|
||||
strncpy (result, string + start, len);
|
||||
result[len] = '\0';
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Parse STRING into tokens and return an array of strings. If WIND is
|
||||
not -1 and INDP is not null, we also want the word surrounding index
|
||||
|
@ -1351,7 +1512,6 @@ history_tokenize_internal (string, wind, indp)
|
|||
{
|
||||
char **result;
|
||||
register int i, start, result_index, size;
|
||||
int len, delimiter;
|
||||
|
||||
/* If we're searching for a string that's not part of a word (e.g., " "),
|
||||
make sure we set *INDP to a reasonable value. */
|
||||
|
@ -1362,8 +1522,6 @@ history_tokenize_internal (string, wind, indp)
|
|||
exactly where the shell would split them. */
|
||||
for (i = result_index = size = 0, result = (char **)NULL; string[i]; )
|
||||
{
|
||||
delimiter = 0;
|
||||
|
||||
/* Skip leading whitespace. */
|
||||
for (; string[i] && whitespace (string[i]); i++)
|
||||
;
|
||||
|
@ -1371,88 +1529,30 @@ history_tokenize_internal (string, wind, indp)
|
|||
return (result);
|
||||
|
||||
start = i;
|
||||
|
||||
if (member (string[i], "()\n"))
|
||||
|
||||
i = history_tokenize_word (string, start);
|
||||
|
||||
/* If we have a non-whitespace delimiter character (which would not be
|
||||
skipped by the loop above), use it and any adjacent delimiters to
|
||||
make a separate field. Any adjacent white space will be skipped the
|
||||
next time through the loop. */
|
||||
if (i == start && history_word_delimiters)
|
||||
{
|
||||
i++;
|
||||
goto got_token;
|
||||
while (string[i] && member (string[i], history_word_delimiters))
|
||||
i++;
|
||||
}
|
||||
|
||||
if (member (string[i], "<>;&|$"))
|
||||
{
|
||||
int peek = string[i + 1];
|
||||
|
||||
if (peek == string[i] && peek != '$')
|
||||
{
|
||||
if (peek == '<' && string[i + 2] == '-')
|
||||
i++;
|
||||
i += 2;
|
||||
goto got_token;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((peek == '&' && (string[i] == '>' || string[i] == '<')) ||
|
||||
((peek == '>') && (string[i] == '&')) ||
|
||||
((peek == '(') && (string[i] == '$')))
|
||||
{
|
||||
i += 2;
|
||||
goto got_token;
|
||||
}
|
||||
}
|
||||
if (string[i] != '$')
|
||||
{
|
||||
i++;
|
||||
goto got_token;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get word from string + i; */
|
||||
|
||||
if (member (string[i], HISTORY_QUOTE_CHARACTERS))
|
||||
delimiter = string[i++];
|
||||
|
||||
for (; string[i]; i++)
|
||||
{
|
||||
if (string[i] == '\\' && string[i + 1] == '\n')
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string[i] == '\\' && delimiter != '\'' &&
|
||||
(delimiter != '"' || member (string[i], slashify_in_quotes)))
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (delimiter && string[i] == delimiter)
|
||||
{
|
||||
delimiter = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!delimiter && (member (string[i], history_word_delimiters)))
|
||||
break;
|
||||
|
||||
if (!delimiter && member (string[i], HISTORY_QUOTE_CHARACTERS))
|
||||
delimiter = string[i];
|
||||
}
|
||||
|
||||
got_token:
|
||||
|
||||
/* If we are looking for the word in which the character at a
|
||||
particular index falls, remember it. */
|
||||
if (indp && wind != -1 && wind >= start && wind < i)
|
||||
*indp = result_index;
|
||||
|
||||
len = i - start;
|
||||
if (result_index + 2 >= size)
|
||||
result = (char **)xrealloc (result, ((size += 10) * sizeof (char *)));
|
||||
result[result_index] = (char *)xmalloc (1 + len);
|
||||
strncpy (result[result_index], string + start, len);
|
||||
result[result_index][len] = '\0';
|
||||
result[++result_index] = (char *)NULL;
|
||||
|
||||
result[result_index++] = history_substring (string, start, i);
|
||||
result[result_index] = (char *)NULL;
|
||||
}
|
||||
|
||||
return (result);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* histfile.c - functions to manipulate the history file. */
|
||||
|
||||
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1989-2003 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the GNU History Library (the Library), a set of
|
||||
routines for managing the text of previously typed lines.
|
||||
|
@ -23,8 +23,13 @@
|
|||
/* The goal is to make the implementation transparent, so that you
|
||||
don't have to know what data types are used, just what functions
|
||||
you can call. I think I have done that. */
|
||||
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (__TANDEM)
|
||||
# include <floss.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
@ -32,7 +37,7 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifndef _MINIX
|
||||
#if ! defined (_MINIX) && defined (HAVE_SYS_FILE_H)
|
||||
# include <sys/file.h>
|
||||
#endif
|
||||
#include "posixstat.h"
|
||||
|
@ -52,7 +57,7 @@
|
|||
# undef HAVE_MMAP
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
#ifdef HISTORY_USE_MMAP
|
||||
# include <sys/mman.h>
|
||||
|
||||
# ifdef MAP_FILE
|
||||
|
@ -67,7 +72,7 @@
|
|||
# define MAP_FAILED ((void *)-1)
|
||||
# endif
|
||||
|
||||
#endif /* HAVE_MMAP */
|
||||
#endif /* HISTORY_USE_MMAP */
|
||||
|
||||
/* If we're compiling for __EMX__ (OS/2) or __CYGWIN__ (cygwin32 environment
|
||||
on win 95/98/nt), we want to open files with O_BINARY mode so that there
|
||||
|
@ -93,6 +98,13 @@ extern int errno;
|
|||
#include "rlshell.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
/* If non-zero, we write timestamps to the history file in history_do_write() */
|
||||
int history_write_timestamps = 0;
|
||||
|
||||
/* Does S look like the beginning of a history timestamp entry? Placeholder
|
||||
for more extensive tests. */
|
||||
#define HIST_TIMESTAMP_START(s) (*(s) == history_comment_char)
|
||||
|
||||
/* Return the string that should be used in the place of this
|
||||
filename. This only matters when you don't specify the
|
||||
filename to read_history (), or write_history (). */
|
||||
|
@ -151,13 +163,20 @@ read_history_range (filename, from, to)
|
|||
const char *filename;
|
||||
int from, to;
|
||||
{
|
||||
register char *line_start, *line_end;
|
||||
char *input, *buffer, *bufend;
|
||||
register char *line_start, *line_end, *p;
|
||||
char *input, *buffer, *bufend, *last_ts;
|
||||
int file, current_line, chars_read;
|
||||
struct stat finfo;
|
||||
size_t file_size;
|
||||
#if defined (EFBIG)
|
||||
int overflow_errno = EFBIG;
|
||||
#elif defined (EOVERFLOW)
|
||||
int overflow_errno = EOVERFLOW;
|
||||
#else
|
||||
int overflow_errno = EIO;
|
||||
#endif
|
||||
|
||||
buffer = (char *)NULL;
|
||||
buffer = last_ts = (char *)NULL;
|
||||
input = history_filename (filename);
|
||||
file = open (input, O_RDONLY|O_BINARY, 0666);
|
||||
|
||||
|
@ -169,37 +188,42 @@ read_history_range (filename, from, to)
|
|||
/* check for overflow on very large files */
|
||||
if (file_size != finfo.st_size || file_size + 1 < file_size)
|
||||
{
|
||||
#if defined (EFBIG)
|
||||
errno = EFBIG;
|
||||
#elif defined (EOVERFLOW)
|
||||
errno = EOVERFLOW;
|
||||
#endif
|
||||
errno = overflow_errno;
|
||||
goto error_and_exit;
|
||||
}
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
#ifdef HISTORY_USE_MMAP
|
||||
/* We map read/write and private so we can change newlines to NULs without
|
||||
affecting the underlying object. */
|
||||
buffer = (char *)mmap (0, file_size, PROT_READ|PROT_WRITE, MAP_RFLAGS, file, 0);
|
||||
if ((void *)buffer == MAP_FAILED)
|
||||
goto error_and_exit;
|
||||
{
|
||||
errno = overflow_errno;
|
||||
goto error_and_exit;
|
||||
}
|
||||
chars_read = file_size;
|
||||
#else
|
||||
buffer = (char *)malloc (file_size + 1);
|
||||
if (buffer == 0)
|
||||
goto error_and_exit;
|
||||
{
|
||||
errno = overflow_errno;
|
||||
goto error_and_exit;
|
||||
}
|
||||
|
||||
chars_read = read (file, buffer, file_size);
|
||||
#endif
|
||||
if (chars_read < 0)
|
||||
{
|
||||
error_and_exit:
|
||||
chars_read = errno;
|
||||
if (errno != 0)
|
||||
chars_read = errno;
|
||||
else
|
||||
chars_read = EIO;
|
||||
if (file >= 0)
|
||||
close (file);
|
||||
|
||||
FREE (input);
|
||||
#ifndef HAVE_MMAP
|
||||
#ifndef HISTORY_USE_MMAP
|
||||
FREE (buffer);
|
||||
#endif
|
||||
|
||||
|
@ -220,8 +244,12 @@ read_history_range (filename, from, to)
|
|||
for (line_start = line_end = buffer; line_end < bufend && current_line < from; line_end++)
|
||||
if (*line_end == '\n')
|
||||
{
|
||||
current_line++;
|
||||
line_start = line_end + 1;
|
||||
p = line_end + 1;
|
||||
/* If we see something we think is a timestamp, continue with this
|
||||
line. We should check more extensively here... */
|
||||
if (HIST_TIMESTAMP_START(p) == 0)
|
||||
current_line++;
|
||||
line_start = p;
|
||||
}
|
||||
|
||||
/* If there are lines left to gobble, then gobble them now. */
|
||||
|
@ -231,7 +259,22 @@ read_history_range (filename, from, to)
|
|||
*line_end = '\0';
|
||||
|
||||
if (*line_start)
|
||||
add_history (line_start);
|
||||
{
|
||||
if (HIST_TIMESTAMP_START(line_start) == 0)
|
||||
{
|
||||
add_history (line_start);
|
||||
if (last_ts)
|
||||
{
|
||||
add_history_time (last_ts);
|
||||
last_ts = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
last_ts = line_start;
|
||||
current_line--;
|
||||
}
|
||||
}
|
||||
|
||||
current_line++;
|
||||
|
||||
|
@ -242,7 +285,7 @@ read_history_range (filename, from, to)
|
|||
}
|
||||
|
||||
FREE (input);
|
||||
#ifndef HAVE_MMAP
|
||||
#ifndef HISTORY_USE_MMAP
|
||||
FREE (buffer);
|
||||
#else
|
||||
munmap (buffer, file_size);
|
||||
|
@ -259,7 +302,7 @@ history_truncate_file (fname, lines)
|
|||
const char *fname;
|
||||
int lines;
|
||||
{
|
||||
char *buffer, *filename, *bp;
|
||||
char *buffer, *filename, *bp, *bp1; /* bp1 == bp+1 */
|
||||
int file, chars_read, rv;
|
||||
struct stat finfo;
|
||||
size_t file_size;
|
||||
|
@ -322,11 +365,14 @@ history_truncate_file (fname, lines)
|
|||
}
|
||||
|
||||
/* Count backwards from the end of buffer until we have passed
|
||||
LINES lines. */
|
||||
for (bp = buffer + chars_read - 1; lines && bp > buffer; bp--)
|
||||
LINES lines. bp1 is set funny initially. But since bp[1] can't
|
||||
be a comment character (since it's off the end) and *bp can't be
|
||||
both a newline and the history comment character, it should be OK. */
|
||||
for (bp1 = bp = buffer + chars_read - 1; lines && bp > buffer; bp--)
|
||||
{
|
||||
if (*bp == '\n')
|
||||
if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0)
|
||||
lines--;
|
||||
bp1 = bp;
|
||||
}
|
||||
|
||||
/* If this is the first line, then the file contains exactly the
|
||||
|
@ -335,11 +381,14 @@ history_truncate_file (fname, lines)
|
|||
the current value of i and 0. Otherwise, write from the start of
|
||||
this line until the end of the buffer. */
|
||||
for ( ; bp > buffer; bp--)
|
||||
if (*bp == '\n')
|
||||
{
|
||||
bp++;
|
||||
break;
|
||||
}
|
||||
{
|
||||
if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0)
|
||||
{
|
||||
bp++;
|
||||
break;
|
||||
}
|
||||
bp1 = bp;
|
||||
}
|
||||
|
||||
/* Write only if there are more lines in the file than we want to
|
||||
truncate to. */
|
||||
|
@ -374,9 +423,9 @@ history_do_write (filename, nelements, overwrite)
|
|||
register int i;
|
||||
char *output;
|
||||
int file, mode, rv;
|
||||
#ifdef HISTORY_USE_MMAP
|
||||
size_t cursize;
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
mode = overwrite ? O_RDWR|O_CREAT|O_TRUNC|O_BINARY : O_RDWR|O_APPEND|O_BINARY;
|
||||
#else
|
||||
mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY;
|
||||
|
@ -390,7 +439,7 @@ history_do_write (filename, nelements, overwrite)
|
|||
return (errno);
|
||||
}
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
#ifdef HISTORY_USE_MMAP
|
||||
cursize = overwrite ? 0 : lseek (file, 0, SEEK_END);
|
||||
#endif
|
||||
|
||||
|
@ -408,10 +457,18 @@ history_do_write (filename, nelements, overwrite)
|
|||
the_history = history_list ();
|
||||
/* Calculate the total number of bytes to write. */
|
||||
for (buffer_size = 0, i = history_length - nelements; i < history_length; i++)
|
||||
buffer_size += 1 + strlen (the_history[i]->line);
|
||||
#if 0
|
||||
buffer_size += 2 + HISTENT_BYTES (the_history[i]);
|
||||
#else
|
||||
{
|
||||
if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0])
|
||||
buffer_size += strlen (the_history[i]->timestamp) + 1;
|
||||
buffer_size += strlen (the_history[i]->line) + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allocate the buffer, and fill it. */
|
||||
#ifdef HAVE_MMAP
|
||||
#ifdef HISTORY_USE_MMAP
|
||||
if (ftruncate (file, buffer_size+cursize) == -1)
|
||||
goto mmap_error;
|
||||
buffer = (char *)mmap (0, buffer_size, PROT_READ|PROT_WRITE, MAP_WFLAGS, file, cursize);
|
||||
|
@ -436,12 +493,18 @@ mmap_error:
|
|||
|
||||
for (j = 0, i = history_length - nelements; i < history_length; i++)
|
||||
{
|
||||
if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0])
|
||||
{
|
||||
strcpy (buffer + j, the_history[i]->timestamp);
|
||||
j += strlen (the_history[i]->timestamp);
|
||||
buffer[j++] = '\n';
|
||||
}
|
||||
strcpy (buffer + j, the_history[i]->line);
|
||||
j += strlen (the_history[i]->line);
|
||||
buffer[j++] = '\n';
|
||||
}
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
#ifdef HISTORY_USE_MMAP
|
||||
if (msync (buffer, buffer_size, 0) != 0 || munmap (buffer, buffer_size) != 0)
|
||||
rv = errno;
|
||||
#else
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* History.c -- standalone history library */
|
||||
/* history.c -- standalone history library */
|
||||
|
||||
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1989-2003 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the GNU History Library (the Library), a set of
|
||||
routines for managing the text of previously typed lines.
|
||||
|
@ -52,6 +52,8 @@
|
|||
/* The number of slots to increase the_history by. */
|
||||
#define DEFAULT_HISTORY_GROW_SIZE 50
|
||||
|
||||
static char *hist_inittime PARAMS((void));
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* History Functions */
|
||||
|
@ -123,14 +125,15 @@ using_history ()
|
|||
}
|
||||
|
||||
/* Return the number of bytes that the primary history entries are using.
|
||||
This just adds up the lengths of the_history->lines. */
|
||||
This just adds up the lengths of the_history->lines and the associated
|
||||
timestamps. */
|
||||
int
|
||||
history_total_bytes ()
|
||||
{
|
||||
register int i, result;
|
||||
|
||||
for (i = result = 0; the_history && the_history[i]; i++)
|
||||
result += strlen (the_history[i]->line);
|
||||
result += HISTENT_BYTES (the_history[i]);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
@ -206,6 +209,40 @@ history_get (offset)
|
|||
: the_history[local_index];
|
||||
}
|
||||
|
||||
time_t
|
||||
history_get_time (hist)
|
||||
HIST_ENTRY *hist;
|
||||
{
|
||||
char *ts;
|
||||
time_t t;
|
||||
|
||||
if (hist == 0 || hist->timestamp == 0)
|
||||
return 0;
|
||||
ts = hist->timestamp;
|
||||
if (ts[0] != history_comment_char)
|
||||
return 0;
|
||||
t = (time_t) atol (ts + 1); /* XXX - should use strtol() here */
|
||||
return t;
|
||||
}
|
||||
|
||||
static char *
|
||||
hist_inittime ()
|
||||
{
|
||||
time_t t;
|
||||
char ts[64], *ret;
|
||||
|
||||
t = (time_t) time ((time_t *)0);
|
||||
#if defined (HAVE_VSNPRINTF) /* assume snprintf if vsnprintf exists */
|
||||
snprintf (ts, sizeof (ts) - 1, "X%lu", (unsigned long) t);
|
||||
#else
|
||||
sprintf (ts, "X%lu", (unsigned long) t);
|
||||
#endif
|
||||
ret = savestring (ts);
|
||||
ret[0] = history_comment_char;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Place STRING at the end of the history list. The data field
|
||||
is set to NULL. */
|
||||
void
|
||||
|
@ -225,10 +262,7 @@ add_history (string)
|
|||
|
||||
/* If there is something in the slot, then remove it. */
|
||||
if (the_history[0])
|
||||
{
|
||||
free (the_history[0]->line);
|
||||
free (the_history[0]);
|
||||
}
|
||||
(void) free_history_entry (the_history[0]);
|
||||
|
||||
/* Copy the rest of the entries, moving down one slot. */
|
||||
for (i = 0; i < history_length; i++)
|
||||
|
@ -260,10 +294,41 @@ add_history (string)
|
|||
temp->line = savestring (string);
|
||||
temp->data = (char *)NULL;
|
||||
|
||||
temp->timestamp = hist_inittime ();
|
||||
|
||||
the_history[history_length] = (HIST_ENTRY *)NULL;
|
||||
the_history[history_length - 1] = temp;
|
||||
}
|
||||
|
||||
/* Change the time stamp of the most recent history entry to STRING. */
|
||||
void
|
||||
add_history_time (string)
|
||||
const char *string;
|
||||
{
|
||||
HIST_ENTRY *hs;
|
||||
|
||||
hs = the_history[history_length - 1];
|
||||
FREE (hs->timestamp);
|
||||
hs->timestamp = savestring (string);
|
||||
}
|
||||
|
||||
/* Free HIST and return the data so the calling application can free it
|
||||
if necessary and desired. */
|
||||
histdata_t
|
||||
free_history_entry (hist)
|
||||
HIST_ENTRY *hist;
|
||||
{
|
||||
histdata_t x;
|
||||
|
||||
if (hist == 0)
|
||||
return ((histdata_t) 0);
|
||||
FREE (hist->line);
|
||||
FREE (hist->timestamp);
|
||||
x = hist->data;
|
||||
free (hist);
|
||||
return (x);
|
||||
}
|
||||
|
||||
/* Make the history entry at WHICH have LINE and DATA. This returns
|
||||
the old entry so you can dispose of the data. In the case of an
|
||||
invalid WHICH, a NULL pointer is returned. */
|
||||
|
@ -283,6 +348,7 @@ replace_history_entry (which, line, data)
|
|||
|
||||
temp->line = savestring (line);
|
||||
temp->data = data;
|
||||
temp->timestamp = savestring (old_value->timestamp);
|
||||
the_history[which] = temp;
|
||||
|
||||
return (old_value);
|
||||
|
@ -327,10 +393,7 @@ stifle_history (max)
|
|||
{
|
||||
/* This loses because we cannot free the data. */
|
||||
for (i = 0, j = history_length - max; i < j; i++)
|
||||
{
|
||||
free (the_history[i]->line);
|
||||
free (the_history[i]);
|
||||
}
|
||||
free_history_entry (the_history[i]);
|
||||
|
||||
history_base = i;
|
||||
for (j = 0, i = history_length - max; j < max; i++, j++)
|
||||
|
@ -372,8 +435,7 @@ clear_history ()
|
|||
/* This loses because we cannot free the data. */
|
||||
for (i = 0; i < history_length; i++)
|
||||
{
|
||||
free (the_history[i]->line);
|
||||
free (the_history[i]);
|
||||
free_history_entry (the_history[i]);
|
||||
the_history[i] = (HIST_ENTRY *)NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* History.h -- the names of functions that you can call in history. */
|
||||
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
|
||||
/* history.h -- the names of functions that you can call in history. */
|
||||
/* Copyright (C) 1989-2003 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the GNU History Library (the Library), a set of
|
||||
routines for managing the text of previously typed lines.
|
||||
|
@ -26,6 +26,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <time.h> /* XXX - for history timestamp code */
|
||||
|
||||
#if defined READLINE_LIBRARY
|
||||
# include "rlstdc.h"
|
||||
# include "rltypedefs.h"
|
||||
|
@ -43,9 +45,13 @@ typedef char *histdata_t;
|
|||
/* The structure used to store a history entry. */
|
||||
typedef struct _hist_entry {
|
||||
char *line;
|
||||
char *timestamp; /* char * rather than time_t for read/write */
|
||||
histdata_t data;
|
||||
} HIST_ENTRY;
|
||||
|
||||
/* Size of the history-library-managed space in history entry HS. */
|
||||
#define HISTENT_BYTES(hs) (strlen ((hs)->line) + strlen ((hs)->timestamp))
|
||||
|
||||
/* A structure used to pass the current state of the history stuff around. */
|
||||
typedef struct _hist_state {
|
||||
HIST_ENTRY **entries; /* Pointer to the entries themselves. */
|
||||
|
@ -76,11 +82,19 @@ extern void history_set_history_state PARAMS((HISTORY_STATE *));
|
|||
The associated data field (if any) is set to NULL. */
|
||||
extern void add_history PARAMS((const char *));
|
||||
|
||||
/* Change the timestamp associated with the most recent history entry to
|
||||
STRING. */
|
||||
extern void add_history_time PARAMS((const char *));
|
||||
|
||||
/* A reasonably useless function, only here for completeness. WHICH
|
||||
is the magic number that tells us which element to delete. The
|
||||
elements are numbered from 0. */
|
||||
extern HIST_ENTRY *remove_history PARAMS((int));
|
||||
|
||||
/* Free the history entry H and return any application-specific data
|
||||
associated with it. */
|
||||
extern histdata_t free_history_entry PARAMS((HIST_ENTRY *));
|
||||
|
||||
/* Make the history entry at WHICH have LINE and DATA. This returns
|
||||
the old entry so you can dispose of the data. In the case of an
|
||||
invalid WHICH, a NULL pointer is returned. */
|
||||
|
@ -119,6 +133,10 @@ extern HIST_ENTRY *current_history PARAMS((void));
|
|||
array. OFFSET is relative to history_base. */
|
||||
extern HIST_ENTRY *history_get PARAMS((int));
|
||||
|
||||
/* Return the timestamp associated with the HIST_ENTRY * passed as an
|
||||
argument */
|
||||
extern time_t history_get_time PARAMS((HIST_ENTRY *));
|
||||
|
||||
/* Return the number of bytes that the primary history entries are using.
|
||||
This just adds up the lengths of the_history->lines. */
|
||||
extern int history_total_bytes PARAMS((void));
|
||||
|
@ -231,6 +249,8 @@ extern char *history_no_expand_chars;
|
|||
extern char *history_search_delimiter_chars;
|
||||
extern int history_quotes_inhibit_expansion;
|
||||
|
||||
extern int history_write_timestamps;
|
||||
|
||||
/* Backwards compatibility */
|
||||
extern int max_input_history;
|
||||
|
||||
|
|
|
@ -77,11 +77,11 @@ history_search_internal (string, direction, anchored)
|
|||
if (string == 0 || *string == '\0')
|
||||
return (-1);
|
||||
|
||||
if (!history_length || ((i == history_length) && !reverse))
|
||||
if (!history_length || ((i >= history_length) && !reverse))
|
||||
return (-1);
|
||||
|
||||
if (reverse && (i == history_length))
|
||||
i--;
|
||||
if (reverse && (i >= history_length))
|
||||
i = history_length - 1;
|
||||
|
||||
#define NEXT_LINE() do { if (reverse) i--; else i++; } while (0)
|
||||
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (__TANDEM)
|
||||
# include <floss.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
@ -154,6 +158,12 @@ _rl_unget_char (key)
|
|||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_rl_pushed_input_available ()
|
||||
{
|
||||
return (push_index != pop_index);
|
||||
}
|
||||
|
||||
/* If a character is available to be read, then read it and stuff it into
|
||||
IBUFFER. Otherwise, just return. Returns number of characters read
|
||||
(0 if none available) and -1 on error (EIO). */
|
||||
|
@ -162,7 +172,7 @@ rl_gather_tyi ()
|
|||
{
|
||||
int tty;
|
||||
register int tem, result;
|
||||
int chars_avail;
|
||||
int chars_avail, k;
|
||||
char input;
|
||||
#if defined(HAVE_SELECT)
|
||||
fd_set readfds, exceptfds;
|
||||
|
@ -202,6 +212,11 @@ rl_gather_tyi ()
|
|||
fcntl (tty, F_SETFL, tem);
|
||||
if (chars_avail == -1 && errno == EAGAIN)
|
||||
return 0;
|
||||
if (chars_avail == 0) /* EOF */
|
||||
{
|
||||
rl_stuff_char (EOF);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
#endif /* O_NDELAY */
|
||||
|
||||
|
@ -225,7 +240,12 @@ rl_gather_tyi ()
|
|||
if (result != -1)
|
||||
{
|
||||
while (chars_avail--)
|
||||
rl_stuff_char ((*rl_getc_function) (rl_instream));
|
||||
{
|
||||
k = (*rl_getc_function) (rl_instream);
|
||||
rl_stuff_char (k);
|
||||
if (k == NEWLINE || k == RETURN)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -64,11 +64,13 @@ rl_make_bare_keymap ()
|
|||
keymap[i].function = (rl_command_func_t *)NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
for (i = 'A'; i < ('Z' + 1); i++)
|
||||
{
|
||||
keymap[i].type = ISFUNC;
|
||||
keymap[i].function = rl_do_lowercase_version;
|
||||
}
|
||||
#endif
|
||||
|
||||
return (keymap);
|
||||
}
|
||||
|
@ -79,8 +81,9 @@ rl_copy_keymap (map)
|
|||
Keymap map;
|
||||
{
|
||||
register int i;
|
||||
Keymap temp = rl_make_bare_keymap ();
|
||||
Keymap temp;
|
||||
|
||||
temp = rl_make_bare_keymap ();
|
||||
for (i = 0; i < KEYMAP_SIZE; i++)
|
||||
{
|
||||
temp[i].type = map[i].type;
|
||||
|
@ -109,12 +112,8 @@ rl_make_keymap ()
|
|||
newmap[CTRL('H')].function = rl_rubout;
|
||||
|
||||
#if KEYMAP_SIZE > 128
|
||||
/* Printing characters in some 8-bit character sets. */
|
||||
for (i = 128; i < 160; i++)
|
||||
newmap[i].function = rl_insert;
|
||||
|
||||
/* ISO Latin-1 printing characters should self-insert. */
|
||||
for (i = 160; i < 256; i++)
|
||||
/* Printing characters in ISO Latin-1 and some 8-bit character sets. */
|
||||
for (i = 128; i < 256; i++)
|
||||
newmap[i].function = rl_insert;
|
||||
#endif /* KEYMAP_SIZE > 128 */
|
||||
|
||||
|
|
|
@ -339,6 +339,47 @@ rl_unix_word_rubout (count, key)
|
|||
if (rl_editing_mode == emacs_mode)
|
||||
rl_mark = rl_point;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This deletes one filename component in a Unix pathname. That is, it
|
||||
deletes backward to directory separator (`/') or whitespace. */
|
||||
int
|
||||
rl_unix_filename_rubout (count, key)
|
||||
int count, key;
|
||||
{
|
||||
int orig_point, c;
|
||||
|
||||
if (rl_point == 0)
|
||||
rl_ding ();
|
||||
else
|
||||
{
|
||||
orig_point = rl_point;
|
||||
if (count <= 0)
|
||||
count = 1;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
c = rl_line_buffer[rl_point - 1];
|
||||
while (rl_point && (whitespace (c) || c == '/'))
|
||||
{
|
||||
rl_point--;
|
||||
c = rl_line_buffer[rl_point - 1];
|
||||
}
|
||||
|
||||
while (rl_point && (whitespace (c) == 0) && c != '/')
|
||||
{
|
||||
rl_point--;
|
||||
c = rl_line_buffer[rl_point - 1];
|
||||
}
|
||||
}
|
||||
|
||||
rl_kill_text (orig_point, rl_point);
|
||||
if (rl_editing_mode == emacs_mode)
|
||||
rl_mark = rl_point;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* mbutil.c -- readline multibyte character utility functions */
|
||||
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001-2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
@ -92,12 +92,12 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero)
|
|||
/* if this is true, means that seed was not pointed character
|
||||
started byte. So correct the point and consume count */
|
||||
if (seed < point)
|
||||
count --;
|
||||
count--;
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
tmp = mbrtowc (&wc, string+point, strlen(string + point), &ps);
|
||||
if ((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
|
||||
if (MB_INVALIDCH ((size_t)tmp))
|
||||
{
|
||||
/* invalid bytes. asume a byte represents a character */
|
||||
point++;
|
||||
|
@ -105,9 +105,8 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero)
|
|||
/* reset states. */
|
||||
memset(&ps, 0, sizeof(mbstate_t));
|
||||
}
|
||||
else if (tmp == (size_t)0)
|
||||
/* found '\0' char */
|
||||
break;
|
||||
else if (MB_NULLWCH (tmp))
|
||||
break; /* found wide '\0' */
|
||||
else
|
||||
{
|
||||
/* valid bytes */
|
||||
|
@ -160,7 +159,7 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero)
|
|||
while (point < seed)
|
||||
{
|
||||
tmp = mbrtowc (&wc, string + point, length - point, &ps);
|
||||
if ((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
|
||||
if (MB_INVALIDCH ((size_t)tmp))
|
||||
{
|
||||
/* in this case, bytes are invalid or shorted to compose
|
||||
multibyte char, so assume that the first byte represents
|
||||
|
@ -169,8 +168,12 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero)
|
|||
/* clear the state of the byte sequence, because
|
||||
in this case effect of mbstate is undefined */
|
||||
memset(&ps, 0, sizeof (mbstate_t));
|
||||
|
||||
/* Since we're assuming that this byte represents a single
|
||||
non-zero-width character, don't forget about it. */
|
||||
prev = point;
|
||||
}
|
||||
else if (tmp == 0)
|
||||
else if (MB_NULLWCH (tmp))
|
||||
break; /* Found '\0' char. Can this happen? */
|
||||
else
|
||||
{
|
||||
|
@ -205,14 +208,16 @@ _rl_get_char_len (src, ps)
|
|||
if (tmp == (size_t)(-2))
|
||||
{
|
||||
/* shorted to compose multibyte char */
|
||||
memset (ps, 0, sizeof(mbstate_t));
|
||||
if (ps)
|
||||
memset (ps, 0, sizeof(mbstate_t));
|
||||
return -2;
|
||||
}
|
||||
else if (tmp == (size_t)(-1))
|
||||
{
|
||||
/* invalid to compose multibyte char */
|
||||
/* initialize the conversion state */
|
||||
memset (ps, 0, sizeof(mbstate_t));
|
||||
if (ps)
|
||||
memset (ps, 0, sizeof(mbstate_t));
|
||||
return -1;
|
||||
}
|
||||
else if (tmp == (size_t)0)
|
||||
|
@ -225,9 +230,12 @@ _rl_get_char_len (src, ps)
|
|||
return 1. Otherwise return 0. */
|
||||
int
|
||||
_rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2)
|
||||
char *buf1, *buf2;
|
||||
mbstate_t *ps1, *ps2;
|
||||
int pos1, pos2;
|
||||
char *buf1;
|
||||
int pos1;
|
||||
mbstate_t *ps1;
|
||||
char *buf2;
|
||||
int pos2;
|
||||
mbstate_t *ps2;
|
||||
{
|
||||
int i, w1, w2;
|
||||
|
||||
|
@ -268,7 +276,7 @@ _rl_adjust_point(string, point, ps)
|
|||
while (pos < point)
|
||||
{
|
||||
tmp = mbrlen (string + pos, length - pos, ps);
|
||||
if((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
|
||||
if (MB_INVALIDCH ((size_t)tmp))
|
||||
{
|
||||
/* in this case, bytes are invalid or shorted to compose
|
||||
multibyte char, so assume that the first byte represents
|
||||
|
@ -276,8 +284,11 @@ _rl_adjust_point(string, point, ps)
|
|||
pos++;
|
||||
/* clear the state of the byte sequence, because
|
||||
in this case effect of mbstate is undefined */
|
||||
memset (ps, 0, sizeof (mbstate_t));
|
||||
if (ps)
|
||||
memset (ps, 0, sizeof (mbstate_t));
|
||||
}
|
||||
else if (MB_NULLWCH (tmp))
|
||||
pos++;
|
||||
else
|
||||
pos += tmp;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* misc.c -- miscellaneous bindable readline functions. */
|
||||
|
||||
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
@ -253,6 +253,8 @@ rl_maybe_unsave_line ()
|
|||
{
|
||||
if (_rl_saved_line_for_history)
|
||||
{
|
||||
/* Can't call with `1' because rl_undo_list might point to an undo
|
||||
list from a history entry, as in rl_replace_from_history() below. */
|
||||
rl_replace_line (_rl_saved_line_for_history->line, 0);
|
||||
rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
|
||||
_rl_free_history_entry (_rl_saved_line_for_history);
|
||||
|
@ -274,6 +276,13 @@ rl_maybe_save_line ()
|
|||
_rl_saved_line_for_history->line = savestring (rl_line_buffer);
|
||||
_rl_saved_line_for_history->data = (char *)rl_undo_list;
|
||||
}
|
||||
else if (STREQ (rl_line_buffer, _rl_saved_line_for_history->line) == 0)
|
||||
{
|
||||
free (_rl_saved_line_for_history->line);
|
||||
_rl_saved_line_for_history->line = savestring (rl_line_buffer);
|
||||
_rl_saved_line_for_history->data = (char *)rl_undo_list; /* XXX possible memleak */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -298,7 +307,7 @@ _rl_history_set_point ()
|
|||
rl_point = rl_end;
|
||||
|
||||
#if defined (VI_MODE)
|
||||
if (rl_editing_mode == vi_mode)
|
||||
if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
|
||||
rl_point = 0;
|
||||
#endif /* VI_MODE */
|
||||
|
||||
|
@ -311,6 +320,8 @@ rl_replace_from_history (entry, flags)
|
|||
HIST_ENTRY *entry;
|
||||
int flags; /* currently unused */
|
||||
{
|
||||
/* Can't call with `1' because rl_undo_list might point to an undo list
|
||||
from a history entry, just like we're setting up here. */
|
||||
rl_replace_line (entry->line, 0);
|
||||
rl_undo_list = (UNDO_LIST *)entry->data;
|
||||
rl_point = rl_end;
|
||||
|
@ -435,6 +446,7 @@ rl_get_previous_history (count, key)
|
|||
rl_replace_from_history (temp, 0);
|
||||
_rl_history_set_point ();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -75,6 +75,23 @@ static char *normalize_codeset PARAMS((char *));
|
|||
static char *find_codeset PARAMS((char *, size_t *));
|
||||
#endif /* !HAVE_SETLOCALE */
|
||||
|
||||
static char *_rl_get_locale_var PARAMS((const char *));
|
||||
|
||||
static char *
|
||||
_rl_get_locale_var (v)
|
||||
const char *v;
|
||||
{
|
||||
char *lspec;
|
||||
|
||||
lspec = sh_get_env_value ("LC_ALL");
|
||||
if (lspec == 0 || *lspec == 0)
|
||||
lspec = sh_get_env_value (v);
|
||||
if (lspec == 0 || *lspec == 0)
|
||||
lspec = sh_get_env_value ("LANG");
|
||||
|
||||
return lspec;
|
||||
}
|
||||
|
||||
/* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value
|
||||
to decide the defaults for 8-bit character input and output. Returns
|
||||
1 if we set eight-bit mode. */
|
||||
|
@ -84,10 +101,21 @@ _rl_init_eightbit ()
|
|||
/* If we have setlocale(3), just check the current LC_CTYPE category
|
||||
value, and go into eight-bit mode if it's not C or POSIX. */
|
||||
#if defined (HAVE_SETLOCALE)
|
||||
char *t;
|
||||
char *lspec, *t;
|
||||
|
||||
/* Set the LC_CTYPE locale category from environment variables. */
|
||||
t = setlocale (LC_CTYPE, "");
|
||||
lspec = _rl_get_locale_var ("LC_CTYPE");
|
||||
/* Since _rl_get_locale_var queries the right environment variables,
|
||||
we query the current locale settings with setlocale(), and, if
|
||||
that doesn't return anything, we set lspec to the empty string to
|
||||
force the subsequent call to setlocale() to define the `native'
|
||||
environment. */
|
||||
if (lspec == 0 || *lspec == 0)
|
||||
lspec = setlocale (LC_CTYPE, (char *)NULL);
|
||||
if (lspec == 0)
|
||||
lspec = "";
|
||||
t = setlocale (LC_CTYPE, lspec);
|
||||
|
||||
if (t && *t && (t[0] != 'C' || t[1]) && (STREQ (t, "POSIX") == 0))
|
||||
{
|
||||
_rl_meta_flag = 1;
|
||||
|
@ -105,9 +133,8 @@ _rl_init_eightbit ()
|
|||
/* We don't have setlocale. Finesse it. Check the environment for the
|
||||
appropriate variables and set eight-bit mode if they have the right
|
||||
values. */
|
||||
lspec = sh_get_env_value ("LC_ALL");
|
||||
if (lspec == 0) lspec = sh_get_env_value ("LC_CTYPE");
|
||||
if (lspec == 0) lspec = sh_get_env_value ("LANG");
|
||||
lspec = _rl_get_locale_var ("LC_CTYPE");
|
||||
|
||||
if (lspec == 0 || (t = normalize_codeset (lspec)) == 0)
|
||||
return (0);
|
||||
for (i = 0; t && legal_lang_values[i]; i++)
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (__TANDEM)
|
||||
# include <floss.h>
|
||||
#endif
|
||||
|
||||
#include "rlconf.h"
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
|
|
|
@ -25,7 +25,11 @@
|
|||
|
||||
#if defined (HAVE_DIRENT_H)
|
||||
# include <dirent.h>
|
||||
# define D_NAMLEN(d) (strlen ((d)->d_name))
|
||||
# if defined (HAVE_STRUCT_DIRENT_D_NAMLEN)
|
||||
# define D_NAMLEN(d) ((d)->d_namlen)
|
||||
# else
|
||||
# define D_NAMLEN(d) (strlen ((d)->d_name))
|
||||
# endif /* !HAVE_STRUCT_DIRENT_D_NAMLEN */
|
||||
#else
|
||||
# if defined (HAVE_SYS_NDIR_H)
|
||||
# include <sys/ndir.h>
|
||||
|
@ -42,11 +46,11 @@
|
|||
# define D_NAMLEN(d) ((d)->d_namlen)
|
||||
#endif /* !HAVE_DIRENT_H */
|
||||
|
||||
#if defined (STRUCT_DIRENT_HAS_D_INO) && !defined (STRUCT_DIRENT_HAS_D_FILENO)
|
||||
#if defined (HAVE_STRUCT_DIRENT_D_INO) && !defined (HAVE_STRUCT_DIRENT_D_FILENO)
|
||||
# define d_fileno d_ino
|
||||
#endif
|
||||
|
||||
#if defined (_POSIX_SOURCE) && (!defined (STRUCT_DIRENT_HAS_D_INO) || defined (BROKEN_DIRENT_D_INO))
|
||||
#if defined (_POSIX_SOURCE) && (!defined (HAVE_STRUCT_DIRENT_D_INO) || defined (BROKEN_DIRENT_D_INO))
|
||||
/* Posix does not require that the d_ino field be present, and some
|
||||
systems do not provide it. */
|
||||
# define REAL_DIR_ENTRY(dp) 1
|
||||
|
|
|
@ -68,11 +68,11 @@
|
|||
#include "xmalloc.h"
|
||||
|
||||
#ifndef RL_LIBRARY_VERSION
|
||||
# define RL_LIBRARY_VERSION "4.3"
|
||||
# define RL_LIBRARY_VERSION "5.0"
|
||||
#endif
|
||||
|
||||
#ifndef RL_READLINE_VERSION
|
||||
# define RL_READLINE_VERSION 0x0403
|
||||
# define RL_READLINE_VERSION 0x0500
|
||||
#endif
|
||||
|
||||
extern void _rl_free_history_entry PARAMS((HIST_ENTRY *));
|
||||
|
@ -85,6 +85,7 @@ static void bind_arrow_keys_internal PARAMS((Keymap));
|
|||
static void bind_arrow_keys PARAMS((void));
|
||||
|
||||
static void readline_default_bindings PARAMS((void));
|
||||
static void reset_default_bindings PARAMS((void));
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
|
@ -347,7 +348,7 @@ readline_internal_setup ()
|
|||
|
||||
#if defined (VI_MODE)
|
||||
if (rl_editing_mode == vi_mode)
|
||||
rl_vi_insertion_mode (1, 0);
|
||||
rl_vi_insertion_mode (1, 'i');
|
||||
#endif /* VI_MODE */
|
||||
|
||||
if (rl_pre_input_hook)
|
||||
|
@ -650,7 +651,21 @@ _rl_dispatch_subseq (key, map, got_subseq)
|
|||
the function. The recursive call to _rl_dispatch_subseq has
|
||||
already taken care of pushing any necessary input back onto
|
||||
the input queue with _rl_unget_char. */
|
||||
r = _rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key));
|
||||
{
|
||||
#if 0
|
||||
r = _rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key));
|
||||
#else
|
||||
/* XXX - experimental code -- might never be executed. Save
|
||||
for later. */
|
||||
Keymap m = FUNCTION_TO_KEYMAP (map, key);
|
||||
int type = m[ANYOTHERKEY].type;
|
||||
func = m[ANYOTHERKEY].function;
|
||||
if (type == ISFUNC && func == rl_do_lowercase_version)
|
||||
r = _rl_dispatch (_rl_to_lower (key), map);
|
||||
else
|
||||
r = _rl_dispatch (ANYOTHERKEY, m);
|
||||
#endif
|
||||
}
|
||||
else if (r && map[ANYOTHERKEY].function)
|
||||
{
|
||||
/* We didn't match (r is probably -1), so return something to
|
||||
|
@ -684,6 +699,7 @@ _rl_dispatch_subseq (key, map, got_subseq)
|
|||
}
|
||||
#if defined (VI_MODE)
|
||||
if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap &&
|
||||
key != ANYOTHERKEY &&
|
||||
_rl_vi_textmod_command (key))
|
||||
_rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign);
|
||||
#endif
|
||||
|
@ -838,7 +854,7 @@ readline_initialize_everything ()
|
|||
/* If the completion parser's default word break characters haven't
|
||||
been set yet, then do so now. */
|
||||
if (rl_completer_word_break_characters == (char *)NULL)
|
||||
rl_completer_word_break_characters = rl_basic_word_break_characters;
|
||||
rl_completer_word_break_characters = (char *)rl_basic_word_break_characters;
|
||||
}
|
||||
|
||||
/* If this system allows us to look at the values of the regular
|
||||
|
@ -850,6 +866,15 @@ readline_default_bindings ()
|
|||
rl_tty_set_default_bindings (_rl_keymap);
|
||||
}
|
||||
|
||||
/* Reset the default bindings for the terminal special characters we're
|
||||
interested in back to rl_insert and read the new ones. */
|
||||
static void
|
||||
reset_default_bindings ()
|
||||
{
|
||||
rl_tty_unset_default_bindings (_rl_keymap);
|
||||
rl_tty_set_default_bindings (_rl_keymap);
|
||||
}
|
||||
|
||||
/* Bind some common arrow key sequences in MAP. */
|
||||
static void
|
||||
bind_arrow_keys_internal (map)
|
||||
|
@ -861,25 +886,25 @@ bind_arrow_keys_internal (map)
|
|||
_rl_keymap = map;
|
||||
|
||||
#if defined (__MSDOS__)
|
||||
_rl_bind_if_unbound ("\033[0A", rl_get_previous_history);
|
||||
_rl_bind_if_unbound ("\033[0B", rl_backward_char);
|
||||
_rl_bind_if_unbound ("\033[0C", rl_forward_char);
|
||||
_rl_bind_if_unbound ("\033[0D", rl_get_next_history);
|
||||
rl_bind_keyseq_if_unbound ("\033[0A", rl_get_previous_history);
|
||||
rl_bind_keyseq_if_unbound ("\033[0B", rl_backward_char);
|
||||
rl_bind_keyseq_if_unbound ("\033[0C", rl_forward_char);
|
||||
rl_bind_keyseq_if_unbound ("\033[0D", rl_get_next_history);
|
||||
#endif
|
||||
|
||||
_rl_bind_if_unbound ("\033[A", rl_get_previous_history);
|
||||
_rl_bind_if_unbound ("\033[B", rl_get_next_history);
|
||||
_rl_bind_if_unbound ("\033[C", rl_forward_char);
|
||||
_rl_bind_if_unbound ("\033[D", rl_backward_char);
|
||||
_rl_bind_if_unbound ("\033[H", rl_beg_of_line);
|
||||
_rl_bind_if_unbound ("\033[F", rl_end_of_line);
|
||||
rl_bind_keyseq_if_unbound ("\033[A", rl_get_previous_history);
|
||||
rl_bind_keyseq_if_unbound ("\033[B", rl_get_next_history);
|
||||
rl_bind_keyseq_if_unbound ("\033[C", rl_forward_char);
|
||||
rl_bind_keyseq_if_unbound ("\033[D", rl_backward_char);
|
||||
rl_bind_keyseq_if_unbound ("\033[H", rl_beg_of_line);
|
||||
rl_bind_keyseq_if_unbound ("\033[F", rl_end_of_line);
|
||||
|
||||
_rl_bind_if_unbound ("\033OA", rl_get_previous_history);
|
||||
_rl_bind_if_unbound ("\033OB", rl_get_next_history);
|
||||
_rl_bind_if_unbound ("\033OC", rl_forward_char);
|
||||
_rl_bind_if_unbound ("\033OD", rl_backward_char);
|
||||
_rl_bind_if_unbound ("\033OH", rl_beg_of_line);
|
||||
_rl_bind_if_unbound ("\033OF", rl_end_of_line);
|
||||
rl_bind_keyseq_if_unbound ("\033OA", rl_get_previous_history);
|
||||
rl_bind_keyseq_if_unbound ("\033OB", rl_get_next_history);
|
||||
rl_bind_keyseq_if_unbound ("\033OC", rl_forward_char);
|
||||
rl_bind_keyseq_if_unbound ("\033OD", rl_backward_char);
|
||||
rl_bind_keyseq_if_unbound ("\033OH", rl_beg_of_line);
|
||||
rl_bind_keyseq_if_unbound ("\033OF", rl_end_of_line);
|
||||
|
||||
_rl_keymap = xkeymap;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Readline.h -- the names of functions callable from within readline. */
|
||||
|
||||
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
@ -40,9 +40,9 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
/* Hex-encoded Readline version number. */
|
||||
#define RL_READLINE_VERSION 0x0403 /* Readline 4.3 */
|
||||
#define RL_VERSION_MAJOR 4
|
||||
#define RL_VERSION_MINOR 3
|
||||
#define RL_READLINE_VERSION 0x0500 /* Readline 5.0 */
|
||||
#define RL_VERSION_MAJOR 5
|
||||
#define RL_VERSION_MINOR 0
|
||||
|
||||
/* Readline data structures. */
|
||||
|
||||
|
@ -160,6 +160,7 @@ extern int rl_kill_line PARAMS((int, int));
|
|||
extern int rl_backward_kill_line PARAMS((int, int));
|
||||
extern int rl_kill_full_line PARAMS((int, int));
|
||||
extern int rl_unix_word_rubout PARAMS((int, int));
|
||||
extern int rl_unix_filename_rubout PARAMS((int, int));
|
||||
extern int rl_unix_line_discard PARAMS((int, int));
|
||||
extern int rl_copy_region_to_kill PARAMS((int, int));
|
||||
extern int rl_kill_region PARAMS((int, int));
|
||||
|
@ -258,6 +259,8 @@ extern int rl_vi_check PARAMS((void));
|
|||
extern int rl_vi_domove PARAMS((int, int *));
|
||||
extern int rl_vi_bracktype PARAMS((int));
|
||||
|
||||
extern void rl_vi_start_inserting PARAMS((int, int, int));
|
||||
|
||||
/* VI-mode pseudo-bindable commands, used as utility functions. */
|
||||
extern int rl_vi_fWord PARAMS((int, int));
|
||||
extern int rl_vi_bWord PARAMS((int, int));
|
||||
|
@ -290,12 +293,20 @@ extern int rl_bind_key PARAMS((int, rl_command_func_t *));
|
|||
extern int rl_bind_key_in_map PARAMS((int, rl_command_func_t *, Keymap));
|
||||
extern int rl_unbind_key PARAMS((int));
|
||||
extern int rl_unbind_key_in_map PARAMS((int, Keymap));
|
||||
extern int rl_bind_key_if_unbound PARAMS((int, rl_command_func_t *));
|
||||
extern int rl_bind_key_if_unbound_in_map PARAMS((int, rl_command_func_t *, Keymap));
|
||||
extern int rl_unbind_function_in_map PARAMS((rl_command_func_t *, Keymap));
|
||||
extern int rl_unbind_command_in_map PARAMS((const char *, Keymap));
|
||||
extern int rl_set_key PARAMS((const char *, rl_command_func_t *, Keymap));
|
||||
extern int rl_bind_keyseq PARAMS((const char *, rl_command_func_t *));
|
||||
extern int rl_bind_keyseq_in_map PARAMS((const char *, rl_command_func_t *, Keymap));
|
||||
extern int rl_bind_keyseq_if_unbound PARAMS((const char *, rl_command_func_t *));
|
||||
extern int rl_bind_keyseq_if_unbound_in_map PARAMS((const char *, rl_command_func_t *, Keymap));
|
||||
extern int rl_generic_bind PARAMS((int, const char *, char *, Keymap));
|
||||
extern int rl_variable_bind PARAMS((const char *, const char *));
|
||||
|
||||
/* Backwards compatibility, use rl_bind_keyseq_in_map instead. */
|
||||
extern int rl_set_key PARAMS((const char *, rl_command_func_t *, Keymap));
|
||||
|
||||
/* Backwards compatibility, use rl_generic_bind instead. */
|
||||
extern int rl_macro_bind PARAMS((const char *, const char *, Keymap));
|
||||
|
||||
|
@ -358,7 +369,7 @@ extern int rl_clear_message PARAMS((void));
|
|||
extern int rl_reset_line_state PARAMS((void));
|
||||
extern int rl_crlf PARAMS((void));
|
||||
|
||||
#if (defined (__STDC__) || defined (__cplusplus)) && defined (USE_VARARGS) && defined (PREFER_STDARG)
|
||||
#if defined (USE_VARARGS) && defined (PREFER_STDARG)
|
||||
extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
|
||||
#else
|
||||
extern int rl_message ();
|
||||
|
@ -384,6 +395,7 @@ extern char *rl_copy_text PARAMS((int, int));
|
|||
extern void rl_prep_terminal PARAMS((int));
|
||||
extern void rl_deprep_terminal PARAMS((void));
|
||||
extern void rl_tty_set_default_bindings PARAMS((Keymap));
|
||||
extern void rl_tty_unset_default_bindings PARAMS((Keymap));
|
||||
|
||||
extern int rl_reset_terminal PARAMS((const char *));
|
||||
extern void rl_resize_terminal PARAMS((void));
|
||||
|
@ -603,7 +615,12 @@ extern const char *rl_basic_word_break_characters;
|
|||
/* The list of characters that signal a break between words for
|
||||
rl_complete_internal. The default list is the contents of
|
||||
rl_basic_word_break_characters. */
|
||||
extern const char *rl_completer_word_break_characters;
|
||||
extern /*const*/ char *rl_completer_word_break_characters;
|
||||
|
||||
/* Hook function to allow an application to set the completion word
|
||||
break characters before readline breaks up the line. Allows
|
||||
position-dependent word break characters. */
|
||||
extern rl_cpvfunc_t *rl_completion_word_break_hook;
|
||||
|
||||
/* List of characters which can be used to quote a substring of the line.
|
||||
Completion occurs on the entire substring, and within the substring
|
||||
|
@ -687,6 +704,11 @@ extern int rl_attempted_completion_over;
|
|||
functions. */
|
||||
extern int rl_completion_type;
|
||||
|
||||
/* Up to this many items will be displayed in response to a
|
||||
possible-completions call. After that, we ask the user if she
|
||||
is sure she wants to see them all. The default value is 100. */
|
||||
extern int rl_completion_query_items;
|
||||
|
||||
/* Character appended to completed words when at the end of the line. The
|
||||
default is a space. Nothing is added if this is '\0'. */
|
||||
extern int rl_completion_append_character;
|
||||
|
@ -695,10 +717,18 @@ extern int rl_completion_append_character;
|
|||
rl_completion_append_character will not be appended. */
|
||||
extern int rl_completion_suppress_append;
|
||||
|
||||
/* Up to this many items will be displayed in response to a
|
||||
possible-completions call. After that, we ask the user if she
|
||||
is sure she wants to see them all. The default value is 100. */
|
||||
extern int rl_completion_query_items;
|
||||
/* Set to any quote character readline thinks it finds before any application
|
||||
completion function is called. */
|
||||
extern int rl_completion_quote_character;
|
||||
|
||||
/* Set to a non-zero value if readline found quoting anywhere in the word to
|
||||
be completed; set before any application completion function is called. */
|
||||
extern int rl_completion_found_quote;
|
||||
|
||||
/* If non-zero, the completion functions don't append any closing quote.
|
||||
This is set to 0 by rl_complete_internal and may be changed by an
|
||||
application-specific completion function. */
|
||||
extern int rl_completion_suppress_quote;
|
||||
|
||||
/* If non-zero, a slash will be appended to completed filenames that are
|
||||
symbolic links to directory names, subject to the value of the
|
||||
|
@ -749,6 +779,7 @@ extern int rl_inhibit_completion;
|
|||
#define RL_STATE_SIGHANDLER 0x08000 /* in readline sighandler */
|
||||
#define RL_STATE_UNDOING 0x10000 /* doing an undo */
|
||||
#define RL_STATE_INPUTPENDING 0x20000 /* rl_execute_next called */
|
||||
#define RL_STATE_TTYCSAVED 0x40000 /* tty special chars saved */
|
||||
|
||||
#define RL_STATE_DONE 0x80000 /* done; accepted line */
|
||||
|
||||
|
@ -785,6 +816,12 @@ struct readline_state {
|
|||
int catchsigs;
|
||||
int catchsigwinch;
|
||||
|
||||
/* search state */
|
||||
|
||||
/* completion state */
|
||||
|
||||
/* options state */
|
||||
|
||||
/* reserved for future expansion, so the struct size doesn't change */
|
||||
char reserved[64];
|
||||
};
|
||||
|
|
|
@ -77,7 +77,7 @@ extern int _rl_stricmp PARAMS((char *, char *));
|
|||
extern int _rl_strnicmp PARAMS((char *, char *, int));
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_STRPBRK)
|
||||
#if defined (HAVE_STRPBRK) && !defined (HAVE_MULTIBYTE)
|
||||
# define _rl_strpbrk(a,b) strpbrk((a),(b))
|
||||
#else
|
||||
extern char *_rl_strpbrk PARAMS((const char *, const char *));
|
||||
|
|
|
@ -35,11 +35,18 @@
|
|||
#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H)
|
||||
# include <wchar.h>
|
||||
# include <wctype.h>
|
||||
# if defined (HAVE_MBSRTOWCS) /* system is supposed to support XPG5 */
|
||||
# if defined (HAVE_MBSRTOWCS) && defined (HAVE_MBRTOWC) && defined (HAVE_MBRLEN) && defined (HAVE_WCWIDTH)
|
||||
/* system is supposed to support XPG5 */
|
||||
# define HANDLE_MULTIBYTE 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* If we don't want multibyte chars even on a system that supports them, let
|
||||
the configuring user turn multibyte support off. */
|
||||
#if defined (NO_MULTIBYTE_SUPPORT)
|
||||
# undef HANDLE_MULTIBYTE
|
||||
#endif
|
||||
|
||||
/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
|
||||
#if HANDLE_MULTIBYTE && !defined (HAVE_MBSTATE_T)
|
||||
# define wcsrtombs(dest, src, len, ps) (wcsrtombs) (dest, src, len, 0)
|
||||
|
@ -90,6 +97,9 @@ extern int _rl_read_mbstring PARAMS((int, char *, int));
|
|||
|
||||
extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int));
|
||||
|
||||
#define MB_INVALIDCH(x) ((x) == (size_t)-1 || (x) == (size_t)-2)
|
||||
#define MB_NULLWCH(x) ((x) == 0)
|
||||
|
||||
#else /* !HANDLE_MULTIBYTE */
|
||||
|
||||
#undef MB_LEN_MAX
|
||||
|
@ -101,6 +111,9 @@ extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int));
|
|||
#define _rl_find_prev_mbchar(b, i, f) (((i) == 0) ? (i) : ((i) - 1))
|
||||
#define _rl_find_next_mbchar(b, i1, i2, f) ((i1) + (i2))
|
||||
|
||||
#define MB_INVALIDCH(x) (0)
|
||||
#define MB_NULLWCH(x) (0)
|
||||
|
||||
#endif /* !HANDLE_MULTIBYTE */
|
||||
|
||||
extern int rl_byte_oriented;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue