mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-06 15:24:56 +08:00
Clean up ts_locale.h/.c. Fix broken and not-consistent-across-platforms
behavior of wchar2char/char2wchar; this should resolve bug #3730. Avoid excess computations of pg_mblen in t_isalpha and friends. Const-ify APIs where possible.
This commit is contained in:
parent
83290b678d
commit
654dcfb9e4
@ -1,13 +1,13 @@
|
|||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* ts_locale.c
|
* ts_locale.c
|
||||||
* locale compatiblility layer for tsearch
|
* locale compatibility layer for tsearch
|
||||||
*
|
*
|
||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/tsearch/ts_locale.c,v 1.2 2007/08/25 00:03:59 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/tsearch/ts_locale.c,v 1.3 2007/11/09 22:37:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -16,41 +16,56 @@
|
|||||||
#include "tsearch/ts_locale.h"
|
#include "tsearch/ts_locale.h"
|
||||||
#include "tsearch/ts_public.h"
|
#include "tsearch/ts_public.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef TS_USE_WIDE
|
#ifdef TS_USE_WIDE
|
||||||
|
|
||||||
#ifdef WIN32
|
/*
|
||||||
|
* wchar2char --- convert wide characters to multibyte format
|
||||||
|
*
|
||||||
|
* This has the same API as the standard wcstombs() function; in particular,
|
||||||
|
* tolen is the maximum number of bytes to store at *to, and *from should be
|
||||||
|
* zero-terminated. The output will be zero-terminated iff there is room.
|
||||||
|
*/
|
||||||
size_t
|
size_t
|
||||||
wchar2char(char *to, const wchar_t *from, size_t len)
|
wchar2char(char *to, const wchar_t *from, size_t tolen)
|
||||||
{
|
{
|
||||||
if (len == 0)
|
if (tolen == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
if (GetDatabaseEncoding() == PG_UTF8)
|
if (GetDatabaseEncoding() == PG_UTF8)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = WideCharToMultiByte(CP_UTF8, 0, from, -1, to, len,
|
r = WideCharToMultiByte(CP_UTF8, 0, from, -1, to, tolen,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
|
||||||
if (r == 0)
|
if (r <= 0)
|
||||||
ereport(ERROR,
|
return (size_t) -1;
|
||||||
(errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
|
|
||||||
errmsg("UTF-16 to UTF-8 translation failed: %lu",
|
|
||||||
GetLastError())));
|
|
||||||
Assert(r <= len);
|
|
||||||
|
|
||||||
return r;
|
Assert(r <= tolen);
|
||||||
|
|
||||||
|
/* Microsoft counts the zero terminator in the result */
|
||||||
|
return r-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return wcstombs(to, from, len);
|
|
||||||
}
|
|
||||||
#endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
|
|
||||||
|
return wcstombs(to, from, tolen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* char2wchar --- convert multibyte characters to wide characters
|
||||||
|
*
|
||||||
|
* This has almost the API of mbstowcs(), except that *from need not be
|
||||||
|
* null-terminated; instead, the number of input bytes is specified as
|
||||||
|
* fromlen. Also, we ereport() rather than returning -1 for invalid
|
||||||
|
* input encoding. tolen is the maximum number of wchar_t's to store at *to.
|
||||||
|
* The output will be zero-terminated iff there is room.
|
||||||
|
*/
|
||||||
size_t
|
size_t
|
||||||
char2wchar(wchar_t *to, const char *from, size_t len)
|
char2wchar(wchar_t *to, size_t tolen, const char *from, size_t fromlen)
|
||||||
{
|
{
|
||||||
if (len == 0)
|
if (tolen == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@ -58,71 +73,117 @@ char2wchar(wchar_t *to, const char *from, size_t len)
|
|||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = MultiByteToWideChar(CP_UTF8, 0, from, len, to, len);
|
r = MultiByteToWideChar(CP_UTF8, 0, from, fromlen, to, tolen);
|
||||||
|
|
||||||
if (!r)
|
if (r <= 0)
|
||||||
{
|
{
|
||||||
pg_verifymbstr(from, len, false);
|
pg_verifymbstr(from, fromlen, false);
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
|
(errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
|
||||||
errmsg("invalid multibyte character for locale"),
|
errmsg("invalid multibyte character for locale"),
|
||||||
errhint("The server's LC_CTYPE locale is probably incompatible with the database encoding.")));
|
errhint("The server's LC_CTYPE locale is probably incompatible with the database encoding.")));
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert(r <= len);
|
Assert(r <= tolen);
|
||||||
|
|
||||||
return r;
|
/* Microsoft counts the zero terminator in the result */
|
||||||
|
return r-1;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
#endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
|
|
||||||
if (lc_ctype_is_c())
|
if (lc_ctype_is_c())
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* pg_mb2wchar_with_len always adds trailing '\0', so 'to' should be
|
* pg_mb2wchar_with_len always adds trailing '\0', so 'to' should be
|
||||||
* allocated with sufficient space
|
* allocated with sufficient space
|
||||||
*/
|
*/
|
||||||
return pg_mb2wchar_with_len(from, (pg_wchar *) to, len);
|
return pg_mb2wchar_with_len(from, (pg_wchar *) to, fromlen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* mbstowcs require ending '\0'
|
* mbstowcs requires ending '\0'
|
||||||
*/
|
*/
|
||||||
char *str = pnstrdup(from, len);
|
char *str = pnstrdup(from, fromlen);
|
||||||
size_t tolen;
|
size_t result;
|
||||||
|
|
||||||
|
result = mbstowcs(to, str, tolen);
|
||||||
|
|
||||||
tolen = mbstowcs(to, str, len);
|
|
||||||
pfree(str);
|
pfree(str);
|
||||||
|
|
||||||
return tolen;
|
if (result == (size_t) -1)
|
||||||
|
{
|
||||||
|
pg_verifymbstr(from, fromlen, false);
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
|
||||||
|
errmsg("invalid multibyte character for locale"),
|
||||||
|
errhint("The server's LC_CTYPE locale is probably incompatible with the database encoding.")));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result < tolen)
|
||||||
|
to[result] = 0;
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
_t_isalpha(const char *ptr)
|
t_isdigit(const char *ptr)
|
||||||
{
|
{
|
||||||
|
int clen = pg_mblen(ptr);
|
||||||
wchar_t character[2];
|
wchar_t character[2];
|
||||||
|
|
||||||
if (lc_ctype_is_c())
|
if (clen == 1 || lc_ctype_is_c())
|
||||||
|
return isdigit(TOUCHAR(ptr));
|
||||||
|
|
||||||
|
char2wchar(character, 2, ptr, clen);
|
||||||
|
|
||||||
|
return iswdigit((wint_t) character[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
t_isspace(const char *ptr)
|
||||||
|
{
|
||||||
|
int clen = pg_mblen(ptr);
|
||||||
|
wchar_t character[2];
|
||||||
|
|
||||||
|
if (clen == 1 || lc_ctype_is_c())
|
||||||
|
return isspace(TOUCHAR(ptr));
|
||||||
|
|
||||||
|
char2wchar(character, 2, ptr, clen);
|
||||||
|
|
||||||
|
return iswspace((wint_t) character[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
t_isalpha(const char *ptr)
|
||||||
|
{
|
||||||
|
int clen = pg_mblen(ptr);
|
||||||
|
wchar_t character[2];
|
||||||
|
|
||||||
|
if (clen == 1 || lc_ctype_is_c())
|
||||||
return isalpha(TOUCHAR(ptr));
|
return isalpha(TOUCHAR(ptr));
|
||||||
|
|
||||||
char2wchar(character, ptr, 1);
|
char2wchar(character, 2, ptr, clen);
|
||||||
|
|
||||||
return iswalpha((wint_t) *character);
|
return iswalpha((wint_t) character[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_t_isprint(const char *ptr)
|
t_isprint(const char *ptr)
|
||||||
{
|
{
|
||||||
|
int clen = pg_mblen(ptr);
|
||||||
wchar_t character[2];
|
wchar_t character[2];
|
||||||
|
|
||||||
if (lc_ctype_is_c())
|
if (clen == 1 || lc_ctype_is_c())
|
||||||
return isprint(TOUCHAR(ptr));
|
return isprint(TOUCHAR(ptr));
|
||||||
|
|
||||||
char2wchar(character, ptr, 1);
|
char2wchar(character, 2, ptr, clen);
|
||||||
|
|
||||||
return iswprint((wint_t) *character);
|
return iswprint((wint_t) character[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* TS_USE_WIDE */
|
#endif /* TS_USE_WIDE */
|
||||||
|
|
||||||
|
|
||||||
@ -168,19 +229,27 @@ t_readline(FILE *fp)
|
|||||||
return recoded;
|
return recoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* lowerstr --- fold null-terminated string to lower case
|
||||||
|
*
|
||||||
|
* Returned string is palloc'd
|
||||||
|
*/
|
||||||
char *
|
char *
|
||||||
lowerstr(char *str)
|
lowerstr(const char *str)
|
||||||
{
|
{
|
||||||
return lowerstr_with_len(str, strlen(str));
|
return lowerstr_with_len(str, strlen(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* lowerstr_with_len --- fold string to lower case
|
||||||
|
*
|
||||||
|
* Input string need not be null-terminated.
|
||||||
|
*
|
||||||
* Returned string is palloc'd
|
* Returned string is palloc'd
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
lowerstr_with_len(char *str, int len)
|
lowerstr_with_len(const char *str, int len)
|
||||||
{
|
{
|
||||||
char *ptr = str;
|
|
||||||
char *out;
|
char *out;
|
||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
@ -202,23 +271,13 @@ lowerstr_with_len(char *str, int len)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* alloc number of wchar_t for worst case, len contains number of
|
* alloc number of wchar_t for worst case, len contains number of
|
||||||
* bytes <= number of characters and alloc 1 wchar_t for 0, because
|
* bytes >= number of characters and alloc 1 wchar_t for 0, because
|
||||||
* wchar2char(wcstombs in really) wants zero-terminated string
|
* wchar2char wants zero-terminated string
|
||||||
*/
|
*/
|
||||||
wptr = wstr = (wchar_t *) palloc(sizeof(wchar_t) * (len + 1));
|
wptr = wstr = (wchar_t *) palloc(sizeof(wchar_t) * (len + 1));
|
||||||
|
|
||||||
/*
|
wlen = char2wchar(wstr, len+1, str, len);
|
||||||
* str SHOULD be cstring, so wlen contains number of converted
|
|
||||||
* character
|
|
||||||
*/
|
|
||||||
wlen = char2wchar(wstr, str, len);
|
|
||||||
if (wlen < 0)
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
|
|
||||||
errmsg("translation failed from server encoding to wchar_t")));
|
|
||||||
|
|
||||||
Assert(wlen <= len);
|
Assert(wlen <= len);
|
||||||
wstr[wlen] = 0;
|
|
||||||
|
|
||||||
while (*wptr)
|
while (*wptr)
|
||||||
{
|
{
|
||||||
@ -229,31 +288,29 @@ lowerstr_with_len(char *str, int len)
|
|||||||
/*
|
/*
|
||||||
* Alloc result string for worst case + '\0'
|
* Alloc result string for worst case + '\0'
|
||||||
*/
|
*/
|
||||||
len = sizeof(char) * pg_database_encoding_max_length() *(wlen + 1);
|
len = pg_database_encoding_max_length() * wlen + 1;
|
||||||
out = (char *) palloc(len);
|
out = (char *) palloc(len);
|
||||||
|
|
||||||
/*
|
|
||||||
* wlen now is number of bytes which is always >= number of characters
|
|
||||||
*/
|
|
||||||
wlen = wchar2char(out, wstr, len);
|
wlen = wchar2char(out, wstr, len);
|
||||||
|
|
||||||
pfree(wstr);
|
pfree(wstr);
|
||||||
|
|
||||||
if (wlen < 0)
|
if (wlen < 0)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
|
(errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
|
||||||
errmsg("translation failed from wchar_t to server encoding %d", errno)));
|
errmsg("translation from wchar_t to server encoding failed: %m")));
|
||||||
Assert(wlen <= len);
|
Assert(wlen < len);
|
||||||
out[wlen] = '\0';
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif /* TS_USE_WIDE */
|
||||||
{
|
{
|
||||||
|
const char *ptr = str;
|
||||||
char *outptr;
|
char *outptr;
|
||||||
|
|
||||||
outptr = out = (char *) palloc(sizeof(char) * (len + 1));
|
outptr = out = (char *) palloc(sizeof(char) * (len + 1));
|
||||||
while (*ptr && ptr - str < len)
|
while ((ptr - str) < len && *ptr)
|
||||||
{
|
{
|
||||||
*outptr++ = tolower(*(unsigned char *) ptr);
|
*outptr++ = tolower(TOUCHAR(ptr));
|
||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
*outptr = '\0';
|
*outptr = '\0';
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/tsearch/ts_utils.c,v 1.4 2007/09/04 02:16:56 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/tsearch/ts_utils.c,v 1.5 2007/11/09 22:37:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -75,7 +75,7 @@ comparestr(const void *a, const void *b)
|
|||||||
* or palloc a new version.
|
* or palloc a new version.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
readstoplist(const char *fname, StopList *s, char *(*wordop) (char *))
|
readstoplist(const char *fname, StopList *s, char *(*wordop) (const char *))
|
||||||
{
|
{
|
||||||
char **stop = NULL;
|
char **stop = NULL;
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/tsearch/wparser_def.c,v 1.7 2007/10/27 19:03:45 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/tsearch/wparser_def.c,v 1.8 2007/11/09 22:37:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -294,12 +294,12 @@ TParserInit(char *str, int len)
|
|||||||
/*
|
/*
|
||||||
* Use wide char code only when max encoding length > 1.
|
* Use wide char code only when max encoding length > 1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (prs->charmaxlen > 1)
|
if (prs->charmaxlen > 1)
|
||||||
{
|
{
|
||||||
prs->usewide = true;
|
prs->usewide = true;
|
||||||
prs->wstr = (wchar_t *) palloc(sizeof(wchar_t) * (prs->lenstr + 1));
|
prs->wstr = (wchar_t *) palloc(sizeof(wchar_t) * (prs->lenstr + 1));
|
||||||
prs->lenwstr = char2wchar(prs->wstr, prs->str, prs->lenstr);
|
prs->lenwstr = char2wchar(prs->wstr, prs->lenstr + 1,
|
||||||
|
prs->str, prs->lenstr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* ts_locale.h
|
* ts_locale.h
|
||||||
* helper utilities for tsearch
|
* locale compatibility layer for tsearch
|
||||||
*
|
*
|
||||||
* Copyright (c) 1998-2007, PostgreSQL Global Development Group
|
* Copyright (c) 1998-2007, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/tsearch/ts_locale.h,v 1.2 2007/08/25 00:03:59 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/tsearch/ts_locale.h,v 1.3 2007/11/09 22:37:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TSLOCALE_H__
|
#ifndef __TSLOCALE_H__
|
||||||
#define __TSLOCALE_H__
|
#define __TSLOCALE_H__
|
||||||
|
|
||||||
@ -34,55 +33,37 @@
|
|||||||
#define TS_USE_WIDE
|
#define TS_USE_WIDE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TOUCHAR(x) (*((unsigned char*)(x)))
|
#define TOUCHAR(x) (*((const unsigned char *) (x)))
|
||||||
|
|
||||||
#ifdef TS_USE_WIDE
|
#ifdef TS_USE_WIDE
|
||||||
|
|
||||||
extern size_t char2wchar(wchar_t *to, const char *from, size_t len);
|
extern size_t wchar2char(char *to, const wchar_t *from, size_t tolen);
|
||||||
|
extern size_t char2wchar(wchar_t *to, size_t tolen, const char *from, size_t fromlen);
|
||||||
|
|
||||||
#ifdef WIN32
|
extern int t_isdigit(const char *ptr);
|
||||||
|
extern int t_isspace(const char *ptr);
|
||||||
|
extern int t_isalpha(const char *ptr);
|
||||||
|
extern int t_isprint(const char *ptr);
|
||||||
|
|
||||||
extern size_t wchar2char(char *to, const wchar_t *from, size_t len);
|
/* The second argument of t_iseq() must be a plain ASCII character */
|
||||||
#else /* WIN32 */
|
#define t_iseq(x,c) (TOUCHAR(x) == (unsigned char) (c))
|
||||||
|
|
||||||
/* correct wcstombs */
|
#define COPYCHAR(d,s) memcpy(d, s, pg_mblen(s))
|
||||||
#define wchar2char wcstombs
|
|
||||||
|
|
||||||
#endif /* WIN32 */
|
#else /* not TS_USE_WIDE */
|
||||||
|
|
||||||
#define t_isdigit(x) ( pg_mblen(x)==1 && isdigit( TOUCHAR(x) ) )
|
#define t_isdigit(x) isdigit(TOUCHAR(x))
|
||||||
#define t_isspace(x) ( pg_mblen(x)==1 && isspace( TOUCHAR(x) ) )
|
#define t_isspace(x) isspace(TOUCHAR(x))
|
||||||
extern int _t_isalpha(const char *ptr);
|
#define t_isalpha(x) isalpha(TOUCHAR(x))
|
||||||
|
#define t_isprint(x) isprint(TOUCHAR(x))
|
||||||
|
#define t_iseq(x,c) (TOUCHAR(x) == (unsigned char) (c))
|
||||||
|
|
||||||
#define t_isalpha(x) ( (pg_mblen(x)==1) ? isalpha( TOUCHAR(x) ) : _t_isalpha(x) )
|
#define COPYCHAR(d,s) (*((unsigned char *) (d)) = TOUCHAR(s))
|
||||||
extern int _t_isprint(const char *ptr);
|
|
||||||
|
|
||||||
#define t_isprint(x) ( (pg_mblen(x)==1) ? isprint( TOUCHAR(x) ) : _t_isprint(x) )
|
#endif /* TS_USE_WIDE */
|
||||||
/*
|
|
||||||
* t_iseq() should be called only for ASCII symbols
|
|
||||||
*/
|
|
||||||
#define t_iseq(x,c) ( (pg_mblen(x)==1) ? ( TOUCHAR(x) == ((unsigned char)(c)) ) : false )
|
|
||||||
|
|
||||||
#define COPYCHAR(d,s) do { \
|
extern char *lowerstr(const char *str);
|
||||||
int lll = pg_mblen( s ); \
|
extern char *lowerstr_with_len(const char *str, int len);
|
||||||
\
|
|
||||||
while( lll-- ) \
|
|
||||||
TOUCHAR((d)+lll) = TOUCHAR((s)+lll); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#else /* not def TS_USE_WIDE */
|
|
||||||
|
|
||||||
#define t_isdigit(x) isdigit( TOUCHAR(x) )
|
|
||||||
#define t_isspace(x) isspace( TOUCHAR(x) )
|
|
||||||
#define t_isalpha(x) isalpha( TOUCHAR(x) )
|
|
||||||
#define t_isprint(x) isprint( TOUCHAR(x) )
|
|
||||||
#define t_iseq(x,c) ( TOUCHAR(x) == ((unsigned char)(c)) )
|
|
||||||
|
|
||||||
#define COPYCHAR(d,s) TOUCHAR(d) = TOUCHAR(s)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern char *lowerstr(char *str);
|
|
||||||
extern char *lowerstr_with_len(char *str, int len);
|
|
||||||
extern char *t_readline(FILE *fp);
|
extern char *t_readline(FILE *fp);
|
||||||
|
|
||||||
#endif /* __TSLOCALE_H__ */
|
#endif /* __TSLOCALE_H__ */
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1998-2007, PostgreSQL Global Development Group
|
* Copyright (c) 1998-2007, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/tsearch/ts_public.h,v 1.4 2007/09/07 15:09:56 teodor Exp $
|
* $PostgreSQL: pgsql/src/include/tsearch/ts_public.h,v 1.5 2007/11/09 22:37:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -74,7 +74,7 @@ typedef struct
|
|||||||
} StopList;
|
} StopList;
|
||||||
|
|
||||||
extern void readstoplist(const char *fname, StopList *s,
|
extern void readstoplist(const char *fname, StopList *s,
|
||||||
char *(*wordop) (char *));
|
char *(*wordop) (const char *));
|
||||||
extern bool searchstoplist(StopList *s, char *key);
|
extern bool searchstoplist(StopList *s, char *key);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user