Tuesday, December 20, 2005

一般Phonetics常見對照

&ANALYZE-SUSPEND _VERSION-NUMBER UIB_v9r12

&ANALYZE-RESUME

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CUSTOM _DEFINITIONS Method-Library

/*------------------------------------------------------------------------

Library : DoubleMetaphone

Purpose : Used to map a string to its primary phonetic equicalent

and secondary phonetic eqivalent. Useful for accomidating

mispellings in database queries.

Syntax : RUN double_metaphone (INPUT c_original,

OUTPUT c_primary_pe,

OUTPUT c_secondary_pe).

Author(s) : Kevin Emery

Created : June 6, 2002

----------------------------------------------------------------------*/

/* This .W file was created with the Progress AppBuilder. */

/*----------------------------------------------------------------------*/

/* *************************** Definitions ************************** */

/* variable c is used in the is_vowel function*/

DEFINE VARIABLE c AS CHARACTER NO-UNDO.

/* temp-table list is used in the string_at function*/

DEFINE TEMP-TABLE list

FIELD val AS CHARACTER.

/* the following variables are used in the double_metaphone function*/

DEFINE VARIABLE c_primary AS CHARACTER NO-UNDO.

DEFINE VARIABLE c_secondary AS CHARACTER NO-UNDO.

DEFINE VARIABLE i_length AS INTEGER NO-UNDO.

DEFINE VARIABLE i_last AS INTEGER NO-UNDO.

DEFINE VARIABLE c_original AS CHARACTER NO-UNDO.

DEFINE VARIABLE b_temp1 AS LOGICAL NO-UNDO.

DEFINE VARIABLE b_temp2 AS LOGICAL NO-UNDO.

DEFINE VARIABLE b_temp3 AS LOGICAL NO-UNDO.

DEFINE VARIABLE b_temp4 AS LOGICAL NO-UNDO.

DEFINE VARIABLE b_temp5 AS LOGICAL NO-UNDO.

DEFINE VARIABLE b_temp6 AS LOGICAL NO-UNDO.

DEFINE VARIABLE b_temp7 AS LOGICAL NO-UNDO.

/* temp-table holds c_primary, c_secondary, i_current (global variables) */

DEFINE TEMP-TABLE vals

FIELD f_primary AS CHARACTER

FIELD f_secondary AS CHARACTER

FIELD f_current AS INTEGER.

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ANALYZE-SUSPEND _UIB-PREPROCESSOR-BLOCK

/* ******************** Preprocessor Definitions ******************** */

/* _UIB-PREPROCESSOR-BLOCK-END */

&ANALYZE-RESUME

/* ************************ Function Prototypes ********************** */

&IF DEFINED(EXCLUDE-clear_list) = 0 &THEN

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD clear_list Method-Library

FUNCTION clear_list RETURNS CHARACTER PRIVATE

() FORWARD.

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ENDIF

&IF DEFINED(EXCLUDE-clear_vals) = 0 &THEN

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD clear_vals Method-Library

FUNCTION clear_vals RETURNS CHARACTER PRIVATE

() FORWARD.

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ENDIF

&IF DEFINED(EXCLUDE-double_metaphone1) = 0 &THEN

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD double_metaphone1 Method-Library

FUNCTION double_metaphone1 RETURNS CHARACTER

() FORWARD.

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ENDIF

&IF DEFINED(EXCLUDE-double_metaphone2) = 0 &THEN

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD double_metaphone2 Method-Library

FUNCTION double_metaphone2 RETURNS CHARACTER

() FORWARD.

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ENDIF

&IF DEFINED(EXCLUDE-double_metaphone3) = 0 &THEN

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD double_metaphone3 Method-Library

FUNCTION double_metaphone3 RETURNS CHARACTER

() FORWARD.

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ENDIF

&IF DEFINED(EXCLUDE-double_metaphone4) = 0 &THEN

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD double_metaphone4 Method-Library

FUNCTION double_metaphone4 RETURNS CHARACTER PRIVATE

() FORWARD.

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ENDIF

&IF DEFINED(EXCLUDE-is_vowel) = 0 &THEN

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD is_vowel Method-Library

FUNCTION is_vowel RETURNS LOGICAL PRIVATE

(s AS CHARACTER, i AS INTEGER) FORWARD.

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ENDIF

&IF DEFINED(EXCLUDE-slavo_germanic) = 0 &THEN

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD slavo_germanic Method-Library

FUNCTION slavo_germanic RETURNS LOGICAL PRIVATE

(s AS CHARACTER) FORWARD.

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ENDIF

&IF DEFINED(EXCLUDE-string_at) = 0 &THEN

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD string_at Method-Library

FUNCTION string_at RETURNS LOGICAL PRIVATE

(s AS CHARACTER, istart AS INTEGER, ilength AS INTEGER) FORWARD.

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ENDIF

/* *********************** Procedure Settings ************************ */

&ANALYZE-SUSPEND _PROCEDURE-SETTINGS

/* Settings for THIS-PROCEDURE

Type: Method-Library

Allow:

Frames: 0

Add Fields to: Neither

Other Settings: INCLUDE-ONLY

*/

&ANALYZE-RESUME _END-PROCEDURE-SETTINGS

/* ************************* Create Window ************************** */

&ANALYZE-SUSPEND _CREATE-WINDOW

/* DESIGN Window definition (used by the UIB)

CREATE WINDOW Method-Library ASSIGN

HEIGHT = 19.95

WIDTH = 60.

/* END WINDOW DEFINITION */

*/

&ANALYZE-RESUME

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CUSTOM _INCLUDED-LIB Method-Library

/* ************************* Included-Libraries *********************** */

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CUSTOM _MAIN-BLOCK Method-Library

/* *************************** Main Block *************************** */

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

/* ********************** Internal Procedures *********************** */

&IF DEFINED(EXCLUDE-double_metaphone) = 0 &THEN

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE double_metaphone Method-Library

PROCEDURE double_metaphone :

/*------------------------------------------------------------------------------

Purpose: map c_initial string to primary phonetic equivalent string

c_primary and secondary phonetic equivalent string c_secondary.

Parameters: input c_initial as character, output c_primary as character,

output c_secondary as character.

Notes: using temp-tables rather than more commonly used array data structre

in the string_at function.

------------------------------------------------------------------------------*/

DEFINE INPUT PARAMETER c_initial AS CHARACTER NO-UNDO.

DEFINE OUTPUT PARAMETER c_primary AS CHARACTER NO-UNDO.

DEFINE OUTPUT PARAMETER c_secondary AS CHARACTER NO-UNDO.

/*initializing variables*/

/*vals table*/

clear_vals().

CREATE vals.

ASSIGN vals.f_primary = ""

vals.f_secondary = ""

vals.f_current = 0

/*other vars*/

i_length = LENGTH(c_initial)

i_last = i_length - 1

c_original = UPPER(c_initial).

/*special cases before entering main loop*/

/*initializing list temp-table*/

clear_list().

CREATE list.

ASSIGN list.val = "GN".

CREATE list.

ASSIGN list.val = "KN".

CREATE list.

ASSIGN list.val = "PN".

CREATE list.

ASSIGN list.val = "WR".

CREATE list.

ASSIGN list.val = "PS".

IF string_at(c_original,0,2) THEN

ASSIGN vals.f_current = vals.f_current + 1.

IF SUBSTRING(c_original,1,1) = "X" THEN DO:

