mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			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;
 | 
						|
}
 |