summaryrefslogtreecommitdiff
path: root/contrib/soundex/soundex.c
blob: 9b06808fa2736502774423e48600f2b742f0be57 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*****************************************************************************/
/* soundex.c */
/*****************************************************************************/

#include <string.h>
#include <stdio.h>
#include "postgres.h"			/* for char16, etc. */
#include "utils/palloc.h"		/* for palloc */
#include "libpq-fe.h"			/* for TUPLE */
#include <stdio.h>
#include <ctype.h>

/* prototype for soundex function */
char	   *soundex(char *instr, char *outstr);

text	   *
text_soundex(text * t)
{
	/* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
	char	   *table = "01230120022455012623010202";
	int			count = 0;
	text	   *new_t;

	char		outstr[6 + 1];	/* max length of soundex is 6 */
	char	   *instr;

	/* make a null-terminated string */
	instr = palloc(VARSIZE(t) + 1);
	memcpy(instr, VARDATA(t), VARSIZE(t) - VARHDRSZ);
	instr[VARSIZE(t) - VARHDRSZ] = (char) 0;

	/* load soundex into outstr */
	soundex(instr, outstr);

	/* Now the outstr contains the soundex of instr */
	/* copy outstr to new_t */
	new_t = (text *) palloc(strlen(outstr) + VARHDRSZ);
	memset(new_t, 0, strlen(outstr) + 1);
	VARSIZE(new_t) = strlen(outstr) + VARHDRSZ;
	memcpy((void *) VARDATA(new_t),
		   (void *) outstr,
		   strlen(outstr));

	/* free instr */
	pfree(instr);

	return (new_t);
}

char	   *
soundex(char *instr, char *outstr)
{								/* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
	char	   *table = "01230120022455012623010202";
	int			count = 0;

	while (!isalpha(instr[0]) && instr[0])
		++instr;

	if (!instr[0])
	{							/* Hey!  Where'd the string go? */
		outstr[0] = (char) 0;
		return outstr;
	}

	if (toupper(instr[0]) == 'P' && toupper(instr[1]) == 'H')
	{
		instr[0] = 'F';
		instr[1] = 'A';
	}

	*outstr++ = (char) toupper(*instr++);

	while (*instr && count < 5)
	{
		if (isalpha(*instr) && *instr != *(instr - 1))
		{
			*outstr = table[toupper(instr[0]) - 'A'];
			if (*outstr != '0')
			{
				++outstr;
				++count;
			}
		}
		++instr;
	}

	*outstr = '\0';
	return (outstr);
}