vals.f_primary = vals.f_primary + "S".

vals.f_secondary = vals.f_secondary + "S".

vals.f_current = vals.f_current + 1.

END.

/* main loop */

REPEAT:

IF (LENGTH(vals.f_primary) >= 4 AND

LENGTH(vals.f_secondary) >= 4) OR

vals.f_current >= i_length THEN LEAVE.

/*MESSAGE SUBSTRING(c_original,vals.f_current + 1,1) VIEW-AS ALERT-BOX.*/

/*MESSAGE vals.f_primary VIEW-AS ALERT-BOX.*/

/*MESSAGE vals.f_current VIEW-AS ALERT-BOX.*/

CASE SUBSTRING(c_original,vals.f_current + 1,1) :

WHEN "A" OR

WHEN "E" OR

WHEN "I" OR

WHEN "O" OR

WHEN "U" OR

WHEN "Y" OR

WHEN "B" OR

WHEN "Ç" OR

WHEN "C" OR

WHEN "D" OR

WHEN "F" THEN DO:

double_metaphone1().

NEXT.

END.

WHEN "G" OR

WHEN "H" OR

WHEN "J" OR

WHEN "K" OR

WHEN "L" OR

WHEN "M" OR

WHEN "N" OR

WHEN "Ñ" OR

WHEN "P" OR

WHEN "Q" THEN DO:

double_metaphone2().

NEXT.

END.

WHEN "R" OR

WHEN "S" OR

WHEN "T" OR

WHEN "V" THEN DO:

double_metaphone3().

NEXT.

END.

WHEN "W" OR

WHEN "X" OR

WHEN "Z" THEN DO:

double_metaphone4().

NEXT.

END.

END CASE.

vals.f_current = vals.f_current + 1.

END.

vals.f_primary = SUBSTRING(vals.f_primary,1,4).

vals.f_secondary = SUBSTRING(vals.f_secondary,1,4).

IF vals.f_primary = vals.f_secondary THEN vals.f_secondary = "".

/*

MESSAGE vals.f_primary VIEW-AS ALERT-BOX.

MESSAGE vals.f_secondary VIEW-AS ALERT-BOX.

*/

c_primary = vals.f_primary.

c_secondary = vals.f_secondary.

END PROCEDURE.

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ENDIF

/* ************************ Function Implementations ***************** */

&IF DEFINED(EXCLUDE-clear_list) = 0 &THEN

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION clear_list Method-Library

FUNCTION clear_list RETURNS CHARACTER PRIVATE

():

/*------------------------------------------------------------------------------

Purpose: clear out list temp-table

Notes:

------------------------------------------------------------------------------*/

FOR EACH list EXCLUSIVE-LOCK :

DELETE list.

END.

RETURN "".

END FUNCTION.

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ENDIF

&IF DEFINED(EXCLUDE-clear_vals) = 0 &THEN

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION clear_vals Method-Library

FUNCTION clear_vals RETURNS CHARACTER PRIVATE

():

/*------------------------------------------------------------------------------

Purpose: clear out vals temp-table

Notes:

------------------------------------------------------------------------------*/

FOR EACH vals EXCLUSIVE-LOCK :

DELETE vals.

END.

RETURN "".

END FUNCTION.

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ENDIF

&IF DEFINED(EXCLUDE-double_metaphone1) = 0 &THEN

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION double_metaphone1 Method-Library

FUNCTION double_metaphone1 RETURNS CHARACTER

():

/*------------------------------------------------------------------------------

Purpose: helper function of double_metaphone procedure .

Notes: handles vowels,Y,B-D,F.

------------------------------------------------------------------------------*/

CASE SUBSTRING(c_original,vals.f_current + 1,1):

WHEN "A" OR

WHEN "E" OR

WHEN "I" OR

WHEN "O" OR

WHEN "U" OR

WHEN "Y" THEN DO:

/*initial vowels map to A*/

IF vals.f_current = 0 THEN DO:

vals.f_primary = vals.f_primary + "A".

vals.f_secondary = vals.f_secondary + "A".

END.

vals.f_current = vals.f_current + 1.

RETURN "".

END.

WHEN "B" THEN DO:

/*-mb, e.g., 'dumb', already skipped over...*/

vals.f_primary = vals.f_primary + "P".

vals.f_secondary = vals.f_secondary + "P".

IF SUBSTRING(c_original,vals.f_current + 2,1) = "B" THEN

vals.f_current = vals.f_current + 2.

ELSE

vals.f_current = vals.f_current + 1.

RETURN "".

END.

/* overrides c

WHEN "Ç" THEN DO:

vals.f_primary = vals.f_primary + "S".

vals.f_secondary = vals.f_secondary + "S".

vals.f_current = vals.f_current + 1.

RETURN "".

END.

*/

WHEN "C" THEN DO:

/*various gremanic*/

/*preliminary boolean assignments*/

clear_list().

CREATE list.

ASSIGN list.val = "ACH".

b_temp1 = string_at(c_original,vals.f_current - 1,3).

clear_list().

CREATE list.

ASSIGN list.val = "BACHER".

CREATE list.

ASSIGN list.val = "MACHER".

b_temp2 = string_at(c_original,vals.f_current - 2,6).

/*logic*/

IF vals.f_current > 1 AND

NOT is_vowel(c_original,vals.f_current - 2) AND

b_temp1 AND

(NOT SUBSTRING(c_original,vals.f_current + 3,1) = "I" AND

(NOT SUBSTRING(c_original,vals.f_current + 3,1) = "E" OR b_temp2)) THEN DO:

vals.f_primary = vals.f_primary + "K".

vals.f_secondary = vals.f_secondary + "K".

vals.f_current = vals.f_current + 2.

RETURN "".

END.

/*special case 'caesar'*/

clear_list().

CREATE list.

ASSIGN list.val = "CAESAR".

IF vals.f_current = 0 AND

string_at(c_original,vals.f_current,6) THEN DO:

vals.f_primary = vals.f_primary + "S".

vals.f_secondary = vals.f_secondary + "S".

vals.f_current = vals.f_current + 2.

RETURN "".

END.

/*italian 'chianti'*/

clear_list().

CREATE list.

ASSIGN list.val = "CHIA".

IF string_at(c_original,vals.f_current,4) THEN DO:

vals.f_primary = vals.f_primary + "K".

vals.f_secondary = vals.f_secondary + "K".

vals.f_current = vals.f_current + 2.

RETURN "".

END.

clear_list().

CREATE list.

ASSIGN list.val = "CH".

IF string_at(c_original,vals.f_current,2) THEN DO:

/*finding 'michael'*/

clear_list().

CREATE list.

ASSIGN list.val = "CHAE".

IF vals.f_current > 0 AND

string_at(c_original,vals.f_current,4) THEN DO:

vals.f_primary = vals.f_primary + "K".

vals.f_secondary = vals.f_secondary + "X".

vals.f_current = vals.f_current + 2.

RETURN "".

END.

/*greek roots e.g., 'chemistry', 'chorus'*/

/*preliminary boolean assignments*/

clear_list().

CREATE list.

ASSIGN list.val = "HARAC".

CREATE list.

ASSIGN list.val = "HARIS".

b_temp1 = string_at(c_original,vals.f_current + 1,5).

clear_list().

CREATE list.

ASSIGN list.val = "HOR".

CREATE list.

ASSIGN list.val = "HYM".

