2000-10-04 23:25:34 +04:00
|
|
|
/* $Header: /cvsroot/pgsql/contrib/soundex/Attic/soundex.c,v 1.7 2000/10/04 19:25:34 petere Exp $ */
|
|
|
|
#include "postgres.h"
|
|
|
|
#include "fmgr.h"
|
|
|
|
#include "utils/builtins.h"
|
2000-05-29 09:45:56 +04:00
|
|
|
#include <ctype.h>
|
1996-08-19 02:14:33 +04:00
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
2000-05-29 09:45:56 +04:00
|
|
|
|
|
|
|
|
2000-10-04 23:25:34 +04:00
|
|
|
Datum
|
|
|
|
text_soundex(PG_FUNCTION_ARGS);
|
1996-08-19 02:14:33 +04:00
|
|
|
|
2000-10-04 23:25:34 +04:00
|
|
|
static void
|
|
|
|
soundex(const char *instr, char *outstr);
|
1996-08-19 02:14:33 +04:00
|
|
|
|
2000-10-04 23:25:34 +04:00
|
|
|
#define SOUNDEX_LEN 4
|
1997-09-07 09:04:48 +04:00
|
|
|
|
|
|
|
|
2000-10-04 23:25:34 +04:00
|
|
|
#define _textin(str) DirectFunctionCall1(textin, CStringGetDatum(str))
|
|
|
|
#define _textout(str) DatumGetPointer(DirectFunctionCall1(textout, PointerGetDatum(str)))
|
1997-09-07 09:04:48 +04:00
|
|
|
|
|
|
|
|
2000-10-04 23:25:34 +04:00
|
|
|
#ifndef SOUNDEX_TEST
|
|
|
|
/*
|
|
|
|
* SQL function: text_soundex(text) returns text
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
text_soundex(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
char outstr[SOUNDEX_LEN + 1];
|
|
|
|
char *arg;
|
|
|
|
|
|
|
|
arg = _textout(PG_GETARG_TEXT_P(0));
|
1997-09-07 09:04:48 +04:00
|
|
|
|
2000-10-04 23:25:34 +04:00
|
|
|
soundex(arg, outstr);
|
1997-09-07 09:04:48 +04:00
|
|
|
|
2000-10-04 23:25:34 +04:00
|
|
|
PG_RETURN_TEXT_P(_textin(outstr));
|
1996-08-19 02:14:33 +04:00
|
|
|
}
|
2000-10-04 23:25:34 +04:00
|
|
|
#endif /* not SOUNDEX_TEST */
|
|
|
|
|
|
|
|
|
|
|
|
/* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
|
|
|
|
static const char *soundex_table = "01230120022455012623010202";
|
|
|
|
#define soundex_code(letter) soundex_table[toupper(letter) - 'A']
|
|
|
|
|
1996-08-19 02:14:33 +04:00
|
|
|
|
2000-10-04 23:25:34 +04:00
|
|
|
static void
|
|
|
|
soundex(const char *instr, char *outstr)
|
2000-05-29 09:45:56 +04:00
|
|
|
{
|
2000-10-04 23:25:34 +04:00
|
|
|
int count;
|
1997-09-07 09:04:48 +04:00
|
|
|
|
2000-10-04 23:25:34 +04:00
|
|
|
AssertArg(instr);
|
|
|
|
AssertArg(outstr);
|
|
|
|
|
|
|
|
outstr[SOUNDEX_LEN] = '\0';
|
|
|
|
|
|
|
|
/* Skip leading non-alphabetic characters */
|
1997-09-07 09:04:48 +04:00
|
|
|
while (!isalpha(instr[0]) && instr[0])
|
|
|
|
++instr;
|
|
|
|
|
2000-10-04 23:25:34 +04:00
|
|
|
/* No string left */
|
1997-09-07 09:04:48 +04:00
|
|
|
if (!instr[0])
|
|
|
|
{
|
2000-10-04 23:25:34 +04:00
|
|
|
outstr[0] = (char) 0;
|
|
|
|
return;
|
1997-09-07 09:04:48 +04:00
|
|
|
}
|
|
|
|
|
2000-10-04 23:25:34 +04:00
|
|
|
/* Take the first letter as is */
|
1997-09-07 09:04:48 +04:00
|
|
|
*outstr++ = (char) toupper(*instr++);
|
|
|
|
|
2000-10-04 23:25:34 +04:00
|
|
|
count = 1;
|
|
|
|
while (*instr && count < SOUNDEX_LEN)
|
1997-09-07 09:04:48 +04:00
|
|
|
{
|
2000-10-04 23:25:34 +04:00
|
|
|
if (isalpha(*instr) && soundex_code(*instr) != soundex_code(*(instr - 1)))
|
1997-09-07 09:04:48 +04:00
|
|
|
{
|
2000-10-04 23:25:34 +04:00
|
|
|
*outstr = soundex_code(instr[0]);
|
1997-09-07 09:04:48 +04:00
|
|
|
if (*outstr != '0')
|
|
|
|
{
|
|
|
|
++outstr;
|
|
|
|
++count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
++instr;
|
|
|
|
}
|
|
|
|
|
2000-10-04 23:25:34 +04:00
|
|
|
/* Fill with 0's */
|
|
|
|
while (count < SOUNDEX_LEN)
|
|
|
|
{
|
|
|
|
*outstr = '0';
|
|
|
|
++outstr;
|
|
|
|
++count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef SOUNDEX_TEST
|
|
|
|
int
|
|
|
|
main (int argc, char *argv[])
|
|
|
|
{
|
|
|
|
if (argc < 2)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "usage: %s string\n", argv[0]);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char output[SOUNDEX_LEN + 1];
|
|
|
|
|
|
|
|
soundex(argv[1], output);
|
|
|
|
printf("soundex(%s) = %s\n", argv[1], output);
|
|
|
|
return 0;
|
|
|
|
}
|
1996-08-19 02:14:33 +04:00
|
|
|
}
|
2000-10-04 23:25:34 +04:00
|
|
|
#endif /* SOUNDEX_TEST */
|