mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-27 08:39:28 +08:00
d3e36da789
that a tsearch2 installation can be relocatable.
140 lines
2.4 KiB
C
140 lines
2.4 KiB
C
/*
|
|
* stopword library
|
|
* Teodor Sigaev <teodor@sigaev.ru>
|
|
*/
|
|
#include "postgres.h"
|
|
|
|
#include <ctype.h>
|
|
|
|
#include "miscadmin.h"
|
|
|
|
#include "common.h"
|
|
#include "dict.h"
|
|
|
|
#define STOPBUFLEN 4096
|
|
|
|
char *
|
|
lowerstr(char *str)
|
|
{
|
|
char *ptr = str;
|
|
|
|
while (*ptr)
|
|
{
|
|
*ptr = tolower(*(unsigned char *) ptr);
|
|
ptr++;
|
|
}
|
|
return str;
|
|
}
|
|
|
|
void
|
|
freestoplist(StopList * s)
|
|
{
|
|
char **ptr = s->stop;
|
|
|
|
if (ptr)
|
|
while (*ptr && s->len > 0)
|
|
{
|
|
free(*ptr);
|
|
ptr++;
|
|
s->len--;
|
|
free(s->stop);
|
|
}
|
|
memset(s, 0, sizeof(StopList));
|
|
}
|
|
|
|
void
|
|
readstoplist(text *in, StopList * s)
|
|
{
|
|
char **stop = NULL;
|
|
|
|
s->len = 0;
|
|
if (in && VARSIZE(in) - VARHDRSZ > 0)
|
|
{
|
|
char *filename = text2char(in);
|
|
FILE *hin;
|
|
char buf[STOPBUFLEN];
|
|
int reallen = 0;
|
|
|
|
/* if path is relative, take it as relative to share dir */
|
|
if (!is_absolute_path(filename))
|
|
{
|
|
char sharepath[MAXPGPATH];
|
|
char *absfn;
|
|
|
|
get_share_path(my_exec_path, sharepath);
|
|
absfn = palloc(strlen(sharepath) + strlen(filename) + 2);
|
|
sprintf(absfn, "%s/%s", sharepath, filename);
|
|
pfree(filename);
|
|
filename = absfn;
|
|
}
|
|
|
|
if ((hin = fopen(filename, "r")) == NULL)
|
|
ereport(ERROR,
|
|
(errcode(ERRCODE_CONFIG_FILE_ERROR),
|
|
errmsg("could not open file \"%s\": %m",
|
|
filename)));
|
|
|
|
while (fgets(buf, STOPBUFLEN, hin))
|
|
{
|
|
buf[strlen(buf) - 1] = '\0';
|
|
if (*buf == '\0')
|
|
continue;
|
|
|
|
if (s->len >= reallen)
|
|
{
|
|
char **tmp;
|
|
|
|
reallen = (reallen) ? reallen * 2 : 16;
|
|
tmp = (char **) realloc((void *) stop, sizeof(char *) * reallen);
|
|
if (!tmp)
|
|
{
|
|
freestoplist(s);
|
|
fclose(hin);
|
|
ereport(ERROR,
|
|
(errcode(ERRCODE_OUT_OF_MEMORY),
|
|
errmsg("out of memory")));
|
|
}
|
|
stop = tmp;
|
|
}
|
|
|
|
stop[s->len] = strdup(buf);
|
|
if (!stop[s->len])
|
|
{
|
|
freestoplist(s);
|
|
fclose(hin);
|
|
ereport(ERROR,
|
|
(errcode(ERRCODE_OUT_OF_MEMORY),
|
|
errmsg("out of memory")));
|
|
}
|
|
if (s->wordop)
|
|
stop[s->len] = (s->wordop) (stop[s->len]);
|
|
|
|
(s->len)++;
|
|
}
|
|
fclose(hin);
|
|
pfree(filename);
|
|
}
|
|
s->stop = stop;
|
|
}
|
|
|
|
static int
|
|
comparestr(const void *a, const void *b)
|
|
{
|
|
return strcmp(*(char **) a, *(char **) b);
|
|
}
|
|
|
|
void
|
|
sortstoplist(StopList * s)
|
|
{
|
|
if (s->stop && s->len > 0)
|
|
qsort(s->stop, s->len, sizeof(char *), comparestr);
|
|
}
|
|
|
|
bool
|
|
searchstoplist(StopList * s, char *key)
|
|
{
|
|
if (s->wordop)
|
|
key = (*(s->wordop)) (key);
|
|
return (s->stop && s->len > 0 && bsearch(&key, s->stop, s->len, sizeof(char *), comparestr)) ? true : false;
|
|
}
|