CREATE list.

ASSIGN list.val = "HIA".

CREATE list.

ASSIGN list.val = "HEM".

b_temp2 = string_at(c_original,vals.f_current + 1,3).

clear_list().

CREATE list.

ASSIGN list.val = "CHORE".

b_temp3 = string_at(c_original,0,5).

/*actual logic*/

IF vals.f_current = 0 AND

(b_temp1 OR b_temp2) AND

NOT b_temp3 THEN DO:

vals.f_primary = vals.f_primary + "K".

vals.f_secondary = vals.f_secondary + "K".

vals.f_current = vals.f_current + 2.

RETURN "".

END.

/*germanic, greek, or otherwise 'ch' for 'kh' sound*/

/*preliminary boolean assignments*/

clear_list().

CREATE list.

ASSIGN list.val = "VAN ".

CREATE list.

ASSIGN list.val = "VON ".

b_temp1 = string_at(c_original,0,4).

clear_list().

CREATE list.

ASSIGN list.val = "SCH".

b_temp2 = string_at(c_original,0,3).

clear_list().

CREATE list.

ASSIGN list.val = "ORCHES".

CREATE list.

ASSIGN list.val = "ARCHIT".

CREATE list.

ASSIGN list.val = "ORCHID".

b_temp3 = string_at(c_original,vals.f_current - 2,6).

clear_list().

CREATE list.

ASSIGN list.val = "T".

CREATE list.

ASSIGN list.val = "S".

b_temp4 = string_at(c_original,vals.f_current + 2,1).

clear_list().

CREATE list.

ASSIGN list.val = "A".

CREATE list.

ASSIGN list.val = "O".

CREATE list.

ASSIGN list.val = "U".

CREATE list.

ASSIGN list.val = "E".

b_temp5 = string_at(c_original,vals.f_current - 1,1).

clear_list().

CREATE list.

ASSIGN list.val = "L".

CREATE list.

ASSIGN list.val = "R".

CREATE list.

ASSIGN list.val = "N".

CREATE list.

ASSIGN list.val = "M".

CREATE list.

ASSIGN list.val = "B".

CREATE list.

ASSIGN list.val = "H".

CREATE list.

ASSIGN list.val = "F".

CREATE list.

ASSIGN list.val = "V".

CREATE list.

ASSIGN list.val = "W".

CREATE list.

ASSIGN list.val = " ".

b_temp6 = string_at(c_original,vals.f_current + 2,1).

clear_list().

CREATE list.

ASSIGN list.val = "MC".

b_temp7 = string_at(c_original,0,2).

/*actual logic*/

IF b_temp1 OR

b_temp2 OR

b_temp3 OR

b_temp4 OR

((b_temp5 OR vals.f_current = 0) AND b_temp6) THEN DO:

vals.f_primary = vals.f_primary + "K".

vals.f_secondary = vals.f_secondary + "K".

END.

ELSE DO:

IF vals.f_current > 0 THEN DO:

IF b_temp7 THEN DO:

vals.f_primary = vals.f_primary + "K".

vals.f_secondary = vals.f_secondary + "K".

END.

ELSE DO:

vals.f_primary = vals.f_primary + "X".

vals.f_secondary = vals.f_secondary + "K".

END.

END.

ELSE DO:

vals.f_primary = vals.f_primary + "X".

vals.f_secondary = vals.f_secondary + "X".

END.

END.

vals.f_current = vals.f_current + 2.

RETURN "".

END.

/*e.g., 'czerny'*/

/*preliminary boolean assignments*/

clear_list().

CREATE list.

ASSIGN list.val = "CZ".

b_temp1 = string_at(c_original,vals.f_current,2).

clear_list().

CREATE list.

ASSIGN list.val = "WICZ".

b_temp2 = string_at(c_original,vals.f_current - 2,4).

/*actual logic*/

IF b_temp1 AND

b_temp2 THEN DO:

vals.f_primary = vals.f_primary + "S".

vals.f_secondary = vals.f_secondary + "X".

vals.f_current = vals.f_current + 2.

RETURN "".

END.

/* e.g., 'focaccia'*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "CIA".

b_temp1 = string_at(c_original,vals.f_current + 1,3).

/*logic*/

IF b_temp1 THEN DO:

vals.f_primary = vals.f_primary + "X".

vals.f_secondary = vals.f_secondary + "X".

vals.f_current = vals.f_current + 3.

RETURN "".

END.

/*double 'C', but not 'McClellan'*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "CC".

b_temp1 = string_at(c_original,vals.f_current,2).

clear_list().

CREATE list.

ASSIGN list.val = "I".

CREATE list.

ASSIGN list.val = "H".

CREATE list.

ASSIGN list.val = "E".

b_temp2 = string_at(c_original,vals.f_current + 2,1).

clear_list().

CREATE list.

ASSIGN list.val = "HU".

b_temp3 = string_at(c_original,vals.f_current + 2,2).

clear_list().

CREATE list.

ASSIGN list.val = "UCCEE".

CREATE list.

ASSIGN list.val = "UCCES".

b_temp4 = string_at(c_original,vals.f_current - 1,5).

/*logic*/

IF b_temp1 AND

(NOT vals.f_current = 1 OR

NOT SUBSTRING(c_original,1,1) = "M") THEN DO:

IF b_temp2 AND

NOT b_temp3 THEN DO:

IF (vals.f_current = 1 AND

SUBSTRING(c_original,vals.f_current,1) = "A") OR

b_temp4 THEN DO:

vals.f_primary = vals.f_primary + "KS".

vals.f_secondary = vals.f_secondary + "KS".

END.

ELSE DO:

vals.f_primary = vals.f_primary + "X".

vals.f_secondary = vals.f_secondary + "X".

END.

vals.f_current = vals.f_current + 3.

RETURN "".

END.

ELSE DO:

/*Pierce's rule*/

vals.f_primary = vals.f_primary + "K".

vals.f_secondary = vals.f_secondary + "K".

vals.f_current = vals.f_current + 2.

RETURN "".

END.

END.

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "CK".

CREATE list.

ASSIGN list.val = "CG".

CREATE list.

ASSIGN list.val = "CQ".

b_temp1 = string_at(c_original,vals.f_current,2).

/*logic*/

IF b_temp1 THEN DO:

vals.f_primary = vals.f_primary + "K".

vals.f_secondary = vals.f_secondary + "K".

vals.f_current = vals.f_current + 2.

RETURN "".

END.

/*italian vs. english*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "CI".

CREATE list.

ASSIGN list.val = "CE".

CREATE list.

ASSIGN list.val = "CY".

b_temp1 = string_at(c_original,vals.f_current,2).

clear_list().

CREATE list.

ASSIGN list.val = "CIO".

CREATE list.

ASSIGN list.val = "CIE".

CREATE list.

ASSIGN list.val = "CIA".

b_temp2 = string_at(c_original,vals.f_current,3).

/*logic*/

IF b_temp1 THEN DO:

IF b_temp2 THEN DO:

vals.f_primary = vals.f_primary + "S".

vals.f_secondary = vals.f_secondary + "X".

END.

ELSE DO:

vals.f_primary = vals.f_primary + "S".

vals.f_secondary = vals.f_secondary + "S".

END.

vals.f_current = vals.f_current + 2.

RETURN "".

END.

/*else*/

vals.f_primary = vals.f_primary + "K".

