一般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