/* * stopword library * Teodor Sigaev */ #include "postgres.h" #include "miscadmin.h" #include "common.h" #include "dict.h" #include "ts_locale.h" #define STOPBUFLEN 4096 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; #ifdef WIN32 char delim = '\\'; #else char delim = '/'; #endif get_share_path(my_exec_path, sharepath); absfn = palloc(strlen(sharepath) + strlen(filename) + 2); sprintf(absfn, "%s%c%s", sharepath, delim, 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'; pg_verifymbstr( buf, strlen(buf), false ); lowerstr(buf); 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; }