vals.f_secondary = vals.f_secondary + "K".

/*name sent in 'mac caffrey, mac gregor'*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = " C".

CREATE list.

ASSIGN list.val = " Q".

CREATE list.

ASSIGN list.val = " G".

b_temp1 = string_at(c_original,vals.f_current + 1,2).

clear_list().

CREATE list.

ASSIGN list.val = "C".

CREATE list.

ASSIGN list.val = "K".

CREATE list.

ASSIGN list.val = "Q".

b_temp2 = string_at(c_original,vals.f_current + 1,1).

clear_list().

CREATE list.

ASSIGN list.val = "CE".

CREATE list.

ASSIGN list.val = "CI".

b_temp3 = string_at(c_original,vals.f_current + 1,2).

/*logic*/

IF b_temp1 THEN vals.f_current = vals.f_current + 3.

ELSE DO:

IF b_temp2 AND

NOT b_temp3 THEN vals.f_current = vals.f_current + 2.

ELSE vals.f_current = vals.f_current + 1.

END.

RETURN "".

END.

WHEN "D" THEN DO:

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "DG".

b_temp1 = string_at(c_original,vals.f_current,2).

clear_list().

CREATE list.

ASSIGN list.val = "I".

CREATE list.

ASSIGN list.val = "E".

CREATE list.

ASSIGN list.val = "Y".

b_temp2 = string_at(c_original,vals.f_current + 2,1).

/*logic*/

IF b_temp1 THEN DO:

IF b_temp2 THEN DO:

/*e.g., edge*/

vals.f_primary = vals.f_primary + "J".

vals.f_secondary = vals.f_secondary + "J".

vals.f_current = vals.f_current + 3.

RETURN "".

END.

ELSE DO:

/*e.g., edgar*/

vals.f_primary = vals.f_primary + "TK".

vals.f_secondary = vals.f_secondary + "TK".

vals.f_current = vals.f_current + 2.

RETURN "".

END.

END.

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "DT".

CREATE list.

ASSIGN list.val = "DD".

b_temp1 = string_at(c_original,vals.f_current,2).

/*logic*/

IF b_temp1 THEN DO:

vals.f_primary = vals.f_primary + "T".

vals.f_secondary = vals.f_secondary + "T".

vals.f_current = vals.f_current + 2.

RETURN "".

END.

/*else*/

vals.f_primary = vals.f_primary + "T".

vals.f_secondary = vals.f_secondary + "T".

vals.f_current = vals.f_current + 1.

RETURN "".

END.

WHEN "F" THEN DO:

IF SUBSTRING(c_original,vals.f_current + 2,1) = "F" THEN

vals.f_current = vals.f_current + 2.

ELSE

vals.f_current = vals.f_current + 1.

vals.f_primary = vals.f_primary + "F".

vals.f_secondary = vals.f_secondary + "F".

RETURN "".

END.

END CASE.

RETURN "".

END FUNCTION.

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ENDIF

&IF DEFINED(EXCLUDE-double_metaphone2) = 0 &THEN

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION double_metaphone2 Method-Library

FUNCTION double_metaphone2 RETURNS CHARACTER

():

/*------------------------------------------------------------------------------

Purpose: helper function of double_metaphone procedure.

Notes: handles G,H,J,K,L,M,N,P,Q.

------------------------------------------------------------------------------*/

CASE SUBSTRING(c_original,vals.f_current + 1,1):

WHEN "G" THEN DO:

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "B".

CREATE list.

ASSIGN list.val = "H".

CREATE list.

ASSIGN list.val = "D".

b_temp1 = string_at(c_original,vals.f_current - 2,1).

b_temp2 = string_at(c_original,vals.f_current - 3,1).

clear_list().

CREATE list.

ASSIGN list.val = "B".

CREATE list.

ASSIGN list.val = "H".

b_temp3 = string_at(c_original,vals.f_current - 4,1).

clear_list().

CREATE list.

ASSIGN list.val = "C".

CREATE list.

ASSIGN list.val = "G".

CREATE list.

ASSIGN list.val = "L".

CREATE list.

ASSIGN list.val = "R".

CREATE list.

ASSIGN list.val = "T".

b_temp4 = string_at(c_original,vals.f_current - 3,1).

/*logic*/

IF SUBSTRING(c_original,vals.f_current + 2,1) = "H" THEN DO:

IF vals.f_current > 0 AND

NOT is_vowel(c_original,vals.f_current - 1) THEN DO:

vals.f_primary = vals.f_primary + "K".

vals.f_secondary = vals.f_secondary + "K".

vals.f_current = vals.f_current + 2.

RETURN "".

END.

IF vals.f_current < 3 THEN DO:

/*'ghislane', 'ghiradelli'*/

IF vals.f_current = 0 THEN DO:

IF SUBSTRING(c_original,vals.f_current + 3,1) = "I" THEN DO:

vals.f_primary = vals.f_primary + "J".

vals.f_secondary = vals.f_secondary + "J".

END.

ELSE DO:

vals.f_primary = vals.f_primary + "K".

vals.f_secondary = vals.f_secondary + "K".

END.

vals.f_current = vals.f_current + 2.

RETURN "".

END.

END.

/*parker's rule w/ further refinements (e.g., 'hugh')*/

IF (vals.f_current > 1 AND b_temp1) OR

/*'bough'*/

(vals.f_current > 2 AND b_temp2) OR

/*'broughton'*/

(vals.f_current > 3 AND b_temp3) THEN DO:

vals.f_current = vals.f_current + 2.

RETURN "".

END.

ELSE DO:

/*e.g., 'laugh', 'McLaughlin... */

IF vals.f_current > 2 AND

SUBSTRING(c_original,vals.f_current,1) = "U" AND

b_temp4 THEN DO:

vals.f_primary = vals.f_primary + "F".

vals.f_secondary = vals.f_secondary + "F".

END.

ELSE IF vals.f_current > 0 AND

NOT SUBSTRING(c_original,vals.f_current,1) = "I" THEN DO:

vals.f_primary = vals.f_primary + "K".

vals.f_secondary = vals.f_secondary + "K".

END.

vals.f_current = vals.f_current + 2.

RETURN "".

END.

END.

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "EY".

b_temp1 = string_at(c_original,vals.f_current + 2,2).

/*logic*/

IF SUBSTRING(c_original,vals.f_current + 2,1) = "N" THEN DO:

IF vals.f_current = 1 AND

is_vowel(c_original,0) AND

NOT slavo_germanic(c_original) THEN DO:

vals.f_primary = vals.f_primary + "KN".

vals.f_secondary = vals.f_secondary + "N".

END.

ELSE DO:

/*e.g., not 'cagney'*/

IF NOT b_temp1 AND

NOT SUBSTRING(c_original,vals.f_current + 2) = "Y" AND

NOT slavo_germanic(c_original) THEN DO:

vals.f_primary = vals.f_primary + "N".

vals.f_secondary = vals.f_secondary + "KN".

END.

ELSE DO:

vals.f_primary = vals.f_primary + "KN".

vals.f_secondary = vals.f_secondary + "KN".

END.

END.

vals.f_current = vals.f_current + 2.

RETURN "".

END.

/*'tagliaro'*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "LI".

b_temp1 = string_at(c_original,vals.f_current + 1,2).

/*logic*/

IF b_temp1 AND

NOT slavo_germanic(c_original) THEN DO:

vals.f_primary = vals.f_primary + "KL".

vals.f_secondary = vals.f_secondary + "L".

vals.f_current = vals.f_current + 2.

RETURN "".

END.

/*-ges-, -gep-, -gel- at beginning*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "ES".

CREATE list.

ASSIGN list.val = "EP".

CREATE list.

ASSIGN list.val = "EB".

CREATE list.

ASSIGN list.val = "EL".

CREATE list.

ASSIGN list.val = "EY".

CREATE list.

ASSIGN list.val = "IB".

CREATE list.

ASSIGN list.val = "IL".

CREATE list.

ASSIGN list.val = "IN".

CREATE list.

ASSIGN list.val = "EI".

CREATE list.

ASSIGN list.val = "ER".

b_temp1 = string_at(c_original,vals.f_current + 1,2).

/*logic*/

IF vals.f_current = 0 AND

(SUBSTRING(c_original,vals.f_current + 2,1) = "Y" OR

b_temp1) THEN DO:

vals.f_primary = vals.f_primary + "K".

vals.f_secondary = vals.f_secondary + "J".

vals.f_current = vals.f_current + 2.

RETURN "".

END.

/* -ger-, -gy- */

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "ER".

b_temp1 = string_at(c_original,vals.f_current + 1,2).

clear_list().

CREATE list.

ASSIGN list.val = "DANGER".

CREATE list.

ASSIGN list.val = "RANGER".

CREATE list.

ASSIGN list.val = "MANGER".

b_temp2 = string_at(c_original,0,6).

clear_list().

CREATE list.

ASSIGN list.val = "E".

CREATE list.

ASSIGN list.val = "I".

b_temp3 = string_at(c_original,vals.f_current - 1,1).

clear_list().

CREATE list.

ASSIGN list.val = "RGY".

CREATE list.

ASSIGN list.val = "OGY".

b_temp4 = string_at(c_original,vals.f_current - 1,3).

/*logic*/

IF (b_temp1 OR SUBSTRING(c_original,vals.f_current + 2,1) = "Y") AND

NOT b_temp2 AND

NOT b_temp3 AND

NOT b_temp4 THEN DO:

vals.f_primary = vals.f_primary + "K".

vals.f_secondary = vals.f_secondary + "J".

vals.f_current = vals.f_current + 2.

RETURN "".

END.

/*itilian 'biaggi'*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "E".

CREATE list.

ASSIGN list.val = "I".

CREATE list.

ASSIGN list.val = "Y".

b_temp1 = string_at(c_original,vals.f_current + 1,1).

clear_list().

CREATE list.

ASSIGN list.val = "AGGI".

CREATE list.

ASSIGN list.val = "OGGI".

b_temp2 = string_at(c_original,vals.f_current - 1,4).

clear_list().

CREATE list.

ASSIGN list.val = "VAN ".

CREATE list.

ASSIGN list.val = "VON ".

b_temp3 = string_at(c_original,0,4).

clear_list().

CREATE list.

ASSIGN list.val = "SCH".

b_temp4 = string_at(c_original,0,3).

clear_list().

CREATE list.

ASSIGN list.val = "ET".

b_temp5 = string_at(c_original,vals.f_current + 1,2).

clear_list().

CREATE list.

ASSIGN list.val = "IER ".

b_temp6 = string_at(c_original,vals.f_current + 1,4).

/*logic*/

IF b_temp1 OR

b_temp2 THEN DO:

/*obvious germanic*/

IF b_temp3 OR

b_temp4 OR

b_temp5 THEN DO:

vals.f_primary = vals.f_primary + "K".

vals.f_secondary = vals.f_secondary + "K".

END.

ELSE DO:

/* always soft if french ending */

IF b_temp6 THEN DO:

vals.f_primary = vals.f_primary + "J".

vals.f_secondary = vals.f_secondary + "J".

END.

ELSE DO:

vals.f_primary = vals.f_primary + "J".

vals.f_secondary = vals.f_secondary + "K".

END.

END.

vals.f_current = vals.f_current + 2.

RETURN "".

END.

/*logic*/

IF SUBSTRING(c_original,vals.f_current + 2,1) = "G" THEN

vals.f_current = vals.f_current + 2.

ELSE

vals.f_current = vals.f_current + 1.

vals.f_primary = vals.f_primary + "K".

vals.f_secondary = vals.f_secondary + "K".

RETURN "".

END.

WHEN "H" THEN DO:

/*only keep if 1st and before vowel or between 2 vowels*/

IF (vals.f_current = 0 OR is_vowel(c_original,vals.f_current - 1)) AND

is_vowel(c_original,vals.f_current + 1) THEN DO:

vals.f_primary = vals.f_primary + "H".

vals.f_secondary = vals.f_secondary + "H".

vals.f_current = vals.f_current + 2.

END.

ELSE vals.f_current = vals.f_current + 1.

RETURN "".

END.

WHEN "J" THEN DO:

/*spanish - 'jose'...*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "JOSE".

b_temp1 = string_at(c_original,vals.f_current,4).

clear_list().

CREATE list.

ASSIGN list.val = "SAN ".

b_temp2 = string_at(c_original,0,4).

/*logic*/

IF b_temp1 OR

b_temp2 THEN DO:

IF (vals.f_current = 0 AND

SUBSTRING(c_original,vals.f_current + 5,1) = " ") OR

b_temp2 THEN DO:

vals.f_primary = vals.f_primary + "H".

vals.f_secondary = vals.f_secondary + "H".

END.

ELSE DO:

vals.f_primary = vals.f_primary + "J".

vals.f_secondary = vals.f_secondary + "H".

END.

vals.f_current = vals.f_current + 1.

RETURN "".

END.

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "L".

CREATE list.

ASSIGN list.val = "T".

CREATE list.

ASSIGN list.val = "K".

CREATE list.

ASSIGN list.val = "S".

CREATE list.

ASSIGN list.val = "N".

CREATE list.

ASSIGN list.val = "M".

CREATE list.

ASSIGN list.val = "B".

CREATE list.

ASSIGN list.val = "Z".

b_temp3 = string_at(c_original,vals.f_current + 1,1).

clear_list().

CREATE list.

ASSIGN list.val = "S".

CREATE list.

ASSIGN list.val = "K".

CREATE list.

ASSIGN list.val = "L".

b_temp4 = string_at(c_original,vals.f_current - 1,1).

/*logic*/

IF vals.f_current = 0 AND

NOT b_temp1 THEN DO:

/*Yankelovich/Jankelowicz*/

vals.f_primary = vals.f_primary + "J".

vals.f_secondary = vals.f_secondary + "A".

END.

ELSE DO:

/*spanish pron. - 'bajador'*/

IF is_vowel(c_original,vals.f_current - 1) AND

NOT slavo_germanic(c_original) AND

(SUBSTRING(c_original,vals.f_current + 2,1) = "A" OR

SUBSTRING(c_original,vals.f_current + 2,1) = "O") THEN DO:

vals.f_primary = vals.f_primary + "J".

vals.f_secondary = vals.f_secondary + "H".

END.

ELSE DO:

IF vals.f_current = i_last THEN DO:

vals.f_primary = vals.f_primary + "J".

vals.f_secondary = vals.f_secondary + "".

END.

ELSE DO:

IF NOT b_temp3 AND

NOT b_temp4 THEN DO:

vals.f_primary = vals.f_primary + "J".

vals.f_secondary = vals.f_secondary + "J".

END.

END.

END.

END.

IF SUBSTRING(c_original,vals.f_current + 2,1) = "J" THEN

vals.f_current = vals.f_current + 2.

ELSE

vals.f_current = vals.f_current + 1.

RETURN "".

END.

WHEN "K" THEN DO:

IF SUBSTRING(c_original,vals.f_current + 2,1) = "K" THEN

vals.f_current = vals.f_current + 2.

ELSE

vals.f_current = vals.f_current + 1.

vals.f_primary = vals.f_primary + "K".

vals.f_secondary = vals.f_secondary + "K".

RETURN "".

END.

WHEN "L" THEN DO:

IF SUBSTRING(c_original,vals.f_current + 2,1) = "L" THEN DO:

/*spanish - 'cabrillo'...*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "ILLO".

CREATE list.

ASSIGN list.val = "ILLA".

CREATE list.

ASSIGN list.val = "ALLE".

b_temp1 = string_at(c_original,vals.f_current - 1,4).

clear_list().

CREATE list.

ASSIGN list.val = "AS".

CREATE list.

ASSIGN list.val = "OS".

b_temp2 = string_at(c_original,i_last - 1,2).

clear_list().

CREATE list.

ASSIGN list.val = "A".

CREATE list.

ASSIGN list.val = "O".

b_temp3 = string_at(c_original,i_last,1).

clear_list().

CREATE list.

ASSIGN list.val = "ALLE".

b_temp4 = string_at(c_original,vals.f_current - 1,4).

/*logic*/

IF (vals.f_current = i_length - 3 AND b_temp1) OR

((b_temp2 OR b_temp3) AND b_temp4) THEN DO:

vals.f_primary = vals.f_primary + "L".

vals.f_secondary = vals.f_secondary + "".

vals.f_current = vals.f_current + 2.

RETURN "".

END.

vals.f_current = vals.f_current + 2.

END.

ELSE vals.f_current = vals.f_current + 1.

vals.f_primary = vals.f_primary + "L".

vals.f_secondary = vals.f_secondary + "L".

RETURN "".

END.

WHEN "M" THEN DO:

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "UMB".

b_temp1 = string_at(c_original,vals.f_current - 1,3).

clear_list().

CREATE list.

ASSIGN list.val = "ER".

b_temp2 = string_at(c_original,vals.f_current + 2,2).

/*logic*/

IF (b_temp1 AND (vals.f_current + 1 = i_last OR b_temp2)) OR

SUBSTRING(c_original,vals.f_current + 2,1) = "M" THEN

vals.f_current = vals.f_current + 2.

ELSE vals.f_current = vals.f_current + 1.

vals.f_primary = vals.f_primary + "M".

vals.f_secondary = vals.f_secondary + "M".

RETURN "".

END.

WHEN "N" THEN DO:

IF SUBSTRING(c_original,vals.f_current + 2,1) = "N" THEN

vals.f_current = vals.f_current + 2.

ELSE vals.f_current = vals.f_current + 1.

vals.f_primary = vals.f_primary + "N".

vals.f_secondary = vals.f_secondary + "N".

RETURN "".

END.

/* not recognized by parser

WHEN "Ñ" THEN DO:

vals.f_current = vals.f_current + 1.

vals.f_primary = vals.f_primary + "N".

vals.f_secondary = vals.f_secondary + "N".

RETURN "".

END.

*/

WHEN "P" THEN DO:

IF SUBSTRING(c_original,vals.f_current + 2,1) = "H" THEN DO:

vals.f_current = vals.f_current + 2.

vals.f_primary = vals.f_primary + "F".

vals.f_secondary = vals.f_secondary + "F".

RETURN "".

END.

/*campbell, raspberry*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "P".

CREATE list.

ASSIGN list.val = "B".

b_temp1 = string_at(c_original,vals.f_current + 1,1).

/*logic*/

IF b_temp1 THEN vals.f_current = vals.f_current + 2.

ELSE vals.f_current = vals.f_current + 1.

vals.f_primary = vals.f_primary + "P".

vals.f_secondary = vals.f_secondary + "P".

RETURN "".

END.

WHEN "Q" THEN DO:

IF SUBSTRING(c_original,vals.f_current + 2,1) = "Q" THEN

vals.f_current = vals.f_current + 2.

ELSE vals.f_current = vals.f_current + 1.

vals.f_primary = vals.f_primary + "K".

vals.f_secondary = vals.f_secondary + "K".

RETURN "".

END.

END CASE.

RETURN "".

END FUNCTION.

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ENDIF

&IF DEFINED(EXCLUDE-double_metaphone3) = 0 &THEN

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION double_metaphone3 Method-Library

FUNCTION double_metaphone3 RETURNS CHARACTER

():

/*------------------------------------------------------------------------------

Purpose: helper function of double_metaphone procedure.

Notes: handles R,S,T,V.

------------------------------------------------------------------------------*/

CASE SUBSTRING(c_original,vals.f_current + 1,1):

WHEN "R" THEN DO:

/*french - 'rogier', but exclude 'hochmeier'*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "IE".

b_temp1 = string_at(c_original,vals.f_current - 2,2).

clear_list().

CREATE list.

ASSIGN list.val = "ME".

CREATE list.

ASSIGN list.val = "MA".

b_temp2 = string_at(c_original,vals.f_current - 4,2).

/*logic*/

IF vals.f_current = i_last AND

NOT slavo_germanic(c_original) AND

b_temp1 AND

NOT b_temp2 THEN DO:

vals.f_primary = vals.f_primary + "".

vals.f_secondary = vals.f_secondary + "R".

END.

ELSE DO:

vals.f_primary = vals.f_primary + "R".

vals.f_secondary = vals.f_secondary + "R".

END.

IF SUBSTRING(c_original,vals.f_current + 2,1) = "R" THEN

vals.f_current = vals.f_current + 2.

ELSE vals.f_current = vals.f_current + 1.

RETURN "".

END.

WHEN "S" THEN DO:

/*special cases 'island', isle...*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "ISL".

CREATE list.

ASSIGN list.val = "YSL".

b_temp1 = string_at(c_original,vals.f_current - 1,3).

/*logic*/

IF b_temp1 THEN DO:

vals.f_current = vals.f_current + 1.

RETURN "".

END.

/*special case 'sugar'*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "SUGAR".

b_temp1 = string_at(c_original,vals.f_current,5).

/*logic*/

IF vals.f_current = 0 AND

b_temp1 THEN DO:

vals.f_primary = vals.f_primary + "X".

vals.f_secondary = vals.f_secondary + "S".

vals.f_current = vals.f_current + 1.

RETURN "".

END.

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "SH".

b_temp1 = string_at(c_original,vals.f_current,2).

/*logic*/

IF b_temp1 THEN DO:

/*germanic*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "HEIM".

CREATE list.

ASSIGN list.val = "HOEK".

CREATE list.

ASSIGN list.val = "HOLM".

CREATE list.

ASSIGN list.val = "HOLZ".

b_temp2 = string_at(c_original,vals.f_current + 1,4).

/*logic*/

IF b_temp2 THEN DO:

vals.f_primary = vals.f_primary + "S".

vals.f_secondary = vals.f_secondary + "S".

END.

ELSE DO:

vals.f_primary = vals.f_primary + "X".

vals.f_secondary = vals.f_secondary + "X".

END.

vals.f_current = vals.f_current + 2.

RETURN "".

END.

/*italian and armenian*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "SIO".

CREATE list.

ASSIGN list.val = "SIA".

b_temp1 = string_at(c_original,vals.f_current,3).

clear_list().

CREATE list.

ASSIGN list.val = "SIAN".

b_temp2 = string_at(c_original,vals.f_current,4).

/*logic*/

IF b_temp1 OR

b_temp2 THEN DO:

IF NOT slavo_germanic(c_original) THEN DO:

vals.f_primary = vals.f_primary + "S".

vals.f_secondary = vals.f_secondary + "X".

END.

ELSE DO:

vals.f_primary = vals.f_primary + "S".

vals.f_secondary = vals.f_secondary + "S".

END.

vals.f_current = vals.f_current + 3.

RETURN "".

END.

/*german and anglicisations, smith, schmidt, snider...*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "M".

CREATE list.

ASSIGN list.val = "N".

CREATE list.

ASSIGN list.val = "L".

CREATE list.

ASSIGN list.val = "W".

b_temp1 = string_at(c_original,vals.f_current + 1,1).

clear_list().

CREATE list.

ASSIGN list.val = "Z".

b_temp2 = string_at(c_original,vals.f_current + 1,1).

/*logic*/

IF (vals.f_current = 0 AND b_temp1) OR

b_temp2 THEN DO:

vals.f_primary = vals.f_primary + "S".

vals.f_secondary = vals.f_secondary + "X".

IF b_temp2 THEN vals.f_current = vals.f_current + 2.

ELSE vals.f_current = vals.f_current + 1.

RETURN "".

END.

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "SC".

b_temp1 = string_at(c_original,vals.f_current,2).

IF b_temp1 THEN DO:

/*Schlesinger's rule*/

IF SUBSTRING(c_original,vals.f_current + 3,1) = "H" THEN DO:

/*dutch origin - school...*/

clear_list().

CREATE list.

ASSIGN list.val = "OO".

CREATE list.

ASSIGN list.val = "ER".

CREATE list.

ASSIGN list.val = "EN".

CREATE list.

ASSIGN list.val = "UY".

CREATE list.

ASSIGN list.val = "ED".

CREATE list.

ASSIGN list.val = "EM".

b_temp2 = string_at(c_original,vals.f_current + 3,2).

IF b_temp2 THEN DO:

/*schermerhorn...*/

clear_list().

CREATE list.

ASSIGN list.val = "ER".

CREATE list.

ASSIGN list.val = "EN".

b_temp3 = string_at(c_original,vals.f_current + 3,2).

IF b_temp3 THEN DO:

vals.f_primary = vals.f_primary + "X".

vals.f_secondary = vals.f_secondary + "SK".

END.

ELSE DO:

vals.f_primary = vals.f_primary + "SK".

vals.f_secondary = vals.f_secondary + "SK".

END.

vals.f_current = vals.f_current + 3.

RETURN "".

END.

ELSE DO:

IF vals.f_current = 0 AND

NOT is_vowel(c_original,3) AND

NOT SUBSTRING(c_original,vals.f_current + 4,1) = "W" THEN DO:

vals.f_primary = vals.f_primary + "X".

vals.f_secondary = vals.f_secondary + "S".

END.

ELSE DO:

vals.f_primary = vals.f_primary + "X".

vals.f_secondary = vals.f_secondary + "X".

END.

vals.f_current = vals.f_current + 3.

RETURN "".

END.

END.

clear_list().

CREATE list.

ASSIGN list.val = "I".

CREATE list.

ASSIGN list.val = "E".

CREATE list.

ASSIGN list.val = "Y".

b_temp4 = string_at(c_original,vals.f_current + 2,1).

IF b_temp4 THEN DO:

vals.f_primary = vals.f_primary + "S".

vals.f_secondary = vals.f_secondary + "S".

vals.f_current = vals.f_current + 3.

RETURN "".

END.

/*else*/

vals.f_primary = vals.f_primary + "SK".

vals.f_secondary = vals.f_secondary + "SK".

vals.f_current = vals.f_current + 3.

RETURN "".

END.

/*french e.g. 'resnais', 'artois'*/

clear_list().

CREATE list.

ASSIGN list.val = "AI".

CREATE list.

ASSIGN list.val = "OI".

b_temp5 = string_at(c_original,vals.f_current - 2,2).

IF vals.f_current = i_last AND

b_temp5 THEN DO:

vals.f_primary = vals.f_primary + "".

vals.f_secondary = vals.f_secondary + "S".

END.

ELSE DO:

vals.f_primary = vals.f_primary + "S".

vals.f_secondary = vals.f_secondary + "S".

END.

clear_list().

CREATE list.

ASSIGN list.val = "S".

CREATE list.

ASSIGN list.val = "Z".

b_temp6 = string_at(c_original,vals.f_current + 1,1).

IF b_temp6 THEN vals.f_current = vals.f_current + 2.

ELSE vals.f_current = vals.f_current + 1.

RETURN "".

END.

WHEN "T" THEN DO:

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "TION".

b_temp1 = string_at(c_original,vals.f_current,4).

/*logic*/

IF b_temp1 THEN DO:

vals.f_primary = vals.f_primary + "X".

vals.f_secondary = vals.f_secondary + "X".

vals.f_current = vals.f_current + 3.

RETURN "".

END.

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "TIA".

CREATE list.

ASSIGN list.val = "TCH".

b_temp1 = string_at(c_original,vals.f_current,3).

/*logic*/

IF b_temp1 THEN DO:

vals.f_primary = vals.f_primary + "X".

vals.f_secondary = vals.f_secondary + "X".

vals.f_current = vals.f_current + 3.

RETURN "".

END.

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "TH".

b_temp1 = string_at(c_original,vals.f_current,2).

clear_list().

CREATE list.

ASSIGN list.val = "TTH".

b_temp2 = string_at(c_original,vals.f_current,3).

/*logic*/

IF b_temp1 OR

b_temp2 THEN DO:

/*special case thomas, thames, or germanic*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "OM".

CREATE list.

ASSIGN list.val = "AM".

b_temp3 = string_at(c_original,vals.f_current + 2,2).

clear_list().

CREATE list.

ASSIGN list.val = "VAN ".

CREATE list.

ASSIGN list.val = "VON ".

b_temp4 = string_at(c_original,0,4).

clear_list().

CREATE list.

ASSIGN list.val = "SCH".

b_temp5 = string_at(c_original,0,3).

/*logic*/

IF b_temp3 OR

b_temp4 OR

b_temp5 THEN DO:

vals.f_primary = vals.f_primary + "T".

vals.f_secondary = vals.f_secondary + "T".

END.

ELSE DO:

vals.f_primary = vals.f_primary + "O".

vals.f_secondary = vals.f_secondary + "T".

END.

vals.f_current = vals.f_current + 2.

RETURN "".

END.

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "T".

CREATE list.

ASSIGN list.val = "D".

b_temp1 = string_at(c_original,vals.f_current + 1,1).

/*logic*/

IF b_temp1 THEN vals.f_current = vals.f_current + 2.

ELSE vals.f_current = vals.f_current + 1.

vals.f_primary = vals.f_primary + "T".

vals.f_secondary = vals.f_secondary + "T".

RETURN "".

END.

WHEN "V" THEN DO:

IF SUBSTRING(c_original,vals.f_current + 3,1) = "V" THEN

vals.f_current = vals.f_current + 2.

ELSE vals.f_current = vals.f_current + 1.

vals.f_primary = vals.f_primary + "F".

vals.f_secondary = vals.f_secondary + "F".

RETURN "".

END.

END CASE.

RETURN "".

END FUNCTION.

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ENDIF

&IF DEFINED(EXCLUDE-double_metaphone4) = 0 &THEN

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION double_metaphone4 Method-Library

FUNCTION double_metaphone4 RETURNS CHARACTER PRIVATE

():

/*------------------------------------------------------------------------------

Purpose: helper function of double_metaphone procedure.

Notes: handles W,X,Z

------------------------------------------------------------------------------*/

CASE SUBSTRING(c_original,vals.f_current + 1,1):

WHEN "W" THEN DO:

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "WR".

b_temp1 = string_at(c_original,vals.f_current,2).

/*logic*/

IF b_temp1 THEN DO:

vals.f_primary = vals.f_primary + "R".

vals.f_secondary = vals.f_secondary + "R".

vals.f_current = vals.f_current + 2.

RETURN "".

END.

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "WH".

b_temp1 = string_at(c_original,vals.f_current,2).

/*logic*/

IF vals.f_current = 0 AND

(is_vowel(c_original,vals.f_current + 1) OR

b_temp1) THEN DO:

/*wasserman should match vasserman*/

IF is_vowel(c_original,vals.f_current + 1) THEN DO:

vals.f_primary = vals.f_primary + "A".

vals.f_secondary = vals.f_secondary + "F".

END.

ELSE DO:

/*need Uomo to match Womo*/

vals.f_primary = vals.f_primary + "A".

vals.f_secondary = vals.f_secondary + "A".

END.

END.

/*Arnow should match Arnoff*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "EWSKI".

CREATE list.

ASSIGN list.val = "EWSKY".

CREATE list.

ASSIGN list.val = "OWSKI".

CREATE list.

ASSIGN list.val = "OWSKY".

b_temp1 = string_at(c_original,vals.f_current - 1,5).

clear_list().

CREATE list.

ASSIGN list.val = "SCH".

b_temp2 = string_at(c_original,0,3).

/*logic*/

IF (vals.f_current = i_last AND is_vowel(c_original,vals.f_current - 1)) OR

b_temp1 OR

b_temp2 THEN DO:

vals.f_primary = vals.f_primary + "".

vals.f_secondary = vals.f_secondary + "F".

vals.f_current = vals.f_current + 1.

RETURN "".

END.

/*polish - filipowicz*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "WICZ".

CREATE list.

ASSIGN list.val = "WITZ".

b_temp1 = string_at(c_original,vals.f_current,4).

/*logic*/

IF b_temp1 THEN DO:

vals.f_primary = vals.f_primary + "TS".

vals.f_secondary = vals.f_secondary + "FX".

vals.f_current = vals.f_current + 4.

RETURN "".

END.

/*else skip it*/

vals.f_current = vals.f_current + 1.

RETURN "".

END.

WHEN "X" THEN DO:

/*french - breaux*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "IAU".

CREATE list.

ASSIGN list.val = "EAU".

b_temp1 = string_at(c_original,vals.f_current - 3,3).

clear_list().

CREATE list.

ASSIGN list.val = "AU".

CREATE list.

ASSIGN list.val = "OU".

b_temp2 = string_at(c_original,vals.f_current - 2,2).

/*logic*/

IF NOT vals.f_current = i_last OR

(NOT b_temp1 AND NOT b_temp2) THEN DO:

vals.f_primary = vals.f_primary + "KS".

vals.f_secondary = vals.f_secondary + "KS".

END.

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "C".

CREATE list.

ASSIGN list.val = "X".

b_temp3 = string_at(c_original,vals.f_current + 1,1).

IF b_temp3 THEN vals.f_current = vals.f_current + 2.

ELSE vals.f_current = vals.f_current + 1.

RETURN "".

END.

WHEN "Z" THEN DO:

/*chinese pinyin 'zhao'*/

/*bool assign*/

clear_list().

CREATE list.

ASSIGN list.val = "ZO".

CREATE list.

ASSIGN list.val = "ZI".

CREATE list.

ASSIGN list.val = "ZA".

b_temp1 = string_at(c_original,vals.f_current + 1,2).

/*logic*/

IF SUBSTRING(c_original,vals.f_current + 2,1) = "H" THEN DO:

vals.f_primary = vals.f_primary + "J".

vals.f_secondary = vals.f_secondary + "J".

vals.f_current = vals.f_current + 2.

RETURN "".

END.

ELSE IF b_temp1 OR

(slavo_germanic(c_original) AND

(vals.f_current > 0 AND

NOT SUBSTRING(c_original,vals.f_current,1) = "T")) THEN DO:

vals.f_primary = vals.f_primary + "S".

vals.f_secondary = vals.f_secondary + "TS".

END.

ELSE DO:

vals.f_primary = vals.f_primary + "S".

vals.f_secondary = vals.f_secondary + "S".

END.

IF SUBSTRING(c_original,vals.f_current + 2,1) = "Z" THEN

vals.f_current = vals.f_current + 2.

ELSE vals.f_current = vals.f_current + 1.

END.

END CASE.

RETURN "".

END FUNCTION.

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ENDIF

&IF DEFINED(EXCLUDE-is_vowel) = 0 &THEN

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION is_vowel Method-Library

FUNCTION is_vowel RETURNS LOGICAL PRIVATE

(s AS CHARACTER, i AS INTEGER) :

/*------------------------------------------------------------------------------

Purpose: return a boolean indicating whether or not the character at

position i in string s is a vowel.

Notes:

------------------------------------------------------------------------------*/

c = SUBSTRING(s,i + 1,1).

RETURN c = "A" OR

c = "E" OR

c = "I" OR

c = "O" OR

c = "U" OR

c = "Y".

END FUNCTION.

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ENDIF

&IF DEFINED(EXCLUDE-slavo_germanic) = 0 &THEN

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION slavo_germanic Method-Library

FUNCTION slavo_germanic RETURNS LOGICAL PRIVATE

(s AS CHARACTER) :

/*------------------------------------------------------------------------------

Purpose: helper function of double_metaphone function

Notes:

------------------------------------------------------------------------------*/

RETURN s MATCHES "*W*" OR

s MATCHES "*K*" OR

s MATCHES "*CZ*" OR

s MATCHES "*WITZ*".

END FUNCTION.

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ENDIF

&IF DEFINED(EXCLUDE-string_at) = 0 &THEN

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION string_at Method-Library

FUNCTION string_at RETURNS LOGICAL PRIVATE

(s AS CHARACTER, istart AS INTEGER, ilength AS INTEGER) :

/*------------------------------------------------------------------------------

Purpose: return boolean indicating whether substring(s,istart,ilength) is

= to list.val for any list entry.

Notes: the list temp-table must be properly initialized before calling

this function.

------------------------------------------------------------------------------*/

IF istart < 0 OR istart > LENGTH(s) THEN RETURN NO.

FOR EACH list :

IF list.val = SUBSTRING(s,istart + 1,ilength) THEN RETURN YES.

END.

RETURN NO.

END FUNCTION.

/* _UIB-CODE-BLOCK-END */

&ANALYZE-RESUME

&ENDIF

0 Comments:

Post a Comment

<< Home